From f08fe4265b54ec6b1d8c18bd3add9f6dcfe34694 Mon Sep 17 00:00:00 2001 From: shirHornstein Date: Thu, 8 Feb 2018 17:03:45 +0200 Subject: [PATCH] support more formats with one digits --- parseany.go | 595 ++++++++++++++++++++++++++++++++++++++++++----- parseany_test.go | 36 +++ 2 files changed, 570 insertions(+), 61 deletions(-) diff --git a/parseany.go b/parseany.go index 859a8dc..41ad356 100644 --- a/parseany.go +++ b/parseany.go @@ -492,7 +492,24 @@ iterRunes: switch { case r == '-': if i < 15 { - return parse("Monday, 02-Jan-06 15:04:05 MST", datestr, loc) + for _, layout := range []string{ + "Monday, 02-Jan-06 15:04:05 MST", + "Monday, 02-Jan-06 15:4:05 MST", + "Monday, 02-Jan-06 15:04:5 MST", + "Monday, 02-Jan-06 15:4:5 MST", + "Monday, 2-Jan-06 15:04:05 MST", + "Monday, 2-Jan-06 15:4:05 MST", + "Monday, 2-Jan-06 15:4:5 MST", + "Monday, 2-Jan-06 15:04:5 MST", + "Monday, 2-Jan-6 15:04:05 MST", + "Monday, 2-Jan-6 15:4:05 MST", + "Monday, 2-Jan-6 15:4:5 MST", + "Monday, 2-Jan-6 15:04:5 MST", + } { + if t, err := parse(layout, datestr, loc); err == nil { + return t, nil + } + } } state = stateWeekdayCommaOffset case r == '+': @@ -510,7 +527,24 @@ iterRunes: switch { case r == '-': if i < 15 { - return parse("Mon, 02-Jan-06 15:04:05 MST", datestr, loc) + for _, layout := range []string{ + "Mon, 02-Jan-06 15:04:05 MST", + "Mon, 02-Jan-06 15:4:05 MST", + "Mon, 02-Jan-06 15:04:5 MST", + "Mon, 02-Jan-06 15:4:5 MST", + "Mon, 2-Jan-06 15:04:05 MST", + "Mon, 2-Jan-06 15:4:05 MST", + "Mon, 2-Jan-06 15:4:5 MST", + "Mon, 2-Jan-06 15:04:5 MST", + "Mon, 2-Jan-6 15:04:05 MST", + "Mon, 2-Jan-6 15:4:05 MST", + "Mon, 2-Jan-6 15:4:5 MST", + "Mon, 2-Jan-6 15:04:5 MST", + } { + if t, err := parse(layout, datestr, loc); err == nil { + return t, nil + } + } } state = stateWeekdayAbbrevCommaOffset case r == '+': @@ -543,7 +577,20 @@ iterRunes: case stateAlphaWSDigitComma: // Starts Alpha, whitespace, digit, comma // May 8, 2009 5:57:51 PM - return parse("Jan 2, 2006 3:04:05 PM", datestr, loc) + for _, layout := range []string{ + "Jan 2, 2006 3:04:05 PM", + "Jan 2, 2006 3:4:05 PM", + "Jan 2, 2006 3:4:5 PM", + "Jan 2, 2006 3:04:5 PM", + "Jan 02, 2006 3:04:05 PM", + "Jan 02, 2006 3:4:05 PM", + "Jan 02, 2006 3:4:5 PM", + "Jan 02, 2006 3:04:5 PM", + } { + if t, err := parse(layout, datestr, loc); err == nil { + return t, nil + } + } case stateAlphaWSAlpha: // Alpha, whitespace, alpha // Mon Jan _2 15:04:05 2006 @@ -630,19 +677,58 @@ iterRunes: case stateDigitDash: // starts digit then dash 02- // 2006-01-02 + // 2006-1-02 + // 2006-1-2 + // 2006-01-2 // 2006-01 - if len(datestr) == len("2014-04-26") { - return parse("2006-01-02", datestr, loc) - } else if len(datestr) == len("2014-04") { - return parse("2006-01", datestr, loc) + for _, layout := range []string{ + "2006-01-02", + "2006-01", + "2006-1-2", + "2006-01-2", + "2006-1-02", + } { + if t, err := parse(layout, datestr, loc); err == nil { + return t, nil + } } + case stateDigitDashAlpha: // 2013-Feb-03 - return parse("2006-Jan-02", datestr, loc) + // 2013-Feb-3 + for _, layout := range []string{ + "2006-Jan-02", + "2006-Jan-2", + } { + if t, err := parse(layout, datestr, loc); err == nil { + return t, nil + } + } case stateDigitDashTOffset: // 2006-01-02T15:04:05+0000 - return parse("2006-01-02T15:04:05-0700", datestr, loc) + for _, layout := range []string{ + "2006-01-02T15:04:05-0700", + "2006-01-02T15:04:5-0700", + "2006-01-02T15:4:05-0700", + "2006-01-02T15:4:5-0700", + "2006-1-02T15:04:05-0700", + "2006-1-02T15:4:05-0700", + "2006-1-02T15:04:5-0700", + "2006-1-02T15:4:5-0700", + "2006-01-2T15:04:05-0700", + "2006-01-2T15:04:5-0700", + "2006-01-2T15:4:05-0700", + "2006-01-2T15:4:5-0700", + "2006-1-2T15:04:05-0700", + "2006-1-2T15:04:5-0700", + "2006-1-2T15:4:05-0700", + "2006-1-2T15:4:5-0700", + } { + if t, err := parse(layout, datestr, loc); err == nil { + return t, nil + } + } case stateDigitDashTOffsetColon: // With another +/- time-zone at end @@ -654,12 +740,54 @@ iterRunes: // 2006-01-02T15:04:05.999-07:00 // 2006-01-02T15:04:05+07:00 // 2006-01-02T15:04:05-07:00 - return parse("2006-01-02T15:04:05-07:00", datestr, loc) + for _, layout := range []string{ + "2006-01-02T15:04:05-07:00", + "2006-01-02T15:04:5-07:00", + "2006-01-02T15:4:05-07:00", + "2006-01-02T15:4:5-07:00", + "2006-1-02T15:04:05-07:00", + "2006-1-02T15:4:05-07:00", + "2006-1-02T15:04:5-07:00", + "2006-1-02T15:4:5-07:00", + "2006-01-2T15:04:05-07:00", + "2006-01-2T15:04:5-07:00", + "2006-01-2T15:4:05-07:00", + "2006-01-2T15:4:5-07:00", + "2006-1-2T15:04:05-07:00", + "2006-1-2T15:04:5-07:00", + "2006-1-2T15:4:05-07:00", + "2006-1-2T15:4:5-07:00", + } { + if t, err := parse(layout, datestr, loc); err == nil { + return t, nil + } + } case stateDigitDashT: // starts digit then dash 02- then T // 2006-01-02T15:04:05.999999 // 2006-01-02T15:04:05.999999 - return parse("2006-01-02T15:04:05", datestr, loc) + for _, layout := range []string{ + "2006-01-02T15:04:05", + "2006-01-02T15:04:5", + "2006-01-02T15:4:05", + "2006-01-02T15:4:5", + "2006-1-02T15:04:05", + "2006-1-02T15:4:05", + "2006-1-02T15:04:5", + "2006-1-02T15:4:5", + "2006-01-2T15:04:05", + "2006-01-2T15:04:5", + "2006-01-2T15:4:05", + "2006-01-2T15:4:5", + "2006-1-2T15:04:05", + "2006-1-2T15:04:5", + "2006-1-2T15:4:05", + "2006-1-2T15:4:5", + } { + if t, err := parse(layout, datestr, loc); err == nil { + return t, nil + } + } case stateDigitDashTZDigit: // With a time-zone at end after Z @@ -679,58 +807,259 @@ iterRunes: // 2006-01-02T15:04:05.999Z // 2006-01-02T15:04:05.99Z // 2009-08-12T22:15Z -- No seconds/milliseconds - switch len(datestr) { - case len("2009-08-12T22:15Z"): - return parse("2006-01-02T15:04Z", datestr, loc) - default: - return parse("2006-01-02T15:04:05Z", datestr, loc) + for _, layout := range []string{ + "2006-01-02T15:04:05Z", + "2006-01-02T15:04:5Z", + "2006-01-02T15:4:05Z", + "2006-01-02T15:4:5Z", + "2006-01-02T15:4Z", + "2006-01-02T15:04Z", + "2006-1-02T15:04:05Z", + "2006-1-02T15:4:05Z", + "2006-1-02T15:04:5Z", + "2006-1-02T15:4:5Z", + "2006-1-02T15:04Z", + "2006-1-02T15:4Z", + "2006-01-2T15:04:05Z", + "2006-01-2T15:04:5Z", + "2006-01-2T15:4:05Z", + "2006-01-2T15:4:5Z", + "2006-01-2T15:4Z", + "2006-01-2T15:04Z", + "2006-1-2T15:04:05Z", + "2006-1-2T15:04:5Z", + "2006-1-2T15:4:05Z", + "2006-1-2T15:4:5Z", + "2006-1-2T15:04Z", + "2006-1-2T15:4Z", + } { + if t, err := parse(layout, datestr, loc); err == nil { + return t, nil + } } + case stateDigitDashWs: // starts digit then dash 02- then whitespace 1 << 2 << 5 + 3 // 2013-04-01 22:43:22 // 2013-04-01 22:43 - switch len(datestr) { - case len("2013-04-01 22:43"): - return parse("2006-01-02 15:04", datestr, loc) - default: - return parse("2006-01-02 15:04:05", datestr, loc) + for _, layout := range []string{ + "2006-01-02 15:04:05", + "2006-01-02 15:04:5", + "2006-01-02 15:4:05", + "2006-01-02 15:4:5", + "2006-01-02 15:4", + "2006-01-02 15:04", + "2006-1-02 15:04:05", + "2006-1-02 15:4:05", + "2006-1-02 15:04:5", + "2006-1-02 15:4:5", + "2006-1-02 15:04", + "2006-1-02 15:4", + "2006-01-2 15:04:05", + "2006-01-2 15:04:5", + "2006-01-2 15:4:05", + "2006-01-2 15:4:5", + "2006-01-2 15:4", + "2006-01-2 15:04", + "2006-1-2 15:04:05", + "2006-1-2 15:04:5", + "2006-1-2 15:4:05", + "2006-1-2 15:4:5", + "2006-1-2 15:04", + "2006-1-2 15:4", + } { + if t, err := parse(layout, datestr, loc); err == nil { + return t, nil + } } case stateDigitDashWsWsOffset: // 2006-01-02 15:04:05 -0700 - return parse("2006-01-02 15:04:05 -0700", datestr, loc) + for _, layout := range []string{ + "2006-01-02 15:04:05 -0700", + "2006-01-02 15:04:5 -0700", + "2006-01-02 15:4:05 -0700", + "2006-01-02 15:4:5 -0700", + "2006-1-02 15:04:05 -0700", + "2006-1-02 15:4:05 -0700", + "2006-1-02 15:04:5 -0700", + "2006-1-02 15:4:5 -0700", + "2006-01-2 15:04:05 -0700", + "2006-01-2 15:04:5 -0700", + "2006-01-2 15:4:05 -0700", + "2006-01-2 15:4:5 -0700", + "2006-1-2 15:04:05 -0700", + "2006-1-2 15:04:5 -0700", + "2006-1-2 15:4:05 -0700", + "2006-1-2 15:4:5 -0700", + } { + if t, err := parse(layout, datestr, loc); err == nil { + return t, nil + } + } case stateDigitDashWsWsOffsetColon: // 2006-01-02 15:04:05 -07:00 - return parse("2006-01-02 15:04:05 -07:00", datestr, loc) + for _, layout := range []string{ + "2006-01-02 15:04:05 -07:00", + "2006-01-02 15:04:5 -07:00", + "2006-01-02 15:4:05 -07:00", + "2006-01-02 15:4:5 -07:00", + "2006-1-02 15:04:05 -07:00", + "2006-1-02 15:4:05 -07:00", + "2006-1-02 15:04:5 -07:00", + "2006-1-02 15:4:5 -07:00", + "2006-01-2 15:04:05 -07:00", + "2006-01-2 15:04:5 -07:00", + "2006-01-2 15:4:05 -07:00", + "2006-01-2 15:4:5 -07:00", + "2006-1-2 15:04:05 -07:00", + "2006-1-2 15:04:5 -07:00", + "2006-1-2 15:4:05 -07:00", + "2006-1-2 15:4:5 -07:00", + } { + if t, err := parse(layout, datestr, loc); err == nil { + return t, nil + } + } case stateDigitDashWsWsOffsetAlpha: // 2015-02-18 00:12:00 +0000 UTC - t, err := parse("2006-01-02 15:04:05 -0700 UTC", datestr, loc) - if err == nil { - return t, nil + + for _, layout := range []string{ + "2006-01-02 15:04:05 +0000 GMT", + "2006-01-02 15:04:5 +0000 GMT", + "2006-01-02 15:4:05 +0000 GMT", + "2006-01-02 15:4:5 +0000 GMT", + "2006-1-02 15:04:05 +0000 GMT", + "2006-1-02 15:4:05 +0000 GMT", + "2006-1-02 15:04:5 +0000 GMT", + "2006-1-02 15:4:5 +0000 GMT", + "2006-01-2 15:04:05 +0000 GMT", + "2006-01-2 15:04:5 +0000 GMT", + "2006-01-2 15:4:05 +0000 GMT", + "2006-01-2 15:4:5 +0000 GMT", + "2006-1-2 15:04:05 +0000 GMT", + "2006-1-2 15:04:5 +0000 GMT", + "2006-1-2 15:4:05 +0000 GMT", + "2006-1-2 15:4:5 +0000 GMT", + + "2006-01-02 15:04:05 -0700 UTC", + "2006-01-02 15:04:5 -0700 UTC", + "2006-01-02 15:4:05 -0700 UTC", + "2006-01-02 15:4:5 -0700 UTC", + "2006-1-02 15:04:05 -0700 UTC", + "2006-1-02 15:4:05 -0700 UTC", + "2006-1-02 15:04:5 -0700 UTC", + "2006-1-02 15:4:5 -0700 UTC", + "2006-01-2 15:04:05 -0700 UTC", + "2006-01-2 15:04:5 -0700 UTC", + "2006-01-2 15:4:05 -0700 UTC", + "2006-01-2 15:4:5 -0700 UTC", + "2006-1-2 15:04:05 -0700 UTC", + "2006-1-2 15:04:5 -0700 UTC", + "2006-1-2 15:4:05 -0700 UTC", + "2006-1-2 15:4:5 -0700 UTC", + } { + if t, err := parse(layout, datestr, loc); err == nil { + return t, nil + } } - return parse("2006-01-02 15:04:05 +0000 GMT", datestr, loc) + case stateDigitDashWsWsOffsetColonAlpha: // 2015-02-18 00:12:00 +00:00 UTC - return parse("2006-01-02 15:04:05 -07:00 UTC", datestr, loc) + for _, layout := range []string{ + "2006-01-02 15:04:05 -07:00 UTC", + "2006-01-02 15:04:5 -07:00 UTC", + "2006-01-02 15:4:05 -07:00 UTC", + "2006-01-02 15:4:5 -07:00 UTC", + "2006-1-02 15:04:05 -07:00 UTC", + "2006-1-02 15:4:05 -07:00 UTC", + "2006-1-02 15:04:5 -07:00 UTC", + "2006-1-02 15:4:5 -07:00 UTC", + "2006-01-2 15:04:05 -07:00 UTC", + "2006-01-2 15:04:5 -07:00 UTC", + "2006-01-2 15:4:05 -07:00 UTC", + "2006-01-2 15:4:5 -07:00 UTC", + "2006-1-2 15:04:05 -07:00 UTC", + "2006-1-2 15:04:5 -07:00 UTC", + "2006-1-2 15:4:05 -07:00 UTC", + "2006-1-2 15:4:5 -07:00 UTC", + } { + if t, err := parse(layout, datestr, loc); err == nil { + return t, nil + } + } case stateDigitDashWsOffset: // 2017-07-19 03:21:51+00:00 - return parse("2006-01-02 15:04:05-07:00", datestr, loc) + for _, layout := range []string{ + "2006-01-02 15:04:05-07:00", + "2006-01-02 15:04:5-07:00", + "2006-01-02 15:4:05-07:00", + "2006-01-02 15:4:5-07:00", + "2006-1-02 15:04:05-07:00", + "2006-1-02 15:4:05-07:00", + "2006-1-02 15:04:5-07:00", + "2006-1-02 15:4:5-07:00", + "2006-01-2 15:04:05-07:00", + "2006-01-2 15:04:5-07:00", + "2006-01-2 15:4:05-07:00", + "2006-01-2 15:4:5-07:00", + "2006-1-2 15:04:05-07:00", + "2006-1-2 15:04:5-07:00", + "2006-1-2 15:4:05-07:00", + "2006-1-2 15:4:5-07:00", + } { + if t, err := parse(layout, datestr, loc); err == nil { + return t, nil + } + } case stateDigitDashWsWsAlpha: // 2014-12-16 06:20:00 UTC - t, err := parse("2006-01-02 15:04:05 UTC", datestr, loc) - if err == nil { - return t, nil - } - t, err = parse("2006-01-02 15:04:05 GMT", datestr, loc) - if err == nil { - return t, nil + for _, layout := range []string{ + "2006-01-02 15:04:05 UTC", + "2006-01-02 15:04:5 UTC", + "2006-01-02 15:4:05 UTC", + "2006-01-02 15:4:5 UTC", + "2006-1-02 15:04:05 UTC", + "2006-1-02 15:4:05 UTC", + "2006-1-02 15:04:5 UTC", + "2006-1-02 15:4:5 UTC", + "2006-01-2 15:04:05 UTC", + "2006-01-2 15:04:5 UTC", + "2006-01-2 15:4:05 UTC", + "2006-01-2 15:4:5 UTC", + "2006-1-2 15:04:05 UTC", + "2006-1-2 15:04:5 UTC", + "2006-1-2 15:4:05 UTC", + "2006-1-2 15:4:5 UTC", + "2006-01-02 15:04:05 GMT", + "2006-01-02 15:04:5 GMT", + "2006-01-02 15:4:05 GMT", + "2006-01-02 15:4:5 GMT", + "2006-1-02 15:04:05 GMT", + "2006-1-02 15:4:05 GMT", + "2006-1-02 15:04:5 GMT", + "2006-1-02 15:4:5 GMT", + "2006-01-2 15:04:05 GMT", + "2006-01-2 15:04:5 GMT", + "2006-01-2 15:4:05 GMT", + "2006-01-2 15:4:5 GMT", + "2006-1-2 15:04:05 GMT", + "2006-1-2 15:04:5 GMT", + "2006-1-2 15:4:05 GMT", + "2006-1-2 15:4:5 GMT", + } { + if t, err := parse(layout, datestr, loc); err == nil { + return t, nil + } } + + if len(datestr) > len("2006-01-02 03:04:05") { - t, err = parse("2006-01-02 03:04:05", datestr[:len("2006-01-02 03:04:05")], loc) + t, err := parse("2006-01-02 03:04:05", datestr[:len("2006-01-02 03:04:05")], loc) if err == nil { return t, nil } @@ -741,28 +1070,112 @@ iterRunes: // 2014-04-26 17:24:37.3186369 // 2017-01-27 00:07:31.945167 // 2016-03-14 00:00:00.000 - return parse("2006-01-02 15:04:05", datestr, loc) + for _, layout := range []string{ + "2006-01-02 15:04:05", + "2006-01-02 15:04:5", + "2006-01-02 15:4:05", + "2006-01-02 15:4:5", + "2006-1-02 15:04:05", + "2006-1-02 15:4:05", + "2006-1-02 15:04:5", + "2006-1-02 15:4:5", + "2006-01-2 15:04:05", + "2006-01-2 15:04:5", + "2006-01-2 15:4:05", + "2006-01-2 15:4:5", + "2006-1-2 15:04:05", + "2006-1-2 15:04:5", + "2006-1-2 15:4:05", + "2006-1-2 15:4:5", + } { + if t, err := parse(layout, datestr, loc); err == nil { + return t, nil + } + } case stateDigitDashWsPeriodAlpha: // 2012-08-03 18:31:59.257000000 UTC // 2014-04-26 17:24:37.3186369 UTC // 2017-01-27 00:07:31.945167 UTC // 2016-03-14 00:00:00.000 UTC - return parse("2006-01-02 15:04:05 UTC", datestr, loc) + for _, layout := range []string{ + "2006-01-02 15:04:05 UTC", + "2006-01-02 15:04:5 UTC", + "2006-01-02 15:4:05 UTC", + "2006-01-02 15:4:5 UTC", + "2006-1-02 15:04:05 UTC", + "2006-1-02 15:4:05 UTC", + "2006-1-02 15:04:5 UTC", + "2006-1-02 15:4:5 UTC", + "2006-01-2 15:04:05 UTC", + "2006-01-2 15:04:5 UTC", + "2006-01-2 15:4:05 UTC", + "2006-01-2 15:4:5 UTC", + "2006-1-2 15:04:05 UTC", + "2006-1-2 15:04:5 UTC", + "2006-1-2 15:4:05 UTC", + "2006-1-2 15:4:5 UTC", + } { + if t, err := parse(layout, datestr, loc); err == nil { + return t, nil + } + } case stateDigitDashWsPeriodOffset: // 2012-08-03 18:31:59.257000000 +0000 // 2014-04-26 17:24:37.3186369 +0000 // 2017-01-27 00:07:31.945167 +0000 // 2016-03-14 00:00:00.000 +0000 - return parse("2006-01-02 15:04:05 -0700", datestr, loc) + for _, layout := range []string{ + "2006-01-02 15:04:05 -0700", + "2006-01-02 15:04:5 -0700", + "2006-01-02 15:4:05 -0700", + "2006-01-02 15:4:5 -0700", + "2006-1-02 15:04:05 -0700", + "2006-1-02 15:4:05 -0700", + "2006-1-02 15:04:5 -0700", + "2006-1-02 15:4:5 -0700", + "2006-01-2 15:04:05 -0700", + "2006-01-2 15:04:5 -0700", + "2006-01-2 15:4:05 -0700", + "2006-01-2 15:4:5 -0700", + "2006-1-2 15:04:05 -0700", + "2006-1-2 15:04:5 -0700", + "2006-1-2 15:4:05 -0700", + "2006-1-2 15:4:5 -0700", + } { + if t, err := parse(layout, datestr, loc); err == nil { + return t, nil + } + } case stateDigitDashWsPeriodOffsetAlpha: // 2012-08-03 18:31:59.257000000 +0000 UTC // 2014-04-26 17:24:37.3186369 +0000 UTC // 2017-01-27 00:07:31.945167 +0000 UTC // 2016-03-14 00:00:00.000 +0000 UTC - return parse("2006-01-02 15:04:05 -0700 UTC", datestr, loc) + for _, layout := range []string{ + "2006-01-02 15:04:05 -0700 UTC", + "2006-01-02 15:04:5 -0700 UTC", + "2006-01-02 15:4:05 -0700 UTC", + "2006-01-02 15:4:5 -0700 UTC", + "2006-1-02 15:04:05 -0700 UTC", + "2006-1-02 15:4:05 -0700 UTC", + "2006-1-02 15:04:5 -0700 UTC", + "2006-1-02 15:4:5 -0700 UTC", + "2006-01-2 15:04:05 -0700 UTC", + "2006-01-2 15:04:5 -0700 UTC", + "2006-01-2 15:4:05 -0700 UTC", + "2006-01-2 15:4:5 -0700 UTC", + "2006-1-2 15:04:05 -0700 UTC", + "2006-1-2 15:04:5 -0700 UTC", + "2006-1-2 15:4:05 -0700 UTC", + "2006-1-2 15:4:5 -0700 UTC", + } { + if t, err := parse(layout, datestr, loc); err == nil { + return t, nil + } + } case stateDigitDotDot: @@ -794,12 +1207,25 @@ iterRunes: case stateDigitWsAlphaComma: // 12 Feb 2006, 19:17 // 12 Feb 2006, 19:17:22 - switch { - case len(datestr) == len("02 Jan 2006, 15:04"): - return parse("02 Jan 2006, 15:04", datestr, loc) - case len(datestr) == len("02 Jan 2006, 15:04:05"): - return parse("02 Jan 2006, 15:04:05", datestr, loc) + for _, layout := range []string{ + "02 Jan 2006, 15:04", + "02 Jan 2006, 15:4", + "2 Jan 2006, 15:04", + "2 Jan 2006, 15:4", + "02 Jan 2006, 15:04:05", + "02 Jan 2006, 15:4:05", + "02 Jan 2006, 15:4:5", + "02 Jan 2006, 15:04:5", + "2 Jan 2006, 15:04:05", + "2 Jan 2006, 15:04:5", + "2 Jan 2006, 15:4:5", + "2 Jan 2006, 15:4:05", + } { + 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) @@ -848,13 +1274,13 @@ iterRunes: // 2014/04/08 22:05 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"} { + for _, layout := range []string{"2006/01/02 15:04", "2006/1/2 15:04", "2006/01/2 15:04", "2006/1/02 15:04", "2006/01/02 15:4", "2006/1/2 15:4", "2006/01/2 15:4", "2006/1/02 15:4"} { if t, err := parse(layout, datestr, loc); err == nil { return t, nil } } } else { - for _, layout := range []string{"01/02/2006 15:04", "01/2/2006 15:04", "1/02/2006 15:04", "1/2/2006 15:04", "1/2/06 15:04", "01/02/06 15:04"} { + for _, layout := range []string{"01/02/2006 15:4", "01/2/2006 15:4", "1/02/2006 15:4", "1/2/2006 15:4", "1/2/06 15:4", "01/02/06 15:4","01/02/2006 15:04", "01/2/2006 15:04", "1/02/2006 15:04", "1/2/2006 15:04", "1/2/06 15:04", "01/02/06 15:04"} { if t, err := parse(layout, datestr, loc); err == nil { return t, nil } @@ -870,14 +1296,19 @@ iterRunes: 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"} { + "2006/01/02 3:04 PM", "2006/01/2 3:04 PM", "2006/1/02 3:04 PM", "2006/1/2 3:04 PM", "2006/01/02 3:4 PM", "2006/01/2 3:4 PM", "2006/1/02 3:4 PM", "2006/1/2 3:4 PM", + "2006/01/02 3:4 PM", "2006/01/2 3:4 PM", "2006/1/02 3:4 PM", "2006/1/2 3:4 PM"} { if t, err := parse(layout, datestr, loc); err == nil { return t, nil } } } else { for _, layout := range []string{"01/02/2006 03:04 PM", "01/2/2006 03:04 PM", "1/02/2006 03:04 PM", "1/2/2006 03:04 PM", - "01/02/2006 3:04 PM", "01/2/2006 3:04 PM", "1/02/2006 3:04 PM", "1/2/2006 3:04 PM"} { + "01/02/2006 03:4 PM", "01/2/2006 03:4 PM", "1/02/2006 03:4 PM", "1/2/2006 03:4 PM", + "01/02/2006 3:04 PM", "01/2/2006 3:04 PM", "1/02/2006 3:04 PM", "1/2/2006 3:04 PM", + "01/02/2006 3:04 PM", "01/2/2006 3:04 PM", "1/02/2006 3:04 PM", "1/2/2006 3:04 PM", + "01/02/2006 3:4 PM", "01/2/2006 3:4 PM", "1/02/2006 3:4 PM", "1/2/2006 3:4 PM", + "01/02/2006 3:4 PM", "01/2/2006 3:4 PM", "1/02/2006 3:4 PM", "1/2/2006 3:4 PM"} { if t, err := parse(layout, datestr, loc); err == nil { return t, nil } @@ -893,13 +1324,19 @@ iterRunes: // 3/01/2012 10:11:59 // 4/8/14 22:05 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"} { + 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", + "2006/01/02 15:04:5", "2006/1/02 15:04:5", "2006/01/2 15:04:5", "2006/1/2 15:04:5", + "2006/01/02 15:4:05", "2006/1/02 15:4:05", "2006/01/2 15:4:05", "2006/1/2 15:4:05", + "2006/01/02 15:4:5", "2006/1/02 15:4:5", "2006/01/2 15:4:5", "2006/1/2 15:4:5"} { if t, err := parse(layout, datestr, loc); err == nil { return t, nil } } } else { - for _, layout := range []string{"01/02/2006 15:04:05", "1/02/2006 15:04:05", "01/2/2006 15:04:05", "1/2/2006 15:04:05"} { + for _, layout := range []string{"01/02/2006 15:04:05", "1/02/2006 15:04:05", "01/2/2006 15:04:05", "1/2/2006 15:04:05", + "01/02/2006 15:4:5", "1/02/2006 15:4:5", "01/2/2006 15:4:5", "1/2/2006 15:4:5", + "01/02/2006 15:4:05", "1/02/2006 15:4:05", "01/2/2006 15:4:05", "1/2/2006 15:4:05", + "01/02/2006 15:04:5", "1/02/2006 15:04:5", "01/2/2006 15:04:5", "1/2/2006 15:04:5"} { if t, err := parse(layout, datestr, loc); err == nil { return t, nil } @@ -915,13 +1352,23 @@ iterRunes: 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"} { + "2006/01/02 03:4:5 PM", "2006/1/02 03:4:5 PM", "2006/01/2 03:4:5 PM", "2006/1/2 03:4:5 PM", + "2006/01/02 03:4:05 PM", "2006/1/02 03:4:05 PM", "2006/01/2 03:4:05 PM", "2006/1/2 03:4:05 PM", + "2006/01/02 03:04:5 PM", "2006/1/02 03:04:5 PM", "2006/01/2 03:04:5 PM", "2006/1/2 03:04:5 PM", + + "2006/01/02 3:4:5 PM", "2006/1/02 3:4:5 PM", "2006/01/2 3:4:5 PM", "2006/1/2 3:4:5 PM", + "2006/01/02 3:4:05 PM", "2006/1/02 3:4:05 PM", "2006/01/2 3:4:05 PM", "2006/1/2 3:4:05 PM", + "2006/01/02 3:04:5 PM", "2006/1/02 3:04:5 PM", "2006/01/2 3:04:5 PM", "2006/1/2 3:04:5 PM"} { if t, err := parse(layout, datestr, loc); err == nil { return t, nil } } } else { - for _, layout := range []string{"01/02/2006 03:04:05 PM", "1/02/2006 03:04:05 PM", "01/2/2006 03:04:05 PM", "1/2/2006 03:04:05 PM"} { + for _, layout := range []string{"01/02/2006 03:04:05 PM", "1/02/2006 03:04:05 PM", "01/2/2006 03:04:05 PM", "1/2/2006 03:04:05 PM", + "01/02/2006 03:4:05 PM", "1/02/2006 03:4:05 PM", "01/2/2006 03:4:05 PM", "1/2/2006 03:4:05 PM", + "01/02/2006 03:04:5 PM", "1/02/2006 03:04:5 PM", "01/2/2006 03:04:5 PM", "1/2/2006 03:04:5 PM", + "01/02/2006 03:4:5 PM", "1/02/2006 03:4:5 PM", "01/2/2006 03:4:5 PM", "1/2/2006 03:4:5 PM", + } { if t, err := parse(layout, datestr, loc); err == nil { return t, nil } @@ -936,25 +1383,51 @@ iterRunes: case stateWeekdayCommaOffset: // Monday, 02 Jan 2006 15:04:05 -0700 // Monday, 02 Jan 2006 15:04:05 +0100 - return parse("Monday, 02 Jan 2006 15:04:05 -0700", datestr, loc) + for _, layout := range []string{ + "Monday, _2 Jan 2006 15:04:05 -0700", + "Monday, _2 Jan 2006 15:04:5 -0700", + "Monday, _2 Jan 2006 15:4:05 -0700", + "Monday, _2 Jan 2006 15:4:5 -0700", + } { + if t, err := parse(layout, datestr, loc); err == nil { + return t, nil + } + } + case stateWeekdayAbbrevComma: // Starts alpha then comma // Mon, 02-Jan-06 15:04:05 MST // Mon, 02 Jan 2006 15:04:05 MST - return parse("Mon, 02 Jan 2006 15:04:05 MST", datestr, loc) + for _, layout := range []string{ + "Mon, _2 Jan 2006 15:04:05 MST", + "Mon, _2 Jan 2006 15:04:5 MST", + "Mon, _2 Jan 2006 15:4:5 MST", + "Mon, _2 Jan 2006 15:4:05 MST", + } { + if t, err := parse(layout, datestr, loc); err == nil { + return t, nil + } + } + case stateWeekdayAbbrevCommaOffset: // Mon, 02 Jan 2006 15:04:05 -0700 // Thu, 13 Jul 2017 08:58:40 +0100 // RFC1123Z = "Mon, 02 Jan 2006 15:04:05 -0700" // RFC1123 with numeric zone // // Thu, 4 Jan 2018 17:53:36 +0000 - if len(datestr) > 10 && datestr[6] == ' ' { - // this really appears to be an invalid RFC1123 with non zero filled day - return parse("Mon, 2 Jan 2006 15:04:05 -0700", datestr, loc) + for _, layout := range []string{ + "Mon, _2 Jan 2006 15:04:05 -0700", + "Mon, _2 Jan 2006 15:4:05 -0700", + "Mon, _2 Jan 2006 15:4:5 -0700", + "Mon, _2 Jan 2006 15:04:5 -0700", + } { + if t, err := parse(layout, datestr, loc); err == nil { + return t, nil + } } - return parse("Mon, 02 Jan 2006 15:04:05 -0700", datestr, loc) + case stateWeekdayAbbrevCommaOffsetZone: // Tue, 11 Jul 2017 16:28:13 +0200 (CEST) - return parse("Mon, 02 Jan 2006 15:04:05 -0700 (CEST)", datestr, loc) + return parse("Mon, _2 Jan 2006 15:04:05 -0700 (CEST)", datestr, loc) } return time.Time{}, fmt.Errorf("Could not find date format for %s", datestr) diff --git a/parseany_test.go b/parseany_test.go index 96a9db1..4374e7c 100644 --- a/parseany_test.go +++ b/parseany_test.go @@ -121,6 +121,10 @@ func TestParse(t *testing.T) { ts = MustParse("May 8, 2009 5:57:51 PM") assert.Equal(t, "2009-05-08 17:57:51 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC))) + ts = MustParse("May 8, 2009 5:57:1 PM") + assert.Equal(t, "2009-05-08 17:57:01 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC))) + ts = MustParse("May 8, 2009 5:7:51 PM") + assert.Equal(t, "2009-05-08 17:07:51 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC))) // ANSIC = "Mon Jan _2 15:04:05 2006" ts = MustParse("Mon Jan 2 15:04:05 2006") @@ -143,6 +147,10 @@ func TestParse(t *testing.T) { // Monday, 02 Jan 2006 15:04:05 +0100 ts = MustParse("Monday, 02 Jan 2006 15:04:05 +0100") assert.Equal(t, "2006-01-02 14:04:05 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC))) + ts = MustParse("Monday, 02 Jan 2006 15:04:5 +0100") + assert.Equal(t, "2006-01-02 14:04:05 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC))) + ts = MustParse("Monday, 02 Jan 2006 15:4:05 +0100") + assert.Equal(t, "2006-01-02 14:04:05 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC))) ts = MustParse("Monday, 02 Jan 2006 15:04:05 -0100") assert.Equal(t, "2006-01-02 16:04:05 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC))) @@ -158,6 +166,12 @@ func TestParse(t *testing.T) { ts = MustParse("Mon, 02 Jan 2006 15:04:05 MST") assert.Equal(t, "2006-01-02 15:04:05 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC))) + ts = MustParse("Mon, 2 Jan 2006 15:4:05 MST") + assert.Equal(t, "2006-01-02 15:04:05 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC))) + + ts = MustParse("Mon, 2 Jan 2006 15:4:5 MST") + assert.Equal(t, "2006-01-02 15:04:05 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC))) + ts = MustParse("Mon, 02-Jan-06 15:04:05 MST") assert.Equal(t, "2006-01-02 15:04:05 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC))) @@ -169,6 +183,10 @@ func TestParse(t *testing.T) { ts = MustParse("Mon, 02 Jan 2006 15:04:05 -0700") assert.Equal(t, "2006-01-02 22:04:05 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC))) + ts = MustParse("Mon, 02 Jan 2006 15:4:05 -0700") + assert.Equal(t, "2006-01-02 22:04:05 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC))) + ts = MustParse("Mon, 02 Jan 2006 15:4:5 -0700") + assert.Equal(t, "2006-01-02 22:04:05 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC))) ts = MustParse("Thu, 4 Jan 2018 17:53:36 +0000") assert.Equal(t, "2018-01-04 17:53:36 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC))) @@ -274,6 +292,9 @@ func TestParse(t *testing.T) { ts = MustParse("2014/4/8 22:05") assert.Equal(t, "2014-04-08 22:05:00 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC))) + ts = MustParse("2014/4/8 2:05") + assert.Equal(t, "2014-04-08 02:05:00 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC))) + ts = MustParse("2014/04/08 22:05") assert.Equal(t, "2014-04-08 22:05:00 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC))) @@ -321,6 +342,9 @@ func TestParse(t *testing.T) { ts = MustParse("2009-08-12T22:15:09-07:00") assert.Equal(t, "2009-08-13 05:15:09 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC))) + ts = MustParse("2009-08-12T22:15:9-07:00") + assert.Equal(t, "2009-08-13 05:15:09 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC))) + ts = MustParse("2009-08-12T22:15:09.123-07:00") assert.Equal(t, "2009-08-13 05:15:09.123 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)), "%v", ts.In(time.UTC)) @@ -339,6 +363,9 @@ func TestParse(t *testing.T) { ts = MustParse("2009-08-12T22:15:09.99999999Z") assert.Equal(t, "2009-08-12 22:15:09.99999999 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC))) + ts = MustParse("2009-08-12T22:15:9.99999999Z") + assert.Equal(t, "2009-08-12 22:15:09.99999999 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC))) + // https://github.com/golang/go/issues/5294 _, err = ParseAny(time.RFC3339) assert.NotEqual(t, nil, err) @@ -365,6 +392,15 @@ func TestParse(t *testing.T) { ts = MustParse("2012-08-03 18:31:59.257000000 +0000 UTC") assert.Equal(t, "2012-08-03 18:31:59.257 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC))) + ts = MustParse("2012-08-03 8:1:59.257000000 +0000 UTC") + assert.Equal(t, "2012-08-03 08:01:59.257 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC))) + + ts = MustParse("2012-8-03 18:31:59.257000000 +0000 UTC") + assert.Equal(t, "2012-08-03 18:31:59.257 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC))) + + ts = MustParse("2012-8-3 18:31:59.257000000 +0000 UTC") + assert.Equal(t, "2012-08-03 18:31:59.257 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC))) + ts = MustParse("2015-09-30 18:48:56.35272715 +0000 UTC") assert.Equal(t, "2015-09-30 18:48:56.35272715 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))