aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGrant Ammons <gammons@gmail.com>2016-05-06 17:40:04 -0400
committerGrant Ammons <gammons@gmail.com>2016-05-06 17:40:04 -0400
commit8bb8317f1f29a7dd1b910931ebd12c739a5fa1cc (patch)
treec1ed847774f1da14c068e8d7a6d2f10097383aac
parent8e77e4e86bbcffc1ca30b25ba26b0225a578df90 (diff)
Parse out arbitrary dates
This will parse out dates in the format of "mon dd", the month being a 3 letter month, and the date being just the day. due mar 10 due sep 25 due oct 2 it will also "intelligently" guess the year, based upon which is the shorter duration from time.Now(). for instance, if today's date is dec 25 and you schedule an event for jan 2, it will schedule it for the following year.
-rw-r--r--todolist/parser.go56
-rw-r--r--todolist/parser_test.go32
2 files changed, 68 insertions, 20 deletions
diff --git a/todolist/parser.go b/todolist/parser.go
index f78ce38..e06545e 100644
--- a/todolist/parser.go
+++ b/todolist/parser.go
@@ -3,6 +3,7 @@ package todolist
import (
"fmt"
"regexp"
+ "strconv"
"strings"
"time"
@@ -56,32 +57,61 @@ func (p *Parser) Due(input string, day time.Time) string {
res := r.FindString(input)
res = res[4:len(res)]
- switch {
- case res == "none":
+ switch res {
+ case "none":
return ""
- case res == "today":
+ case "today":
return now.BeginningOfDay().Format("2006-01-02")
- case res == "tomorrow" || res == "tom":
+ case "tomorrow", "tom":
return now.BeginningOfDay().AddDate(0, 0, 1).Format("2006-01-02")
- case res == "monday" || res == "mon":
+ case "monday", "mon":
return p.monday(day)
- case res == "tuesday" || res == "tue":
+ case "tuesday", "tue":
return p.tuesday(day)
- case res == "wednesday" || res == "wed":
+ case "wednesday", "wed":
return p.wednesday(day)
- case res == "thursday" || res == "thu":
+ case "thursday", "thu":
return p.thursday(day)
- case res == "friday" || res == "fri":
+ case "friday", "fri":
return p.friday(day)
- case res == "saturday" || res == "sat":
+ case "saturday", "sat":
return p.saturday(day)
- case res == "sunday" || res == "sun":
+ case "sunday", "sun":
return p.sunday(day)
- case res == "next week":
+ case "next week":
n := now.BeginningOfDay()
return now.New(n).Monday().AddDate(0, 0, 7).Format("2006-01-02")
}
- return time.Now().Format("2006-01-02")
+ return p.parseArbitraryDate(res, time.Now())
+}
+
+func (p *Parser) parseArbitraryDate(_date string, pivot time.Time) string {
+ d1 := p.parseArbitraryDateWithYear(_date, pivot.Year())
+
+ var diff1 time.Duration
+ if d1.After(time.Now()) {
+ diff1 = d1.Sub(pivot)
+ } else {
+ diff1 = pivot.Sub(d1)
+ }
+ d2 := p.parseArbitraryDateWithYear(_date, pivot.Year()+1)
+ if d2.Sub(pivot) > diff1 {
+ return d1.Format("2006-01-02")
+ } else {
+ return d2.Format("2006-01-02")
+ }
+}
+
+func (p *Parser) parseArbitraryDateWithYear(_date string, year int) time.Time {
+ res := strings.Join([]string{_date, strconv.Itoa(year)}, " ")
+ if date, err := time.Parse("Jan 2 2006", res); err == nil {
+ return date
+ }
+
+ if date, err := time.Parse("2 Jan 2006", res); err == nil {
+ return date
+ }
+ panic(fmt.Errorf("Could not parse the date you gave me: '%s'", _date))
}
func (p *Parser) monday(day time.Time) string {
diff --git a/todolist/parser_test.go b/todolist/parser_test.go
index 9a2732c..2134a86 100644
--- a/todolist/parser_test.go
+++ b/todolist/parser_test.go
@@ -104,10 +104,28 @@ func TestTuesdayOnWednesday(t *testing.T) {
assert.Equal("2016-05-03", parser.tuesday(now))
}
-//func TestDueNextWeek(t *testing.T) {
-// parser := &Parser{}
-//
-// fmt.Println("about to parse")
-// todo := parser.Parse("do this thing with @bob and @mary due next week")
-// fmt.Println(todo.Due)
-//}
+func TestDueOnSpecificDate(t *testing.T) {
+ assert := assert.New(t)
+ parser := &Parser{}
+ assert.Equal("2016-05-02", parser.Due("due may 2", time.Now()))
+}
+
+func TestDueOnSpecificDateEuropean(t *testing.T) {
+ assert := assert.New(t)
+ parser := &Parser{}
+ assert.Equal("2016-05-02", parser.Due("due 2 may", time.Now()))
+}
+
+func TestDueIntelligentlyChoosesCorrectYear(t *testing.T) {
+ assert := assert.New(t)
+ parser := &Parser{}
+ marchTime, _ := time.Parse("2006-01-02", "2016-03-25")
+ januaryTime, _ := time.Parse("2006-01-02", "2016-01-05")
+ septemberTime, _ := time.Parse("2006-01-02", "2016-09-25")
+ decemberTime, _ := time.Parse("2006-01-02", "2016-12-25")
+
+ assert.Equal("2016-01-10", parser.parseArbitraryDate("jan 10", januaryTime))
+ assert.Equal("2016-01-10", parser.parseArbitraryDate("jan 10", marchTime))
+ assert.Equal("2017-01-10", parser.parseArbitraryDate("jan 10", septemberTime))
+ assert.Equal("2017-01-10", parser.parseArbitraryDate("jan 10", decemberTime))
+}