From afa6a0f9344e9569740baf003242328fa2259ede Mon Sep 17 00:00:00 2001 From: Aaron Raddon Date: Thu, 11 Jan 2018 13:21:04 -0800 Subject: [PATCH] mm.dd.yyyy format closes #34 (pr #35) --- README.md | 7 +++++++ example/main.go | 7 +++++++ parseany.go | 48 +++++++++++++++++++++++++++++++++++++++++------- parseany_test.go | 15 +++++++++++++++ 4 files changed, 70 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 89f50c6..c09851f 100644 --- a/README.md +++ b/README.md @@ -127,6 +127,10 @@ var examples = []string{ "2014-04", "2014", "2014-05-11 08:20:13,787", + // mm.dd.yy + "3.31.2014", + "03.31.2014", + "08.21.71", // yyyymmdd and similar "20140601", // unix seconds, ms @@ -230,6 +234,9 @@ func main() { | 2014-04 | 2014-04-01 00:00:00 +0000 UTC | | 2014 | 2014-01-01 00:00:00 +0000 UTC | | 2014-05-11 08:20:13,787 | 2014-05-11 08:20:13.787 +0000 UTC | +| 3.31.2014 | 2014-03-31 00:00:00 +0000 UTC | +| 03.31.2014 | 2014-03-31 00:00:00 +0000 UTC | +| 08.21.71 | 1971-08-21 00:00:00 +0000 UTC | | 20140601 | 2014-06-01 00:00:00 +0000 UTC | | 1332151919 | 2012-03-19 10:11:59 +0000 UTC | | 1384216367189 | 2013-11-12 00:32:47.189 +0000 UTC | diff --git a/example/main.go b/example/main.go index 75125ea..72f99f0 100644 --- a/example/main.go +++ b/example/main.go @@ -76,6 +76,10 @@ var examples = []string{ "2014-04", "2014", "2014-05-11 08:20:13,787", + // mm.dd.yy + "3.31.2014", + "03.31.2014", + "08.21.71", // yyyymmdd and similar "20140601", // unix seconds, ms @@ -179,6 +183,9 @@ func main() { | 2014-04 | 2014-04-01 00:00:00 +0000 UTC | | 2014 | 2014-01-01 00:00:00 +0000 UTC | | 2014-05-11 08:20:13,787 | 2014-05-11 08:20:13.787 +0000 UTC | +| 3.31.2014 | 2014-03-31 00:00:00 +0000 UTC | +| 03.31.2014 | 2014-03-31 00:00:00 +0000 UTC | +| 08.21.71 | 1971-08-21 00:00:00 +0000 UTC | | 20140601 | 2014-06-01 00:00:00 +0000 UTC | | 1332151919 | 2012-03-19 10:11:59 +0000 UTC | | 1384216367189 | 2013-11-12 00:32:47.189 +0000 UTC | diff --git a/parseany.go b/parseany.go index 0c2526a..6a30dc7 100644 --- a/parseany.go +++ b/parseany.go @@ -36,6 +36,8 @@ const ( stateDigitDashTZDigit stateDigitDashTOffset stateDigitDashTOffsetColon + stateDigitDot + stateDigitDotDot stateDigitSlash stateDigitSlashWS stateDigitSlashWSColon @@ -119,7 +121,8 @@ func parse(layout, datestr string, loc *time.Location) (time.Time, error) { func parseTime(datestr string, loc *time.Location) (time.Time, error) { state := stateStart - firstSlash := 0 + part1Len := 0 + part2Len := 0 // General strategy is to read rune by rune through the date looking for // certain hints of what type of date we are dealing with. @@ -157,7 +160,10 @@ iterRunes: state = stateDigitDash case '/': state = stateDigitSlash - firstSlash = i + part1Len = i + case '.': + state = stateDigitDot + part1Len = i } case stateDigitDash: // starts digit then dash 02- // 2006-01-02T15:04:05Z07:00 @@ -431,6 +437,14 @@ iterRunes: case len(datestr) == len("02 Jan 2006, 15:04:05"): return parse("02 Jan 2006, 15:04:05", datestr, loc) } + case stateDigitDot: + // 3.31.2014 + if r == '.' { + state = stateDigitDotDot + part2Len = i + } + case stateDigitDotDot: + // iterate all the way through case stateAlpha: // starts alpha // stateAlphaWS // Mon Jan _2 15:04:05 2006 @@ -747,6 +761,26 @@ iterRunes: // 2016-03-14 00:00:00.000 +0000 UTC return parse("2006-01-02 15:04:05 -0700 UTC", datestr, loc) + case stateDigitDotDot: + + //u.Infof("%s lty?%v", datestr, len(datestr)-part2Len) + switch { + case len(datestr) == len("01.02.2006"): + return parse("01.02.2006", datestr, loc) + case len(datestr)-part2Len == 3: + for _, layout := range []string{"01.02.06", "1.02.06", "01.2.06", "1.2.06"} { + if t, err := parse(layout, datestr, loc); err == nil { + return t, nil + } + } + default: + for _, layout := range []string{"1.02.2006", "01.2.2006", "1.2.2006"} { + if t, err := parse(layout, datestr, loc); err == nil { + return t, nil + } + } + } + case stateAlphaWSAlphaColon: // Mon Jan _2 15:04:05 2006 return parse(time.ANSIC, datestr, loc) @@ -776,7 +810,7 @@ iterRunes: // 10/13/2014 // 01/02/2006 // 2014/10/13 - if firstSlash == 4 { + if part1Len == 4 { if len(datestr) == len("2006/01/02") { return parse("2006/01/02", datestr, loc) } @@ -794,7 +828,7 @@ iterRunes: // 2014/4/8 22:05 // 2014/04/08 22:05 - if firstSlash == 4 { + if part1Len == 4 { for _, layout := range []string{"2006/01/02 15:04", "2006/1/2 15:04", "2006/01/2 15:04", "2006/1/02 15:04"} { if t, err := parse(layout, datestr, loc); err == nil { return t, nil @@ -815,7 +849,7 @@ iterRunes: // 2014/4/8 22:05 PM // 2014/04/08 22:05 PM - if firstSlash == 4 { + if part1Len == 4 { for _, layout := range []string{"2006/01/02 03:04 PM", "2006/01/2 03:04 PM", "2006/1/02 03:04 PM", "2006/1/2 03:04 PM", "2006/01/02 3:04 PM", "2006/01/2 3:04 PM", "2006/1/02 3:04 PM", "2006/1/2 3:04 PM"} { if t, err := parse(layout, datestr, loc); err == nil { @@ -839,7 +873,7 @@ iterRunes: // 03/1/2012 10:11:59 // 3/01/2012 10:11:59 // 4/8/14 22:05 - if firstSlash == 4 { + if part1Len == 4 { for _, layout := range []string{"2006/01/02 15:04:05", "2006/1/02 15:04:05", "2006/01/2 15:04:05", "2006/1/2 15:04:05"} { if t, err := parse(layout, datestr, loc); err == nil { return t, nil @@ -860,7 +894,7 @@ iterRunes: // 03/1/2012 10:11:59 PM // 3/01/2012 10:11:59 PM - if firstSlash == 4 { + if part1Len == 4 { for _, layout := range []string{"2006/01/02 03:04:05 PM", "2006/1/02 03:04:05 PM", "2006/01/2 03:04:05 PM", "2006/1/2 03:04:05 PM", "2006/01/02 3:04:05 PM", "2006/1/02 3:04:05 PM", "2006/01/2 3:04:05 PM", "2006/1/2 3:04:05 PM"} { if t, err := parse(layout, datestr, loc); err == nil { diff --git a/parseany_test.go b/parseany_test.go index 2fb3a34..1a59dba 100644 --- a/parseany_test.go +++ b/parseany_test.go @@ -466,6 +466,21 @@ func TestParse(t *testing.T) { ts = MustParse("2016-06-21T19:55:00.799+0100") assert.Equal(t, "2016-06-21 18:55:00.799 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC))) + //--------------------------------------------- + // mm.dd.yyyy + // mm.dd.yy + + ts = MustParse("3.31.2014") + assert.Equal(t, "2014-03-31 00:00:00 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC))) + + ts = MustParse("03.31.2014") + assert.Equal(t, "2014-03-31 00:00:00 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC))) + + ts = MustParse("08.21.71") + assert.Equal(t, "1971-08-21 00:00:00 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC))) + + //--------------------------------------------- + // yyyymmdd and similar ts = MustParse("2014") assert.Equal(t, "2014-01-01 00:00:00 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))