From 6cee9c0be88c5330ec14c8b9f2fc7af779b3019b Mon Sep 17 00:00:00 2001 From: gbaptista Date: Mon, 4 Mar 2019 07:43:59 -0300 Subject: [PATCH] support for the "04/27/2019" date format --- rules/en/en.go | 1 + rules/en/slash_mdy.go | 93 ++++++++++++++++++++++++++++++++++++++ rules/en/slash_mdy_test.go | 44 ++++++++++++++++++ 3 files changed, 138 insertions(+) create mode 100644 rules/en/slash_mdy.go create mode 100644 rules/en/slash_mdy_test.go diff --git a/rules/en/en.go b/rules/en/en.go index 0b9bd9d..cd428b6 100644 --- a/rules/en/en.go +++ b/rules/en/en.go @@ -3,6 +3,7 @@ package en import "github.com/olebedev/when/rules" var All = []rules.Rule{ + SlashMDY(rules.Override), Weekday(rules.Override), CasualDate(rules.Override), CasualTime(rules.Override), diff --git a/rules/en/slash_mdy.go b/rules/en/slash_mdy.go new file mode 100644 index 0000000..1c5a42d --- /dev/null +++ b/rules/en/slash_mdy.go @@ -0,0 +1,93 @@ +package en + +import ( + "regexp" + "strconv" + "time" + + "github.com/olebedev/when/rules" +) + +/* + +- MM/DD/YYYY +- 3/11/2015 +- 3/11/2015 +- 3/11 + +also with "\", gift for windows' users +*/ + +var MONTHS_DAYS = []int{ + 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, +} + +func getDays(year, month int) int { + // naive leap year check + if (year-2000)%4 == 0 && month == 2 { + return 29 + } + return MONTHS_DAYS[month] +} + +func SlashMDY(s rules.Strategy) rules.Rule { + + return &rules.F{ + RegExp: regexp.MustCompile("(?i)(?:\\W|^)" + + "([0-3]{0,1}[0-9]{1})" + + "[\\/\\\\]" + + "([0-3]{0,1}[0-9]{1})" + + "(?:[\\/\\\\]" + + "((?:1|2)[0-9]{3})\\s*)?" + + "(?:\\W|$)"), + Applier: func(m *rules.Match, c *rules.Context, o *rules.Options, ref time.Time) (bool, error) { + if (c.Day != nil || c.Month != nil || c.Year != nil) && s != rules.Override { + return false, nil + } + + month, _ := strconv.Atoi(m.Captures[0]) + day, _ := strconv.Atoi(m.Captures[1]) + year := -1 + if m.Captures[2] != "" { + year, _ = strconv.Atoi(m.Captures[2]) + } + + if day == 0 { + return false, nil + } + WithYear: + if year != -1 { + if getDays(year, month) >= day { + c.Year = &year + c.Month = &month + c.Day = &day + } else { + return false, nil + } + return true, nil + } + + if int(ref.Month()) > month { + year = ref.Year() + 1 + goto WithYear + } + + if int(ref.Month()) == month { + if getDays(ref.Year(), month) >= day { + if day > ref.Day() { + year = ref.Year() + } else if day < ref.Day() { + year = ref.Year() + 1 + } else { + return false, nil + } + goto WithYear + } else { + return false, nil + } + } + + return true, nil + }, + } +} diff --git a/rules/en/slash_mdy_test.go b/rules/en/slash_mdy_test.go new file mode 100644 index 0000000..3d8e8d5 --- /dev/null +++ b/rules/en/slash_mdy_test.go @@ -0,0 +1,44 @@ +package en_test + +import ( + "testing" + "time" + + "github.com/olebedev/when" + "github.com/olebedev/when/rules" + "github.com/olebedev/when/rules/en" +) + +// July 15 days offset from the begining of the year +const OFFSET = 197 + +func TestSlashMDY(t *testing.T) { + fixt := []Fixture{ + {"The Deadline is 10/10/2016", 16, "10/10/2016", (284 - OFFSET) * 24 * time.Hour}, + {"The Deadline is 2/1/2016", 16, "2/1/2016", (32 - OFFSET) * 24 * time.Hour}, + {"The Deadline is 2/29/2016", 16, "2/29/2016", (60 - OFFSET) * 24 * time.Hour}, + + // next year + {"The Deadline is 2/28", 16, "2/28", (59 + 366 - OFFSET) * 24 * time.Hour}, + {"The Deadline is 02/28/2017", 16, "02/28/2017", (59 + 366 - OFFSET) * 24 * time.Hour}, + + // right after w/o a year + {"The Deadline is 07/28", 16, "07/28", (210 - OFFSET) * 24 * time.Hour}, + + // before w/o a year + {"The Deadline is 06/30", 16, "06/30", (181 + 366 - OFFSET) * 24 * time.Hour}, + + // prev day will be added to the future + {"The Deadline is 07/14", 16, "07/14", (195 + 366 - OFFSET) * 24 * time.Hour}, + } + + w := when.New(nil) + w.Add(en.SlashMDY(rules.Override)) + + null = time.Date(2016, time.July, 15, 0, 0, 0, 0, time.UTC) + + ApplyFixtures(t, "en.SlashMDY", w, fixt) + + null = time.Date(2016, time.January, 6, 0, 0, 0, 0, time.UTC) + +}