diff options
author | Koni Marti <koni.marti@gmail.com> | 2022-11-15 21:24:49 +0100 |
---|---|---|
committer | Robin Jarry <robin@jarry.cc> | 2022-12-02 22:59:23 +0100 |
commit | ff101bda430dda18e6f150ce6915891139ecccd9 (patch) | |
tree | df7906c7c5379307522ddc21634660fc99f02b2d /worker/lib/daterange.go | |
parent | 23a05d17ac1d23466ff73efa19576d43d06efe4b (diff) | |
download | aerc-ff101bda430dda18e6f150ce6915891139ecccd9.tar.gz |
search: handle date ranges in search/filter query
Handle date ranges in the filter and search commands for searching and
filtering based on the Date: header. Implement a flag (-d) that accepts
a date range <start[..end]> where the start date is included in the
range but the end date is not, i.e. [start,end).
The start or end date can be omitted: "start", "start..", "..end", or
"start..end" are all valid inputs.
An example filter query would look like this: :filter -d 2022-11-09..
The dates should be in the YYYY-MM-DD format.
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Diffstat (limited to 'worker/lib/daterange.go')
-rw-r--r-- | worker/lib/daterange.go | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/worker/lib/daterange.go b/worker/lib/daterange.go new file mode 100644 index 00000000..c996392c --- /dev/null +++ b/worker/lib/daterange.go @@ -0,0 +1,63 @@ +package lib + +import ( + "fmt" + "strings" + "time" +) + +const dateFmt = "2006-01-02" + +// ParseDateRange parses a date range into a start and end date. Dates are +// expected to be in the YYYY-MM-DD format. +// +// Start and end dates are connected by the range operator ".." where end date +// is not included in the date range. +// +// ParseDateRange can also parse open-ended ranges, i.e. start.. or ..end are +// allowed. +func ParseDateRange(s string) (start, end time.Time, err error) { + s = strings.ReplaceAll(s, " ", "") + i := strings.Index(s, "..") + switch { + case i < 0: + // single date + start, err = time.Parse(dateFmt, s) + if err != nil { + err = fmt.Errorf("failed to parse date: %w", err) + return + } + end = start.AddDate(0, 0, 1) + + case i == 0: + // end date only + if len(s) < 2 { + err = fmt.Errorf("no date found") + return + } + end, err = time.Parse(dateFmt, s[2:]) + if err != nil { + err = fmt.Errorf("failed to parse date: %w", err) + return + } + + case i > 0: + // start date first + start, err = time.Parse(dateFmt, s[:i]) + if err != nil { + err = fmt.Errorf("failed to parse date: %w", err) + return + } + if len(s[i:]) <= 2 { + return + } + // and end dates if available + end, err = time.Parse(dateFmt, s[(i+2):]) + if err != nil { + err = fmt.Errorf("failed to parse date: %w", err) + return + } + } + + return +} |