diff --git a/parseany.go b/parseany.go index 23a39b7..abeff81 100644 --- a/parseany.go +++ b/parseany.go @@ -137,11 +137,12 @@ const ( var ( // ErrAmbiguousMMDD for date formats such as 04/02/2014 the MM/dd vs dd/MM are // ambiguous, so it is an error for strict parse rules. - ErrAmbiguousMMDD = fmt.Errorf("this date has ambiguous MM/dd vs dd/MM type format") + ErrAmbiguousMMDD = fmt.Errorf("this date has ambiguous MM/dd vs dd/MM type format") + ErrCouldNotFindFormat = fmt.Errorf("could not find format for") ) func unknownErr(datestr string) error { - return fmt.Errorf("could not find format for %q", datestr) + return fmt.Errorf("%w %q", ErrCouldNotFindFormat, datestr) } // ParseAny parse an unknown date format, detect the layout. @@ -236,7 +237,10 @@ func ParseStrict(datestr string, opts ...ParserOption) (time.Time, error) { func parseTime(datestr string, loc *time.Location, opts ...ParserOption) (p *parser, err error) { - p = newParser(datestr, loc, opts...) + p, err = newParser(datestr, loc, opts...) + if err != nil { + return + } if p.retryAmbiguousDateWithSwap { // month out of range signifies that a day/month swap is the correct solution to an ambiguous date // this is because it means that a day is being interpreted as a month and overflowing the valid value for that @@ -252,7 +256,7 @@ func parseTime(datestr string, loc *time.Location, opts ...ParserOption) (p *par // turn off the retry to avoid endless recursion retryAmbiguousDateWithSwap := RetryAmbiguousDateWithSwap(false) modifiedOpts := append(opts, preferMonthFirst, retryAmbiguousDateWithSwap) - p, err = parseTime(datestr, time.Local, modifiedOpts...) + p, _ = parseTime(datestr, time.Local, modifiedOpts...) } } @@ -1185,8 +1189,15 @@ iterRunes: // Thu, 4 Jan 2018 17:53:36 +0000 // Tue, 11 Jul 2017 16:28:13 +0200 (CEST) // Mon, 02-Jan-06 15:04:05 MST + var offset int switch r { - case ' ', '-': + case ' ': + for i+1 < len(datestr) && datestr[i+1] == ' ' { + i++ + offset++ + } + fallthrough + case '-': if p.dayi == 0 { p.dayi = i + 1 } else if p.moi == 0 { @@ -1194,11 +1205,11 @@ iterRunes: p.setDay() p.moi = i + 1 } else if p.yeari == 0 { - p.molen = i - p.moi + p.molen = i - p.moi - offset p.set(p.moi, "Jan") p.yeari = i + 1 } else { - p.yearlen = i - p.yeari + p.yearlen = i - p.yeari - offset p.setYear() p.stateTime = timeStart break iterRunes @@ -1421,7 +1432,12 @@ iterRunes: // 15:44:11 UTC+0100 2015 switch r { case '+', '-': - p.tzlen = i - p.tzi + if datestr[p.tzi:i] == "GMT" { + p.tzi = 0 + p.tzlen = 0 + } else { + p.tzlen = i - p.tzi + } if p.tzlen == 4 { p.set(p.tzi, " MST") } else if p.tzlen == 3 { @@ -1532,7 +1548,6 @@ iterRunes: if datestr[i-1] == 'm' { p.extra = i - 2 p.trimExtra() - break } case '+', '-', '(': // This really doesn't seem valid, but for some reason when round-tripping a go date @@ -1542,7 +1557,6 @@ iterRunes: p.extra = i - 1 p.stateTime = timeWsOffset p.trimExtra() - break default: switch { case unicode.IsDigit(r): @@ -1689,7 +1703,6 @@ iterRunes: // 00:00:00.000 +0300 +0300 p.extra = i - 1 p.trimExtra() - break default: if unicode.IsLetter(r) { // 00:07:31.945167 +0000 UTC @@ -1758,10 +1771,13 @@ iterRunes: p.trimExtra() case timeWsAlphaZoneOffset: // 06:20:00 UTC-05 - if i-p.offseti < 4 { + switch i - p.offseti { + case 2, 3, 4: p.set(p.offseti, "-07") - } else { + case 5: p.set(p.offseti, "-0700") + case 6: + p.set(p.offseti, "-07:00") } case timePeriod: @@ -2135,7 +2151,7 @@ func RetryAmbiguousDateWithSwap(retryAmbiguousDateWithSwap bool) ParserOption { } } -func newParser(dateStr string, loc *time.Location, opts ...ParserOption) *parser { +func newParser(dateStr string, loc *time.Location, opts ...ParserOption) (*parser, error) { p := &parser{ stateDate: dateStart, stateTime: timeIgnore, @@ -2148,9 +2164,11 @@ func newParser(dateStr string, loc *time.Location, opts ...ParserOption) *parser // allow the options to mutate the parser fields from their defaults for _, option := range opts { - _ = option(p) + if err := option(p); err != nil { + return nil, fmt.Errorf("option error: %w", err) + } } - return p + return p, nil } func (p *parser) nextIs(i int, b byte) bool { @@ -2268,17 +2286,6 @@ func (p *parser) trimExtra() { } } -// func (p *parser) remove(i, length int) { -// if len(p.format) > i+length { -// //append(a[:i], a[j:]...) -// p.format = append(p.format[0:i], p.format[i+length:]...) -// } -// if len(p.datestr) > i+length { -// //append(a[:i], a[j:]...) -// p.datestr = fmt.Sprintf("%s%s", p.datestr[0:i], p.datestr[i+length:]) -// } -// } - func (p *parser) parse() (time.Time, error) { if p.t != nil { return *p.t, nil diff --git a/parseany_test.go b/parseany_test.go index 4e55037..56f524b 100644 --- a/parseany_test.go +++ b/parseany_test.go @@ -10,8 +10,7 @@ import ( func TestOne(t *testing.T) { time.Local = time.UTC - var ts time.Time - ts = MustParse("2020-07-20+08:00") + ts := MustParse("2020-07-20+08:00") assert.Equal(t, "2020-07-19 16:00:00 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC))) } @@ -20,481 +19,508 @@ type dateTest struct { err bool } -var testInputs = []dateTest{ - {in: "oct 7, 1970", out: "1970-10-07 00:00:00 +0000 UTC"}, - {in: "oct 7, '70", out: "1970-10-07 00:00:00 +0000 UTC"}, - {in: "Oct 7, '70", out: "1970-10-07 00:00:00 +0000 UTC"}, - {in: "Oct. 7, '70", out: "1970-10-07 00:00:00 +0000 UTC"}, - {in: "oct. 7, '70", out: "1970-10-07 00:00:00 +0000 UTC"}, - {in: "oct. 7, 1970", out: "1970-10-07 00:00:00 +0000 UTC"}, - {in: "Sept. 7, '70", out: "1970-09-07 00:00:00 +0000 UTC"}, - {in: "sept. 7, 1970", out: "1970-09-07 00:00:00 +0000 UTC"}, - {in: "Feb 8, 2009 5:57:51 AM", out: "2009-02-08 05:57:51 +0000 UTC"}, - {in: "May 8, 2009 5:57:51 PM", out: "2009-05-08 17:57:51 +0000 UTC"}, - {in: "May 8, 2009 5:57:1 PM", out: "2009-05-08 17:57:01 +0000 UTC"}, - {in: "May 8, 2009 5:7:51 PM", out: "2009-05-08 17:07:51 +0000 UTC"}, - {in: "May 8, 2009, 5:7:51 PM", out: "2009-05-08 17:07:51 +0000 UTC"}, - {in: "7 oct 70", out: "1970-10-07 00:00:00 +0000 UTC"}, - {in: "7 oct 1970", out: "1970-10-07 00:00:00 +0000 UTC"}, - {in: "7 May 1970", out: "1970-05-07 00:00:00 +0000 UTC"}, - {in: "7 Sep 1970", out: "1970-09-07 00:00:00 +0000 UTC"}, - {in: "7 June 1970", out: "1970-06-07 00:00:00 +0000 UTC"}, - {in: "7 September 1970", out: "1970-09-07 00:00:00 +0000 UTC"}, - // ANSIC = "Mon Jan _2 15:04:05 2006" - {in: "Mon Jan 2 15:04:05 2006", out: "2006-01-02 15:04:05 +0000 UTC"}, - {in: "Thu May 8 17:57:51 2009", out: "2009-05-08 17:57:51 +0000 UTC"}, - {in: "Thu May 8 17:57:51 2009", out: "2009-05-08 17:57:51 +0000 UTC"}, - // ANSIC_GLIBC = "Mon 02 Jan 2006 03:04:05 PM UTC" - {in: "Mon 02 Jan 2006 03:04:05 PM UTC", out: "2006-01-02 15:04:05 +0000 UTC"}, - {in: "Mon 30 Sep 2018 09:09:09 PM UTC", out: "2018-09-30 21:09:09 +0000 UTC"}, - // RubyDate = "Mon Jan 02 15:04:05 -0700 2006" - {in: "Mon Jan 02 15:04:05 -0700 2006", out: "2006-01-02 22:04:05 +0000 UTC"}, - {in: "Thu May 08 11:57:51 -0700 2009", out: "2009-05-08 18:57:51 +0000 UTC"}, - // UnixDate = "Mon Jan _2 15:04:05 MST 2006" - {in: "Mon Jan 2 15:04:05 MST 2006", out: "2006-01-02 15:04:05 +0000 UTC"}, - {in: "Thu May 8 17:57:51 MST 2009", out: "2009-05-08 17:57:51 +0000 UTC"}, - {in: "Thu May 8 17:57:51 PST 2009", out: "2009-05-08 17:57:51 +0000 UTC"}, - {in: "Thu May 08 17:57:51 PST 2009", out: "2009-05-08 17:57:51 +0000 UTC"}, - {in: "Thu May 08 17:57:51 CEST 2009", out: "2009-05-08 17:57:51 +0000 UTC"}, - {in: "Thu May 08 05:05:07 PST 2009", out: "2009-05-08 05:05:07 +0000 UTC"}, - {in: "Thu May 08 5:5:7 PST 2009", out: "2009-05-08 05:05:07 +0000 UTC"}, - // Day Month dd time - {in: "Mon Aug 10 15:44:11 UTC+0000 2015", out: "2015-08-10 15:44:11 +0000 UTC"}, - {in: "Mon Aug 10 15:44:11 PST-0700 2015", out: "2015-08-10 22:44:11 +0000 UTC"}, - {in: "Mon Aug 10 15:44:11 CEST+0200 2015", out: "2015-08-10 13:44:11 +0000 UTC"}, - {in: "Mon Aug 1 15:44:11 CEST+0200 2015", out: "2015-08-01 13:44:11 +0000 UTC"}, - {in: "Mon Aug 1 5:44:11 CEST+0200 2015", out: "2015-08-01 03:44:11 +0000 UTC"}, - // ?? - {in: "Fri Jul 03 2015 18:04:07 GMT+0100 (GMT Daylight Time)", out: "2015-07-03 17:04:07 +0000 UTC"}, - {in: "Fri Jul 3 2015 06:04:07 GMT+0100 (GMT Daylight Time)", out: "2015-07-03 05:04:07 +0000 UTC"}, - {in: "Fri Jul 3 2015 06:04:07 PST-0700 (Pacific Daylight Time)", out: "2015-07-03 13:04:07 +0000 UTC"}, - // Month dd, yyyy at time - {in: "September 17, 2012 at 5:00pm UTC-05", out: "2012-09-17 17:00:00 +0000 UTC"}, - {in: "September 17, 2012 at 10:09am PST-08", out: "2012-09-17 18:09:00 +0000 UTC"}, - {in: "September 17, 2012, 10:10:09", out: "2012-09-17 10:10:09 +0000 UTC"}, - {in: "May 17, 2012 at 10:09am PST-08", out: "2012-05-17 18:09:00 +0000 UTC"}, - {in: "May 17, 2012 AT 10:09am PST-08", out: "2012-05-17 18:09:00 +0000 UTC"}, - // Month dd, yyyy time - {in: "September 17, 2012 5:00pm UTC-05", out: "2012-09-17 17:00:00 +0000 UTC"}, - {in: "September 17, 2012 10:09am PST-08", out: "2012-09-17 18:09:00 +0000 UTC"}, - {in: "September 17, 2012 09:01:00", out: "2012-09-17 09:01:00 +0000 UTC"}, - // Month dd yyyy time - {in: "September 17 2012 5:00pm UTC-05", out: "2012-09-17 17:00:00 +0000 UTC"}, - {in: "September 17 2012 5:00pm UTC-0500", out: "2012-09-17 17:00:00 +0000 UTC"}, - {in: "September 17 2012 10:09am PST-08", out: "2012-09-17 18:09:00 +0000 UTC"}, - {in: "September 17 2012 5:00PM UTC-05", out: "2012-09-17 17:00:00 +0000 UTC"}, - {in: "September 17 2012 10:09AM PST-08", out: "2012-09-17 18:09:00 +0000 UTC"}, - {in: "September 17 2012 09:01:00", out: "2012-09-17 09:01:00 +0000 UTC"}, - {in: "May 17, 2012 10:10:09", out: "2012-05-17 10:10:09 +0000 UTC"}, - // Month dd, yyyy - {in: "September 17, 2012", out: "2012-09-17 00:00:00 +0000 UTC"}, - {in: "May 7, 2012", out: "2012-05-07 00:00:00 +0000 UTC"}, - {in: "June 7, 2012", out: "2012-06-07 00:00:00 +0000 UTC"}, - {in: "June 7 2012", out: "2012-06-07 00:00:00 +0000 UTC"}, - // Month dd[th,nd,st,rd] yyyy - {in: "September 17th, 2012", out: "2012-09-17 00:00:00 +0000 UTC"}, - {in: "September 17th 2012", out: "2012-09-17 00:00:00 +0000 UTC"}, - {in: "September 7th, 2012", out: "2012-09-07 00:00:00 +0000 UTC"}, - {in: "September 7th 2012", out: "2012-09-07 00:00:00 +0000 UTC"}, - {in: "September 7tH 2012", out: "2012-09-07 00:00:00 +0000 UTC"}, - {in: "May 1st 2012", out: "2012-05-01 00:00:00 +0000 UTC"}, - {in: "May 1st, 2012", out: "2012-05-01 00:00:00 +0000 UTC"}, - {in: "May 21st 2012", out: "2012-05-21 00:00:00 +0000 UTC"}, - {in: "May 21st, 2012", out: "2012-05-21 00:00:00 +0000 UTC"}, - {in: "May 23rd 2012", out: "2012-05-23 00:00:00 +0000 UTC"}, - {in: "May 23rd, 2012", out: "2012-05-23 00:00:00 +0000 UTC"}, - {in: "June 2nd, 2012", out: "2012-06-02 00:00:00 +0000 UTC"}, - {in: "June 2nd 2012", out: "2012-06-02 00:00:00 +0000 UTC"}, - {in: "June 22nd, 2012", out: "2012-06-22 00:00:00 +0000 UTC"}, - {in: "June 22nd 2012", out: "2012-06-22 00:00:00 +0000 UTC"}, - // RFC1123 = "Mon, 02 Jan 2006 15:04:05 MST" - {in: "Fri, 03 Jul 2015 08:08:08 MST", out: "2015-07-03 08:08:08 +0000 UTC"}, - //{in: "Fri, 03 Jul 2015 08:08:08 CET", out: "2015-07-03 08:08:08 +0000 UTC"}, - {in: "Fri, 03 Jul 2015 08:08:08 PST", out: "2015-07-03 16:08:08 +0000 UTC", loc: "America/Los_Angeles"}, - {in: "Fri, 03 Jul 2015 08:08:08 PST", out: "2015-07-03 08:08:08 +0000 UTC"}, - {in: "Fri, 3 Jul 2015 08:08:08 MST", out: "2015-07-03 08:08:08 +0000 UTC"}, - {in: "Fri, 03 Jul 2015 8:08:08 MST", out: "2015-07-03 08:08:08 +0000 UTC"}, - {in: "Fri, 03 Jul 2015 8:8:8 MST", out: "2015-07-03 08:08:08 +0000 UTC"}, - // ? - {in: "Thu, 03 Jul 2017 08:08:04 +0100", out: "2017-07-03 07:08:04 +0000 UTC"}, - {in: "Thu, 03 Jul 2017 08:08:04 -0100", out: "2017-07-03 09:08:04 +0000 UTC"}, - {in: "Thu, 3 Jul 2017 08:08:04 +0100", out: "2017-07-03 07:08:04 +0000 UTC"}, - {in: "Thu, 03 Jul 2017 8:08:04 +0100", out: "2017-07-03 07:08:04 +0000 UTC"}, - {in: "Thu, 03 Jul 2017 8:8:4 +0100", out: "2017-07-03 07:08:04 +0000 UTC"}, - // - {in: "Tue, 11 Jul 2017 04:08:03 +0200 (CEST)", out: "2017-07-11 02:08:03 +0000 UTC"}, - {in: "Tue, 5 Jul 2017 04:08:03 -0700 (CEST)", out: "2017-07-05 11:08:03 +0000 UTC"}, - {in: "Tue, 11 Jul 2017 04:08:03 +0200 (CEST)", out: "2017-07-11 02:08:03 +0000 UTC", loc: "Europe/Berlin"}, - // day, dd-Mon-yy hh:mm:zz TZ - {in: "Fri, 03-Jul-15 08:08:08 MST", out: "2015-07-03 08:08:08 +0000 UTC"}, - {in: "Fri, 03-Jul-15 08:08:08 PST", out: "2015-07-03 16:08:08 +0000 UTC", loc: "America/Los_Angeles"}, - {in: "Fri, 03-Jul 2015 08:08:08 PST", out: "2015-07-03 08:08:08 +0000 UTC"}, - {in: "Fri, 3-Jul-15 08:08:08 MST", out: "2015-07-03 08:08:08 +0000 UTC"}, - {in: "Fri, 03-Jul-15 8:08:08 MST", out: "2015-07-03 08:08:08 +0000 UTC"}, - {in: "Fri, 03-Jul-15 8:8:8 MST", out: "2015-07-03 08:08:08 +0000 UTC"}, - // day, dd-Mon-yy hh:mm:zz TZ (text) https://github.com/araddon/dateparse/issues/116 - {in: "Sun, 3 Jan 2021 00:12:23 +0800 (GMT+08:00)", out: "2021-01-02 16:12:23 +0000 UTC"}, - // RFC850 = "Monday, 02-Jan-06 15:04:05 MST" - {in: "Wednesday, 07-May-09 08:00:43 MST", out: "2009-05-07 08:00:43 +0000 UTC"}, - {in: "Wednesday, 28-Feb-18 09:01:00 MST", out: "2018-02-28 09:01:00 +0000 UTC"}, - {in: "Wednesday, 28-Feb-18 09:01:00 MST", out: "2018-02-28 16:01:00 +0000 UTC", loc: "America/Denver"}, - // with offset then with variations on non-zero filled stuff - {in: "Monday, 02 Jan 2006 15:04:05 +0100", out: "2006-01-02 14:04:05 +0000 UTC"}, - {in: "Wednesday, 28 Feb 2018 09:01:00 -0300", out: "2018-02-28 12:01:00 +0000 UTC"}, - {in: "Wednesday, 2 Feb 2018 09:01:00 -0300", out: "2018-02-02 12:01:00 +0000 UTC"}, - {in: "Wednesday, 2 Feb 2018 9:01:00 -0300", out: "2018-02-02 12:01:00 +0000 UTC"}, - {in: "Wednesday, 2 Feb 2018 09:1:00 -0300", out: "2018-02-02 12:01:00 +0000 UTC"}, - // dd mon yyyy 12 Feb 2006, 19:17:08 - {in: "07 Feb 2004, 09:07", out: "2004-02-07 09:07:00 +0000 UTC"}, - {in: "07 Feb 2004, 09:07:07", out: "2004-02-07 09:07:07 +0000 UTC"}, - {in: "7 Feb 2004, 09:07:07", out: "2004-02-07 09:07:07 +0000 UTC"}, - {in: "07 Feb 2004, 9:7:7", out: "2004-02-07 09:07:07 +0000 UTC"}, - // dd Mon yyyy hh:mm:ss - {in: "07 Feb 2004 09:07:08", out: "2004-02-07 09:07:08 +0000 UTC"}, - {in: "07 Feb 2004 09:07", out: "2004-02-07 09:07:00 +0000 UTC"}, - {in: "7 Feb 2004 9:7:8", out: "2004-02-07 09:07:08 +0000 UTC"}, - {in: "07 Feb 2004 09:07:08.123", out: "2004-02-07 09:07:08.123 +0000 UTC"}, - // yyyy mmm dd - {in: "2013 May 02 11:37:55", out: "2013-05-02 11:37:55 +0000 UTC"}, // https://github.com/araddon/dateparse/issues/141 - // dd-mon-yyyy 12 Feb 2006, 19:17:08 GMT - {in: "07 Feb 2004, 09:07:07 GMT", out: "2004-02-07 09:07:07 +0000 UTC"}, - // dd-mon-yyyy 12 Feb 2006, 19:17:08 +0100 - {in: "07 Feb 2004, 09:07:07 +0100", out: "2004-02-07 08:07:07 +0000 UTC"}, - // dd-mon-yyyy 12-Feb-2006 19:17:08 - {in: "07-Feb-2004 09:07:07 +0100", out: "2004-02-07 08:07:07 +0000 UTC"}, - // dd-mon-yy 12-Feb-2006 19:17:08 - {in: "07-Feb-04 09:07:07 +0100", out: "2004-02-07 08:07:07 +0000 UTC"}, - // yyyy-mon-dd 2013-Feb-03 - {in: "2013-Feb-03", out: "2013-02-03 00:00:00 +0000 UTC"}, - // 03 February 2013 - {in: "03 February 2013", out: "2013-02-03 00:00:00 +0000 UTC"}, - {in: "3 February 2013", out: "2013-02-03 00:00:00 +0000 UTC"}, - // Chinese 2014年04月18日 - {in: "2014年04月08日", out: "2014-04-08 00:00:00 +0000 UTC"}, - {in: "2014年04月08日 19:17:22", out: "2014-04-08 19:17:22 +0000 UTC"}, - // mm/dd/yyyy - {in: "03/31/2014", out: "2014-03-31 00:00:00 +0000 UTC"}, - {in: "3/31/2014", out: "2014-03-31 00:00:00 +0000 UTC"}, - {in: "3/5/2014", out: "2014-03-05 00:00:00 +0000 UTC"}, - // mm/dd/yy - {in: "08/08/71", out: "1971-08-08 00:00:00 +0000 UTC"}, - {in: "8/8/71", out: "1971-08-08 00:00:00 +0000 UTC"}, - // mm/dd/yy hh:mm:ss - {in: "04/02/2014 04:08:09", out: "2014-04-02 04:08:09 +0000 UTC"}, - {in: "4/2/2014 04:08:09", out: "2014-04-02 04:08:09 +0000 UTC"}, - {in: "04/02/2014 4:08:09", out: "2014-04-02 04:08:09 +0000 UTC"}, - {in: "04/02/2014 4:8:9", out: "2014-04-02 04:08:09 +0000 UTC"}, - {in: "04/02/2014 04:08", out: "2014-04-02 04:08:00 +0000 UTC"}, - {in: "04/02/2014 4:8", out: "2014-04-02 04:08:00 +0000 UTC"}, - {in: "04/02/2014 04:08:09.123", out: "2014-04-02 04:08:09.123 +0000 UTC"}, - {in: "04/02/2014 04:08:09.12312", out: "2014-04-02 04:08:09.12312 +0000 UTC"}, - {in: "04/02/2014 04:08:09.123123", out: "2014-04-02 04:08:09.123123 +0000 UTC"}, - // mm:dd:yy hh:mm:ss - {in: "04:02:2014 04:08:09", out: "2014-04-02 04:08:09 +0000 UTC"}, - {in: "4:2:2014 04:08:09", out: "2014-04-02 04:08:09 +0000 UTC"}, - {in: "04:02:2014 4:08:09", out: "2014-04-02 04:08:09 +0000 UTC"}, - {in: "04:02:2014 4:8:9", out: "2014-04-02 04:08:09 +0000 UTC"}, - {in: "04:02:2014 04:08", out: "2014-04-02 04:08:00 +0000 UTC"}, - {in: "04:02:2014 4:8", out: "2014-04-02 04:08:00 +0000 UTC"}, - {in: "04:02:2014 04:08:09.123", out: "2014-04-02 04:08:09.123 +0000 UTC"}, - {in: "04:02:2014 04:08:09.12312", out: "2014-04-02 04:08:09.12312 +0000 UTC"}, - {in: "04:02:2014 04:08:09.123123", out: "2014-04-02 04:08:09.123123 +0000 UTC"}, - // mm/dd/yy hh:mm:ss AM - {in: "04/02/2014 04:08:09 AM", out: "2014-04-02 04:08:09 +0000 UTC"}, - {in: "04/02/2014 04:08:09 PM", out: "2014-04-02 16:08:09 +0000 UTC"}, - {in: "04/02/2014 04:08 AM", out: "2014-04-02 04:08:00 +0000 UTC"}, - {in: "04/02/2014 04:08 PM", out: "2014-04-02 16:08:00 +0000 UTC"}, - {in: "04/02/2014 4:8 AM", out: "2014-04-02 04:08:00 +0000 UTC"}, - {in: "04/02/2014 4:8 PM", out: "2014-04-02 16:08:00 +0000 UTC"}, - {in: "04/02/2014 04:08:09.123 AM", out: "2014-04-02 04:08:09.123 +0000 UTC"}, - {in: "04/02/2014 04:08:09.123 PM", out: "2014-04-02 16:08:09.123 +0000 UTC"}, - // yyyy/mm/dd - {in: "2014/04/02", out: "2014-04-02 00:00:00 +0000 UTC"}, - {in: "2014/03/31", out: "2014-03-31 00:00:00 +0000 UTC"}, - {in: "2014/4/2", out: "2014-04-02 00:00:00 +0000 UTC"}, - // yyyy/mm/dd hh:mm:ss AM - {in: "2014/04/02 04:08", out: "2014-04-02 04:08:00 +0000 UTC"}, - {in: "2014/03/31 04:08", out: "2014-03-31 04:08:00 +0000 UTC"}, - {in: "2014/4/2 04:08", out: "2014-04-02 04:08:00 +0000 UTC"}, - {in: "2014/04/02 4:8", out: "2014-04-02 04:08:00 +0000 UTC"}, - {in: "2014/04/02 04:08:09", out: "2014-04-02 04:08:09 +0000 UTC"}, - {in: "2014/03/31 04:08:09", out: "2014-03-31 04:08:09 +0000 UTC"}, - {in: "2014/4/2 04:08:09", out: "2014-04-02 04:08:09 +0000 UTC"}, - {in: "2014/04/02 04:08:09.123", out: "2014-04-02 04:08:09.123 +0000 UTC"}, - {in: "2014/04/02 04:08:09.123123", out: "2014-04-02 04:08:09.123123 +0000 UTC"}, - {in: "2014/04/02 04:08:09 AM", out: "2014-04-02 04:08:09 +0000 UTC"}, - {in: "2014/03/31 04:08:09 AM", out: "2014-03-31 04:08:09 +0000 UTC"}, - {in: "2014/4/2 04:08:09 AM", out: "2014-04-02 04:08:09 +0000 UTC"}, - {in: "2014/04/02 04:08:09.123 AM", out: "2014-04-02 04:08:09.123 +0000 UTC"}, - {in: "2014/04/02 04:08:09.123 PM", out: "2014-04-02 16:08:09.123 +0000 UTC"}, - // dd/mon/yyyy:hh:mm:ss tz nginx-log? https://github.com/araddon/dateparse/issues/118 - // 112.195.209.90 - - [20/Feb/2018:12:12:14 +0800] "GET / HTTP/1.1" 200 190 "-" "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Mobile Safari/537.36" "-" - {in: "06/May/2008:08:11:17 -0700", out: "2008-05-06 15:11:17 +0000 UTC"}, - {in: "30/May/2008:08:11:17 -0700", out: "2008-05-30 15:11:17 +0000 UTC"}, - // dd/mon/yyy hh:mm:ss tz - {in: "06/May/2008:08:11:17 -0700", out: "2008-05-06 15:11:17 +0000 UTC"}, - {in: "30/May/2008:08:11:17 -0700", out: "2008-05-30 15:11:17 +0000 UTC"}, - // yyyy-mm-dd - {in: "2014-04-02", out: "2014-04-02 00:00:00 +0000 UTC"}, - {in: "2014-03-31", out: "2014-03-31 00:00:00 +0000 UTC"}, - {in: "2014-4-2", out: "2014-04-02 00:00:00 +0000 UTC"}, - // yyyy-mm-dd-07:00 - {in: "2020-07-20+08:00", out: "2020-07-19 16:00:00 +0000 UTC"}, - {in: "2020-07-20+0800", out: "2020-07-19 16:00:00 +0000 UTC"}, - // dd-mmm-yy (alpha month) - {in: "28-Feb-02", out: "2002-02-28 00:00:00 +0000 UTC"}, - {in: "15-Jan-18", out: "2018-01-15 00:00:00 +0000 UTC"}, - {in: "15-Jan-2017", out: "2017-01-15 00:00:00 +0000 UTC"}, - // dd-mmm-yy (digit month) - {in: "28-02-02", out: "2002-02-28 00:00:00 +0000 UTC"}, // https://github.com/araddon/dateparse/issues/139 - {in: "15-01-18", out: "2018-01-15 00:00:00 +0000 UTC"}, - {in: "15-01-2017", out: "2017-01-15 00:00:00 +0000 UTC"}, - - // yyyy-mm - {in: "2014-04", out: "2014-04-01 00:00:00 +0000 UTC"}, - // yyyy-mm-dd hh:mm:ss AM - {in: "2014-04-02 04:08", out: "2014-04-02 04:08:00 +0000 UTC"}, - {in: "2014-03-31 04:08", out: "2014-03-31 04:08:00 +0000 UTC"}, - {in: "2014-4-2 04:08", out: "2014-04-02 04:08:00 +0000 UTC"}, - {in: "2014-04-02 4:8", out: "2014-04-02 04:08:00 +0000 UTC"}, - {in: "2014-04-02 04:08:09", out: "2014-04-02 04:08:09 +0000 UTC"}, - {in: "2014-03-31 04:08:09", out: "2014-03-31 04:08:09 +0000 UTC"}, - {in: "2014-4-2 04:08:09", out: "2014-04-02 04:08:09 +0000 UTC"}, - {in: "2014-04-02 04:08:09.123", out: "2014-04-02 04:08:09.123 +0000 UTC"}, - {in: "2014-04-02 04:08:09.123123", out: "2014-04-02 04:08:09.123123 +0000 UTC"}, - {in: "2014-04-02 04:08:09.12312312", out: "2014-04-02 04:08:09.12312312 +0000 UTC"}, - {in: "2014-04-02 04:08:09 AM", out: "2014-04-02 04:08:09 +0000 UTC"}, - {in: "2014-03-31 04:08:09 AM", out: "2014-03-31 04:08:09 +0000 UTC"}, - {in: "2014-04-26 05:24:37 PM", out: "2014-04-26 17:24:37 +0000 UTC"}, - {in: "2014-4-2 04:08:09 AM", out: "2014-04-02 04:08:09 +0000 UTC"}, - {in: "2014-04-02 04:08:09.123 AM", out: "2014-04-02 04:08:09.123 +0000 UTC"}, - {in: "2014-04-02 04:08:09.123 PM", out: "2014-04-02 16:08:09.123 +0000 UTC"}, - // yyyy-mm-dd hh:mm:ss,000 - {in: "2014-05-11 08:20:13,787", out: "2014-05-11 08:20:13.787 +0000 UTC"}, - // yyyy-mm-dd hh:mm:ss +0000 - {in: "2012-08-03 18:31:59 +0000", out: "2012-08-03 18:31:59 +0000 UTC"}, - {in: "2012-08-03 13:31:59 -0600", out: "2012-08-03 19:31:59 +0000 UTC"}, - {in: "2012-08-03 18:31:59.257000000 +0000", out: "2012-08-03 18:31:59.257 +0000 UTC"}, - {in: "2012-08-03 8:1:59.257000000 +0000", out: "2012-08-03 08:01:59.257 +0000 UTC"}, - {in: "2012-8-03 18:31:59.257000000 +0000", out: "2012-08-03 18:31:59.257 +0000 UTC"}, - {in: "2012-8-3 18:31:59.257000000 +0000", out: "2012-08-03 18:31:59.257 +0000 UTC"}, - {in: "2014-04-26 17:24:37.123456 +0000", out: "2014-04-26 17:24:37.123456 +0000 UTC"}, - {in: "2014-04-26 17:24:37.12 +0000", out: "2014-04-26 17:24:37.12 +0000 UTC"}, - {in: "2014-04-26 17:24:37.1 +0000", out: "2014-04-26 17:24:37.1 +0000 UTC"}, - {in: "2014-05-11 08:20:13 +0000", out: "2014-05-11 08:20:13 +0000 UTC"}, - {in: "2014-05-11 08:20:13 +0530", out: "2014-05-11 02:50:13 +0000 UTC"}, - // yyyy-mm-dd hh:mm:ss +0300 +03 ?? issue author said this is from golang? - {in: "2018-06-29 19:09:57.77297118 +0300 +03", out: "2018-06-29 16:09:57.77297118 +0000 UTC"}, - {in: "2018-06-29 19:09:57.77297118 +0300 +0300", out: "2018-06-29 16:09:57.77297118 +0000 UTC"}, - {in: "2018-06-29 19:09:57 +0300 +03", out: "2018-06-29 16:09:57 +0000 UTC"}, - {in: "2018-06-29 19:09:57 +0300 +0300", out: "2018-06-29 16:09:57 +0000 UTC"}, - - // 13:31:51.999 -07:00 MST - // yyyy-mm-dd hh:mm:ss +00:00 - {in: "2012-08-03 18:31:59 +00:00", out: "2012-08-03 18:31:59 +0000 UTC"}, - {in: "2014-05-01 08:02:13 +00:00", out: "2014-05-01 08:02:13 +0000 UTC"}, - {in: "2014-5-01 08:02:13 +00:00", out: "2014-05-01 08:02:13 +0000 UTC"}, - {in: "2014-05-1 08:02:13 +00:00", out: "2014-05-01 08:02:13 +0000 UTC"}, - {in: "2012-08-03 13:31:59 -06:00", out: "2012-08-03 19:31:59 +0000 UTC"}, - {in: "2012-08-03 18:31:59.257000000 +00:00", out: "2012-08-03 18:31:59.257 +0000 UTC"}, - {in: "2012-08-03 8:1:59.257000000 +00:00", out: "2012-08-03 08:01:59.257 +0000 UTC"}, - {in: "2012-8-03 18:31:59.257000000 +00:00", out: "2012-08-03 18:31:59.257 +0000 UTC"}, - {in: "2012-8-3 18:31:59.257000000 +00:00", out: "2012-08-03 18:31:59.257 +0000 UTC"}, - {in: "2014-04-26 17:24:37.123456 +00:00", out: "2014-04-26 17:24:37.123456 +0000 UTC"}, - {in: "2014-04-26 17:24:37.12 +00:00", out: "2014-04-26 17:24:37.12 +0000 UTC"}, - {in: "2014-04-26 17:24:37.1 +00:00", out: "2014-04-26 17:24:37.1 +0000 UTC"}, - // yyyy-mm-dd hh:mm:ss +0000 TZ - // Golang Native Format - {in: "2012-08-03 18:31:59 +0000 UTC", out: "2012-08-03 18:31:59 +0000 UTC"}, - {in: "2012-08-03 13:31:59 -0600 MST", out: "2012-08-03 19:31:59 +0000 UTC", loc: "America/Denver"}, - {in: "2015-02-18 00:12:00 +0000 UTC", out: "2015-02-18 00:12:00 +0000 UTC"}, - {in: "2015-02-18 00:12:00 +0000 GMT", out: "2015-02-18 00:12:00 +0000 UTC"}, - {in: "2015-02-08 03:02:00 +0200 CEST", out: "2015-02-08 01:02:00 +0000 UTC", loc: "Europe/Berlin"}, - {in: "2015-02-08 03:02:00 +0300 MSK", out: "2015-02-08 00:02:00 +0000 UTC"}, - {in: "2015-2-08 03:02:00 +0300 MSK", out: "2015-02-08 00:02:00 +0000 UTC"}, - {in: "2015-02-8 03:02:00 +0300 MSK", out: "2015-02-08 00:02:00 +0000 UTC"}, - {in: "2015-2-8 03:02:00 +0300 MSK", out: "2015-02-08 00:02:00 +0000 UTC"}, - {in: "2012-08-03 18:31:59.257000000 +0000 UTC", out: "2012-08-03 18:31:59.257 +0000 UTC"}, - {in: "2012-08-03 8:1:59.257000000 +0000 UTC", out: "2012-08-03 08:01:59.257 +0000 UTC"}, - {in: "2012-8-03 18:31:59.257000000 +0000 UTC", out: "2012-08-03 18:31:59.257 +0000 UTC"}, - {in: "2012-8-3 18:31:59.257000000 +0000 UTC", out: "2012-08-03 18:31:59.257 +0000 UTC"}, - {in: "2014-04-26 17:24:37.123456 +0000 UTC", out: "2014-04-26 17:24:37.123456 +0000 UTC"}, - {in: "2014-04-26 17:24:37.12 +0000 UTC", out: "2014-04-26 17:24:37.12 +0000 UTC"}, - {in: "2014-04-26 17:24:37.1 +0000 UTC", out: "2014-04-26 17:24:37.1 +0000 UTC"}, - {in: "2015-02-08 03:02:00 +0200 CEST m=+0.000000001", out: "2015-02-08 01:02:00 +0000 UTC", loc: "Europe/Berlin"}, - {in: "2015-02-08 03:02:00 +0300 MSK m=+0.000000001", out: "2015-02-08 00:02:00 +0000 UTC"}, - {in: "2015-02-08 03:02:00.001 +0300 MSK m=+0.000000001", out: "2015-02-08 00:02:00.001 +0000 UTC"}, - // yyyy-mm-dd hh:mm:ss TZ - {in: "2012-08-03 18:31:59 UTC", out: "2012-08-03 18:31:59 +0000 UTC"}, - {in: "2014-12-16 06:20:00 GMT", out: "2014-12-16 06:20:00 +0000 UTC"}, - {in: "2012-08-03 13:31:59 MST", out: "2012-08-03 20:31:59 +0000 UTC", loc: "America/Denver"}, - {in: "2012-08-03 18:31:59.257000000 UTC", out: "2012-08-03 18:31:59.257 +0000 UTC"}, - {in: "2012-08-03 8:1:59.257000000 UTC", out: "2012-08-03 08:01:59.257 +0000 UTC"}, - {in: "2012-8-03 18:31:59.257000000 UTC", out: "2012-08-03 18:31:59.257 +0000 UTC"}, - {in: "2012-8-3 18:31:59.257000000 UTC", out: "2012-08-03 18:31:59.257 +0000 UTC"}, - {in: "2014-04-26 17:24:37.123456 UTC", out: "2014-04-26 17:24:37.123456 +0000 UTC"}, - {in: "2014-04-26 17:24:37.12 UTC", out: "2014-04-26 17:24:37.12 +0000 UTC"}, - {in: "2014-04-26 17:24:37.1 UTC", out: "2014-04-26 17:24:37.1 +0000 UTC"}, - // This one is pretty special, it is TIMEZONE based but starts with P to emulate collions with PM - {in: "2014-04-26 05:24:37 PST", out: "2014-04-26 05:24:37 +0000 UTC"}, - {in: "2014-04-26 05:24:37 PST", out: "2014-04-26 13:24:37 +0000 UTC", loc: "America/Los_Angeles"}, - // yyyy-mm-dd hh:mm:ss+00:00 - {in: "2012-08-03 18:31:59+00:00", out: "2012-08-03 18:31:59 +0000 UTC"}, - {in: "2017-07-19 03:21:51+00:00", out: "2017-07-19 03:21:51 +0000 UTC"}, - // yyyy:mm:dd hh:mm:ss+00:00 - {in: "2012:08:03 18:31:59+00:00", out: "2012-08-03 18:31:59 +0000 UTC"}, - // dd:mm:yyyy hh:mm:ss+00:00 - {in: "08:03:2012 18:31:59+00:00", out: "2012-08-03 18:31:59 +0000 UTC"}, - // yyyy-mm-dd hh:mm:ss.000+00:00 PST - {in: "2012-08-03 18:31:59.000+00:00 PST", out: "2012-08-03 18:31:59 +0000 UTC", loc: "America/Los_Angeles"}, - // yyyy-mm-dd hh:mm:ss +00:00 TZ - {in: "2012-08-03 18:31:59 +00:00 UTC", out: "2012-08-03 18:31:59 +0000 UTC"}, - {in: "2012-08-03 13:31:51 -07:00 MST", out: "2012-08-03 20:31:51 +0000 UTC", loc: "America/Denver"}, - {in: "2012-08-03 18:31:59.257000000 +00:00 UTC", out: "2012-08-03 18:31:59.257 +0000 UTC"}, - {in: "2012-08-03 13:31:51.123 -08:00 PST", out: "2012-08-03 21:31:51.123 +0000 UTC", loc: "America/Los_Angeles"}, - {in: "2012-08-03 13:31:51.123 +02:00 CEST", out: "2012-08-03 11:31:51.123 +0000 UTC", loc: "Europe/Berlin"}, - {in: "2012-08-03 8:1:59.257000000 +00:00 UTC", out: "2012-08-03 08:01:59.257 +0000 UTC"}, - {in: "2012-8-03 18:31:59.257000000 +00:00 UTC", out: "2012-08-03 18:31:59.257 +0000 UTC"}, - {in: "2012-8-3 18:31:59.257000000 +00:00 UTC", out: "2012-08-03 18:31:59.257 +0000 UTC"}, - {in: "2014-04-26 17:24:37.123456 +00:00 UTC", out: "2014-04-26 17:24:37.123456 +0000 UTC"}, - {in: "2014-04-26 17:24:37.12 +00:00 UTC", out: "2014-04-26 17:24:37.12 +0000 UTC"}, - {in: "2014-04-26 17:24:37.1 +00:00 UTC", out: "2014-04-26 17:24:37.1 +0000 UTC"}, - // yyyy-mm-ddThh:mm:ss - {in: "2009-08-12T22:15:09", out: "2009-08-12 22:15:09 +0000 UTC"}, - {in: "2009-08-08T02:08:08", out: "2009-08-08 02:08:08 +0000 UTC"}, - {in: "2009-08-08T2:8:8", out: "2009-08-08 02:08:08 +0000 UTC"}, - {in: "2009-08-12T22:15:09.123", out: "2009-08-12 22:15:09.123 +0000 UTC"}, - {in: "2009-08-12T22:15:09.123456", out: "2009-08-12 22:15:09.123456 +0000 UTC"}, - {in: "2009-08-12T22:15:09.12", out: "2009-08-12 22:15:09.12 +0000 UTC"}, - {in: "2009-08-12T22:15:09.1", out: "2009-08-12 22:15:09.1 +0000 UTC"}, - {in: "2014-04-26 17:24:37.3186369", out: "2014-04-26 17:24:37.3186369 +0000 UTC"}, - // yyyy-mm-ddThh:mm:ss-07:00 - {in: "2009-08-12T22:15:09-07:00", out: "2009-08-13 05:15:09 +0000 UTC"}, - {in: "2009-08-12T22:15:09-03:00", out: "2009-08-13 01:15:09 +0000 UTC"}, - {in: "2009-08-12T22:15:9-07:00", out: "2009-08-13 05:15:09 +0000 UTC"}, - {in: "2009-08-12T22:15:09.123-07:00", out: "2009-08-13 05:15:09.123 +0000 UTC"}, - {in: "2016-06-21T19:55:00+01:00", out: "2016-06-21 18:55:00 +0000 UTC"}, - {in: "2016-06-21T19:55:00.799+01:00", out: "2016-06-21 18:55:00.799 +0000 UTC"}, - // yyyy-mm-ddThh:mm:ss-07 TZ truncated to 2 digits instead of 4 - {in: "2019-05-29T08:41-04", out: "2019-05-29 12:41:00 +0000 UTC"}, - // yyyy-mm-ddThh:mm:ss-0700 - {in: "2009-08-12T22:15:09-0700", out: "2009-08-13 05:15:09 +0000 UTC"}, - {in: "2009-08-12T22:15:09-0300", out: "2009-08-13 01:15:09 +0000 UTC"}, - {in: "2009-08-12T22:15:9-0700", out: "2009-08-13 05:15:09 +0000 UTC"}, - {in: "2009-08-12T22:15:09.123-0700", out: "2009-08-13 05:15:09.123 +0000 UTC"}, - {in: "2016-06-21T19:55:00+0100", out: "2016-06-21 18:55:00 +0000 UTC"}, - {in: "2016-06-21T19:55:00.799+0100", out: "2016-06-21 18:55:00.799 +0000 UTC"}, - {in: "2016-06-21T19:55:00+0100", out: "2016-06-21 18:55:00 +0000 UTC"}, - {in: "2016-06-21T19:55:00-0700", out: "2016-06-22 02:55:00 +0000 UTC"}, - {in: "2016-06-21T19:55:00.799+0100", out: "2016-06-21 18:55:00.799 +0000 UTC"}, - {in: "2016-06-21T19:55+0100", out: "2016-06-21 18:55:00 +0000 UTC"}, - {in: "2016-06-21T19:55+0130", out: "2016-06-21 18:25:00 +0000 UTC"}, - // yyyy-mm-ddThh:mm:ss:000+0000 - weird format with additional colon in front of milliseconds - {in: "2012-08-17T18:31:59:257+0100", out: "2012-08-17 17:31:59.257 +0000 UTC"}, // https://github.com/araddon/dateparse/issues/117 - {in: "2012-08-17T18:31:59:257", out: "2012-08-17 18:31:59.257 +0000 UTC"}, // https://github.com/araddon/dateparse/issues/137 - - // yyyy-mm-ddThh:mm:ssZ - {in: "2009-08-12T22:15Z", out: "2009-08-12 22:15:00 +0000 UTC"}, - {in: "2009-08-12T22:15:09Z", out: "2009-08-12 22:15:09 +0000 UTC"}, - {in: "2009-08-12T22:15:09.99Z", out: "2009-08-12 22:15:09.99 +0000 UTC"}, - {in: "2009-08-12T22:15:09.9999Z", out: "2009-08-12 22:15:09.9999 +0000 UTC"}, - {in: "2009-08-12T22:15:09.99999999Z", out: "2009-08-12 22:15:09.99999999 +0000 UTC"}, - {in: "2009-08-12T22:15:9.99999999Z", out: "2009-08-12 22:15:09.99999999 +0000 UTC"}, - // yyyy.mm - {in: "2014.05", out: "2014-05-01 00:00:00 +0000 UTC"}, - {in: "2018.09.30", out: "2018-09-30 00:00:00 +0000 UTC"}, +func TestParse(t *testing.T) { - // mm.dd.yyyy - {in: "3.31.2014", out: "2014-03-31 00:00:00 +0000 UTC"}, - {in: "3.3.2014", out: "2014-03-03 00:00:00 +0000 UTC"}, - {in: "03.31.2014", out: "2014-03-31 00:00:00 +0000 UTC"}, - // mm.dd.yy - {in: "08.21.71", out: "1971-08-21 00:00:00 +0000 UTC"}, - // dd.mm.yyyy - {in: "23.07.1938", out: "1938-07-23 00:00:00 +0000 UTC"}, - {in: "23/07/1938", out: "1938-07-23 00:00:00 +0000 UTC"}, - // yyyymmdd and similar - {in: "2014", out: "2014-01-01 00:00:00 +0000 UTC"}, - {in: "20140601", out: "2014-06-01 00:00:00 +0000 UTC"}, - {in: "20140722105203", out: "2014-07-22 10:52:03 +0000 UTC"}, - {in: "20140722105203.364", out: "2014-07-22 10:52:03.364 +0000 UTC"}, - // yymmdd hh:mm:yy mysql log https://github.com/araddon/dateparse/issues/119 - // 080313 05:21:55 mysqld started - // 080313 5:21:55 InnoDB: Started; log sequence number 0 43655 - {in: "171113 14:14:20", out: "2017-11-13 14:14:20 +0000 UTC"}, - - // all digits: unix secs, ms etc - {in: "1332151919.329", out: "2012-03-19 10:11:59.329 +0000 UTC"}, - {in: "1332151919.32", out: "2012-03-19 10:11:59.32 +0000 UTC"}, - {in: "1332151919.", out: "2012-03-19 10:11:59 +0000 UTC"}, - {in: "1332151919.001", out: "2012-03-19 10:11:59.001 +0000 UTC"}, - {in: "1332151919", out: "2012-03-19 10:11:59 +0000 UTC"}, - {in: "1332151919", out: "2012-03-19 10:11:59 +0000 UTC", loc: "America/Denver"}, - {in: "1384216367111", out: "2013-11-12 00:32:47.111 +0000 UTC"}, - {in: "1384216367111222", out: "2013-11-12 00:32:47.111222 +0000 UTC"}, - {in: "1384216367111222333", out: "2013-11-12 00:32:47.111222333 +0000 UTC"}, - - // dd[th,nd,st,rd] Month yyyy - {in: "1st September 2012", out: "2012-09-01 00:00:00 +0000 UTC"}, - {in: "2nd September 2012", out: "2012-09-02 00:00:00 +0000 UTC"}, - {in: "3rd September 2012", out: "2012-09-03 00:00:00 +0000 UTC"}, - {in: "4th September 2012", out: "2012-09-04 00:00:00 +0000 UTC"}, - {in: "2nd January 2018", out: "2018-01-02 00:00:00 +0000 UTC"}, - {in: "3nd Feb 2018 13:58:24", out: "2018-02-03 13:58:24 +0000 UTC"}, -} + type dateTest struct { + in, out, loc string + err bool + } -func TestParse(t *testing.T) { + var testInputs = []dateTest{ + {in: "oct 7, 1970", out: "1970-10-07 00:00:00 +0000 UTC"}, + {in: "oct 7, '70", out: "1970-10-07 00:00:00 +0000 UTC"}, + {in: "Oct 7, '70", out: "1970-10-07 00:00:00 +0000 UTC"}, + {in: "Oct. 7, '70", out: "1970-10-07 00:00:00 +0000 UTC"}, + {in: "oct. 7, '70", out: "1970-10-07 00:00:00 +0000 UTC"}, + {in: "oct. 7, 1970", out: "1970-10-07 00:00:00 +0000 UTC"}, + {in: "Sept. 7, '70", out: "1970-09-07 00:00:00 +0000 UTC"}, + {in: "sept. 7, 1970", out: "1970-09-07 00:00:00 +0000 UTC"}, + {in: "Feb 8, 2009 5:57:51 AM", out: "2009-02-08 05:57:51 +0000 UTC"}, + {in: "May 8, 2009 5:57:51 PM", out: "2009-05-08 17:57:51 +0000 UTC"}, + {in: "May 8, 2009 5:57:1 PM", out: "2009-05-08 17:57:01 +0000 UTC"}, + {in: "May 8, 2009 5:7:51 PM", out: "2009-05-08 17:07:51 +0000 UTC"}, + {in: "May 8, 2009, 5:7:51 PM", out: "2009-05-08 17:07:51 +0000 UTC"}, + {in: "7 oct 70", out: "1970-10-07 00:00:00 +0000 UTC"}, + {in: "7 oct 1970", out: "1970-10-07 00:00:00 +0000 UTC"}, + {in: "7 May 1970", out: "1970-05-07 00:00:00 +0000 UTC"}, + {in: "7 Sep 1970", out: "1970-09-07 00:00:00 +0000 UTC"}, + {in: "7 June 1970", out: "1970-06-07 00:00:00 +0000 UTC"}, + {in: "7 September 1970", out: "1970-09-07 00:00:00 +0000 UTC"}, + // ANSIC = "Mon Jan _2 15:04:05 2006" + {in: "Mon Jan 2 15:04:05 2006", out: "2006-01-02 15:04:05 +0000 UTC"}, + {in: "Thu May 8 17:57:51 2009", out: "2009-05-08 17:57:51 +0000 UTC"}, + {in: "Thu May 8 17:57:51 2009", out: "2009-05-08 17:57:51 +0000 UTC"}, + // ANSIC_GLIBC = "Mon 02 Jan 2006 03:04:05 PM UTC" + {in: "Mon 02 Jan 2006 03:04:05 PM UTC", out: "2006-01-02 15:04:05 +0000 UTC"}, + {in: "Mon 30 Sep 2018 09:09:09 PM UTC", out: "2018-09-30 21:09:09 +0000 UTC"}, + // RubyDate = "Mon Jan 02 15:04:05 -0700 2006" + {in: "Mon Jan 02 15:04:05 -0700 2006", out: "2006-01-02 22:04:05 +0000 UTC"}, + {in: "Thu May 08 11:57:51 -0700 2009", out: "2009-05-08 18:57:51 +0000 UTC"}, + // UnixDate = "Mon Jan _2 15:04:05 MST 2006" + {in: "Mon Jan 2 15:04:05 MST 2006", out: "2006-01-02 15:04:05 +0000 UTC"}, + {in: "Thu May 8 17:57:51 MST 2009", out: "2009-05-08 17:57:51 +0000 UTC"}, + {in: "Thu May 8 17:57:51 PST 2009", out: "2009-05-08 17:57:51 +0000 UTC"}, + {in: "Thu May 08 17:57:51 PST 2009", out: "2009-05-08 17:57:51 +0000 UTC"}, + {in: "Thu May 08 17:57:51 CEST 2009", out: "2009-05-08 17:57:51 +0000 UTC"}, + {in: "Thu May 08 05:05:07 PST 2009", out: "2009-05-08 05:05:07 +0000 UTC"}, + {in: "Thu May 08 5:5:7 PST 2009", out: "2009-05-08 05:05:07 +0000 UTC"}, + // Day Month dd time + {in: "Mon Aug 10 15:44:11 UTC+0000 2015", out: "2015-08-10 15:44:11 +0000 UTC"}, + {in: "Mon Aug 10 15:44:11 PST-0700 2015", out: "2015-08-10 22:44:11 +0000 UTC"}, + {in: "Mon Aug 10 15:44:11 CEST+0200 2015", out: "2015-08-10 13:44:11 +0000 UTC"}, + {in: "Mon Aug 1 15:44:11 CEST+0200 2015", out: "2015-08-01 13:44:11 +0000 UTC"}, + {in: "Mon Aug 1 5:44:11 CEST+0200 2015", out: "2015-08-01 03:44:11 +0000 UTC"}, + // ?? + {in: "Fri Jul 03 2015 18:04:07 GMT+0100 (GMT Daylight Time)", out: "2015-07-03 17:04:07 +0000 UTC"}, + {in: "Fri Jul 3 2015 06:04:07 GMT+0100 (GMT Daylight Time)", out: "2015-07-03 05:04:07 +0000 UTC"}, + {in: "Fri Jul 3 2015 06:04:07 PST-0700 (Pacific Daylight Time)", out: "2015-07-03 13:04:07 +0000 UTC"}, + // Month dd, yyyy at time + {in: "September 17, 2012 at 5:00pm UTC-05", out: "2012-09-17 17:00:00 +0000 UTC"}, + {in: "September 17, 2012 at 10:09am PST-08", out: "2012-09-17 18:09:00 +0000 UTC"}, + {in: "September 17, 2012, 10:10:09", out: "2012-09-17 10:10:09 +0000 UTC"}, + {in: "May 17, 2012 at 10:09am PST-08", out: "2012-05-17 18:09:00 +0000 UTC"}, + {in: "May 17, 2012 AT 10:09am PST-08", out: "2012-05-17 18:09:00 +0000 UTC"}, + // Month dd, yyyy time + {in: "September 17, 2012 5:00pm UTC-05", out: "2012-09-17 17:00:00 +0000 UTC"}, + {in: "September 17, 2012 10:09am PST-08", out: "2012-09-17 18:09:00 +0000 UTC"}, + {in: "September 17, 2012 09:01:00", out: "2012-09-17 09:01:00 +0000 UTC"}, + // Month dd yyyy time + {in: "September 17 2012 5:00pm UTC-05", out: "2012-09-17 17:00:00 +0000 UTC"}, + {in: "September 17 2012 5:00pm UTC-0500", out: "2012-09-17 17:00:00 +0000 UTC"}, + {in: "September 17 2012 10:09am PST-08", out: "2012-09-17 18:09:00 +0000 UTC"}, + {in: "September 17 2012 5:00PM UTC-05", out: "2012-09-17 17:00:00 +0000 UTC"}, + {in: "September 17 2012 10:09AM PST-08", out: "2012-09-17 18:09:00 +0000 UTC"}, + {in: "September 17 2012 09:01:00", out: "2012-09-17 09:01:00 +0000 UTC"}, + {in: "May 17, 2012 10:10:09", out: "2012-05-17 10:10:09 +0000 UTC"}, + // Month dd, yyyy + {in: "September 17, 2012", out: "2012-09-17 00:00:00 +0000 UTC"}, + {in: "May 7, 2012", out: "2012-05-07 00:00:00 +0000 UTC"}, + {in: "June 7, 2012", out: "2012-06-07 00:00:00 +0000 UTC"}, + {in: "June 7 2012", out: "2012-06-07 00:00:00 +0000 UTC"}, + // Month dd[th,nd,st,rd] yyyy + {in: "September 17th, 2012", out: "2012-09-17 00:00:00 +0000 UTC"}, + {in: "September 17th 2012", out: "2012-09-17 00:00:00 +0000 UTC"}, + {in: "September 7th, 2012", out: "2012-09-07 00:00:00 +0000 UTC"}, + {in: "September 7th 2012", out: "2012-09-07 00:00:00 +0000 UTC"}, + {in: "September 7tH 2012", out: "2012-09-07 00:00:00 +0000 UTC"}, + {in: "May 1st 2012", out: "2012-05-01 00:00:00 +0000 UTC"}, + {in: "May 1st, 2012", out: "2012-05-01 00:00:00 +0000 UTC"}, + {in: "May 21st 2012", out: "2012-05-21 00:00:00 +0000 UTC"}, + {in: "May 21st, 2012", out: "2012-05-21 00:00:00 +0000 UTC"}, + {in: "May 23rd 2012", out: "2012-05-23 00:00:00 +0000 UTC"}, + {in: "May 23rd, 2012", out: "2012-05-23 00:00:00 +0000 UTC"}, + {in: "June 2nd, 2012", out: "2012-06-02 00:00:00 +0000 UTC"}, + {in: "June 2nd 2012", out: "2012-06-02 00:00:00 +0000 UTC"}, + {in: "June 22nd, 2012", out: "2012-06-22 00:00:00 +0000 UTC"}, + {in: "June 22nd 2012", out: "2012-06-22 00:00:00 +0000 UTC"}, + // RFC1123 = "Mon, 02 Jan 2006 15:04:05 MST" + {in: "Fri, 03 Jul 2015 08:08:08 MST", out: "2015-07-03 08:08:08 +0000 UTC"}, + //{in: "Fri, 03 Jul 2015 08:08:08 CET", out: "2015-07-03 08:08:08 +0000 UTC"}, + {in: "Fri, 03 Jul 2015 08:08:08 PST", out: "2015-07-03 16:08:08 +0000 UTC", loc: "America/Los_Angeles"}, + {in: "Fri, 03 Jul 2015 08:08:08 PST", out: "2015-07-03 08:08:08 +0000 UTC"}, + {in: "Fri, 3 Jul 2015 08:08:08 MST", out: "2015-07-03 08:08:08 +0000 UTC"}, + {in: "Fri, 03 Jul 2015 8:08:08 MST", out: "2015-07-03 08:08:08 +0000 UTC"}, + {in: "Fri, 03 Jul 2015 8:8:8 MST", out: "2015-07-03 08:08:08 +0000 UTC"}, + // ? + {in: "Thu, 03 Jul 2017 08:08:04 +0100", out: "2017-07-03 07:08:04 +0000 UTC"}, + {in: "Thu, 03 Jul 2017 08:08:04 -0100", out: "2017-07-03 09:08:04 +0000 UTC"}, + {in: "Thu, 3 Jul 2017 08:08:04 +0100", out: "2017-07-03 07:08:04 +0000 UTC"}, + {in: "Thu, 03 Jul 2017 8:08:04 +0100", out: "2017-07-03 07:08:04 +0000 UTC"}, + {in: "Thu, 03 Jul 2017 8:8:4 +0100", out: "2017-07-03 07:08:04 +0000 UTC"}, + // + {in: "Tue, 11 Jul 2017 04:08:03 +0200 (CEST)", out: "2017-07-11 02:08:03 +0000 UTC"}, + {in: "Tue, 5 Jul 2017 04:08:03 -0700 (CEST)", out: "2017-07-05 11:08:03 +0000 UTC"}, + {in: "Tue, 11 Jul 2017 04:08:03 +0200 (CEST)", out: "2017-07-11 02:08:03 +0000 UTC", loc: "Europe/Berlin"}, + // day, dd-Mon-yy hh:mm:zz TZ + {in: "Fri, 03-Jul-15 08:08:08 MST", out: "2015-07-03 08:08:08 +0000 UTC"}, + {in: "Fri, 03-Jul-15 08:08:08 PST", out: "2015-07-03 16:08:08 +0000 UTC", loc: "America/Los_Angeles"}, + {in: "Fri, 03-Jul 2015 08:08:08 PST", out: "2015-07-03 08:08:08 +0000 UTC"}, + {in: "Fri, 3-Jul-15 08:08:08 MST", out: "2015-07-03 08:08:08 +0000 UTC"}, + {in: "Fri, 03-Jul-15 8:08:08 MST", out: "2015-07-03 08:08:08 +0000 UTC"}, + {in: "Fri, 03-Jul-15 8:8:8 MST", out: "2015-07-03 08:08:08 +0000 UTC"}, + // day, dd-Mon-yy hh:mm:zz TZ (text) https://github.com/araddon/dateparse/issues/116 + {in: "Sun, 3 Jan 2021 00:12:23 +0800 (GMT+08:00)", out: "2021-01-02 16:12:23 +0000 UTC"}, + // RFC850 = "Monday, 02-Jan-06 15:04:05 MST" + {in: "Wednesday, 07-May-09 08:00:43 MST", out: "2009-05-07 08:00:43 +0000 UTC"}, + {in: "Wednesday, 28-Feb-18 09:01:00 MST", out: "2018-02-28 09:01:00 +0000 UTC"}, + {in: "Wednesday, 28-Feb-18 09:01:00 MST", out: "2018-02-28 16:01:00 +0000 UTC", loc: "America/Denver"}, + // with offset then with variations on non-zero filled stuff + {in: "Monday, 02 Jan 2006 15:04:05 +0100", out: "2006-01-02 14:04:05 +0000 UTC"}, + {in: "Wednesday, 28 Feb 2018 09:01:00 -0300", out: "2018-02-28 12:01:00 +0000 UTC"}, + {in: "Wednesday, 2 Feb 2018 09:01:00 -0300", out: "2018-02-02 12:01:00 +0000 UTC"}, + {in: "Wednesday, 2 Feb 2018 9:01:00 -0300", out: "2018-02-02 12:01:00 +0000 UTC"}, + {in: "Wednesday, 2 Feb 2018 09:1:00 -0300", out: "2018-02-02 12:01:00 +0000 UTC"}, + // dd mon yyyy 12 Feb 2006, 19:17:08 + {in: "07 Feb 2004, 09:07", out: "2004-02-07 09:07:00 +0000 UTC"}, + {in: "07 Feb 2004, 09:07:07", out: "2004-02-07 09:07:07 +0000 UTC"}, + {in: "7 Feb 2004, 09:07:07", out: "2004-02-07 09:07:07 +0000 UTC"}, + {in: "07 Feb 2004, 9:7:7", out: "2004-02-07 09:07:07 +0000 UTC"}, + // dd Mon yyyy hh:mm:ss + {in: "07 Feb 2004 09:07:08", out: "2004-02-07 09:07:08 +0000 UTC"}, + {in: "07 Feb 2004 09:07", out: "2004-02-07 09:07:00 +0000 UTC"}, + {in: "7 Feb 2004 9:7:8", out: "2004-02-07 09:07:08 +0000 UTC"}, + {in: "07 Feb 2004 09:07:08.123", out: "2004-02-07 09:07:08.123 +0000 UTC"}, + // yyyy mmm dd + {in: "2013 May 02 11:37:55", out: "2013-05-02 11:37:55 +0000 UTC"}, // https://github.com/araddon/dateparse/issues/141 + // dd-mon-yyyy 12 Feb 2006, 19:17:08 GMT + {in: "07 Feb 2004, 09:07:07 GMT", out: "2004-02-07 09:07:07 +0000 UTC"}, + // dd-mon-yyyy 12 Feb 2006, 19:17:08 +0100 + {in: "07 Feb 2004, 09:07:07 +0100", out: "2004-02-07 08:07:07 +0000 UTC"}, + // dd-mon-yyyy 12-Feb-2006 19:17:08 + {in: "07-Feb-2004 09:07:07 +0100", out: "2004-02-07 08:07:07 +0000 UTC"}, + // dd-mon-yy 12-Feb-2006 19:17:08 + {in: "07-Feb-04 09:07:07 +0100", out: "2004-02-07 08:07:07 +0000 UTC"}, + // yyyy-mon-dd 2013-Feb-03 + {in: "2013-Feb-03", out: "2013-02-03 00:00:00 +0000 UTC"}, + // 03 February 2013 + {in: "03 February 2013", out: "2013-02-03 00:00:00 +0000 UTC"}, + {in: "3 February 2013", out: "2013-02-03 00:00:00 +0000 UTC"}, + // Chinese 2014年04月18日 + {in: "2014年04月08日", out: "2014-04-08 00:00:00 +0000 UTC"}, + {in: "2014年04月08日 19:17:22", out: "2014-04-08 19:17:22 +0000 UTC"}, + // mm/dd/yyyy + {in: "03/31/2014", out: "2014-03-31 00:00:00 +0000 UTC"}, + {in: "3/31/2014", out: "2014-03-31 00:00:00 +0000 UTC"}, + {in: "3/5/2014", out: "2014-03-05 00:00:00 +0000 UTC"}, + // mm/dd/yy + {in: "08/08/71", out: "1971-08-08 00:00:00 +0000 UTC"}, + {in: "8/8/71", out: "1971-08-08 00:00:00 +0000 UTC"}, + // mm/dd/yy hh:mm:ss + {in: "04/02/2014 04:08:09", out: "2014-04-02 04:08:09 +0000 UTC"}, + {in: "4/2/2014 04:08:09", out: "2014-04-02 04:08:09 +0000 UTC"}, + {in: "04/02/2014 4:08:09", out: "2014-04-02 04:08:09 +0000 UTC"}, + {in: "04/02/2014 4:8:9", out: "2014-04-02 04:08:09 +0000 UTC"}, + {in: "04/02/2014 04:08", out: "2014-04-02 04:08:00 +0000 UTC"}, + {in: "04/02/2014 4:8", out: "2014-04-02 04:08:00 +0000 UTC"}, + {in: "04/02/2014 04:08:09.123", out: "2014-04-02 04:08:09.123 +0000 UTC"}, + {in: "04/02/2014 04:08:09.12312", out: "2014-04-02 04:08:09.12312 +0000 UTC"}, + {in: "04/02/2014 04:08:09.123123", out: "2014-04-02 04:08:09.123123 +0000 UTC"}, + // mm:dd:yy hh:mm:ss + {in: "04:02:2014 04:08:09", out: "2014-04-02 04:08:09 +0000 UTC"}, + {in: "4:2:2014 04:08:09", out: "2014-04-02 04:08:09 +0000 UTC"}, + {in: "04:02:2014 4:08:09", out: "2014-04-02 04:08:09 +0000 UTC"}, + {in: "04:02:2014 4:8:9", out: "2014-04-02 04:08:09 +0000 UTC"}, + {in: "04:02:2014 04:08", out: "2014-04-02 04:08:00 +0000 UTC"}, + {in: "04:02:2014 4:8", out: "2014-04-02 04:08:00 +0000 UTC"}, + {in: "04:02:2014 04:08:09.123", out: "2014-04-02 04:08:09.123 +0000 UTC"}, + {in: "04:02:2014 04:08:09.12312", out: "2014-04-02 04:08:09.12312 +0000 UTC"}, + {in: "04:02:2014 04:08:09.123123", out: "2014-04-02 04:08:09.123123 +0000 UTC"}, + // mm/dd/yy hh:mm:ss AM + {in: "04/02/2014 04:08:09 AM", out: "2014-04-02 04:08:09 +0000 UTC"}, + {in: "04/02/2014 04:08:09 PM", out: "2014-04-02 16:08:09 +0000 UTC"}, + {in: "04/02/2014 04:08 AM", out: "2014-04-02 04:08:00 +0000 UTC"}, + {in: "04/02/2014 04:08 PM", out: "2014-04-02 16:08:00 +0000 UTC"}, + {in: "04/02/2014 4:8 AM", out: "2014-04-02 04:08:00 +0000 UTC"}, + {in: "04/02/2014 4:8 PM", out: "2014-04-02 16:08:00 +0000 UTC"}, + {in: "04/02/2014 04:08:09.123 AM", out: "2014-04-02 04:08:09.123 +0000 UTC"}, + {in: "04/02/2014 04:08:09.123 PM", out: "2014-04-02 16:08:09.123 +0000 UTC"}, + // yyyy/mm/dd + {in: "2014/04/02", out: "2014-04-02 00:00:00 +0000 UTC"}, + {in: "2014/03/31", out: "2014-03-31 00:00:00 +0000 UTC"}, + {in: "2014/4/2", out: "2014-04-02 00:00:00 +0000 UTC"}, + // yyyy/mm/dd hh:mm:ss AM + {in: "2014/04/02 04:08", out: "2014-04-02 04:08:00 +0000 UTC"}, + {in: "2014/03/31 04:08", out: "2014-03-31 04:08:00 +0000 UTC"}, + {in: "2014/4/2 04:08", out: "2014-04-02 04:08:00 +0000 UTC"}, + {in: "2014/04/02 4:8", out: "2014-04-02 04:08:00 +0000 UTC"}, + {in: "2014/04/02 04:08:09", out: "2014-04-02 04:08:09 +0000 UTC"}, + {in: "2014/03/31 04:08:09", out: "2014-03-31 04:08:09 +0000 UTC"}, + {in: "2014/4/2 04:08:09", out: "2014-04-02 04:08:09 +0000 UTC"}, + {in: "2014/04/02 04:08:09.123", out: "2014-04-02 04:08:09.123 +0000 UTC"}, + {in: "2014/04/02 04:08:09.123123", out: "2014-04-02 04:08:09.123123 +0000 UTC"}, + {in: "2014/04/02 04:08:09 AM", out: "2014-04-02 04:08:09 +0000 UTC"}, + {in: "2014/03/31 04:08:09 AM", out: "2014-03-31 04:08:09 +0000 UTC"}, + {in: "2014/4/2 04:08:09 AM", out: "2014-04-02 04:08:09 +0000 UTC"}, + {in: "2014/04/02 04:08:09.123 AM", out: "2014-04-02 04:08:09.123 +0000 UTC"}, + {in: "2014/04/02 04:08:09.123 PM", out: "2014-04-02 16:08:09.123 +0000 UTC"}, + // dd/mon/yyyy:hh:mm:ss tz nginx-log? https://github.com/araddon/dateparse/issues/118 + // 112.195.209.90 - - [20/Feb/2018:12:12:14 +0800] "GET / HTTP/1.1" 200 190 "-" "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Mobile Safari/537.36" "-" + {in: "06/May/2008:08:11:17 -0700", out: "2008-05-06 15:11:17 +0000 UTC"}, + {in: "30/May/2008:08:11:17 -0700", out: "2008-05-30 15:11:17 +0000 UTC"}, + // dd/mon/yyy hh:mm:ss tz + {in: "06/May/2008:08:11:17 -0700", out: "2008-05-06 15:11:17 +0000 UTC"}, + {in: "30/May/2008:08:11:17 -0700", out: "2008-05-30 15:11:17 +0000 UTC"}, + // yyyy-mm-dd + {in: "2014-04-02", out: "2014-04-02 00:00:00 +0000 UTC"}, + {in: "2014-03-31", out: "2014-03-31 00:00:00 +0000 UTC"}, + {in: "2014-4-2", out: "2014-04-02 00:00:00 +0000 UTC"}, + // yyyy-mm-dd-07:00 + {in: "2020-07-20+08:00", out: "2020-07-19 16:00:00 +0000 UTC"}, + {in: "2020-07-20+0800", out: "2020-07-19 16:00:00 +0000 UTC"}, + // dd-mmm-yy (alpha month) + {in: "28-Feb-02", out: "2002-02-28 00:00:00 +0000 UTC"}, + {in: "15-Jan-18", out: "2018-01-15 00:00:00 +0000 UTC"}, + {in: "15-Jan-2017", out: "2017-01-15 00:00:00 +0000 UTC"}, + // dd-mmm-yy (digit month) + {in: "28-02-02", out: "2002-02-28 00:00:00 +0000 UTC"}, // https://github.com/araddon/dateparse/issues/139 + {in: "15-01-18", out: "2018-01-15 00:00:00 +0000 UTC"}, + {in: "15-01-2017", out: "2017-01-15 00:00:00 +0000 UTC"}, + + // yyyy-mm + {in: "2014-04", out: "2014-04-01 00:00:00 +0000 UTC"}, + // yyyy-mm-dd hh:mm:ss AM + {in: "2014-04-02 04:08", out: "2014-04-02 04:08:00 +0000 UTC"}, + {in: "2014-03-31 04:08", out: "2014-03-31 04:08:00 +0000 UTC"}, + {in: "2014-4-2 04:08", out: "2014-04-02 04:08:00 +0000 UTC"}, + {in: "2014-04-02 4:8", out: "2014-04-02 04:08:00 +0000 UTC"}, + {in: "2014-04-02 04:08:09", out: "2014-04-02 04:08:09 +0000 UTC"}, + {in: "2014-03-31 04:08:09", out: "2014-03-31 04:08:09 +0000 UTC"}, + {in: "2014-4-2 04:08:09", out: "2014-04-02 04:08:09 +0000 UTC"}, + {in: "2014-04-02 04:08:09.123", out: "2014-04-02 04:08:09.123 +0000 UTC"}, + {in: "2014-04-02 04:08:09.123123", out: "2014-04-02 04:08:09.123123 +0000 UTC"}, + {in: "2014-04-02 04:08:09.12312312", out: "2014-04-02 04:08:09.12312312 +0000 UTC"}, + {in: "2014-04-02 04:08:09 AM", out: "2014-04-02 04:08:09 +0000 UTC"}, + {in: "2014-03-31 04:08:09 AM", out: "2014-03-31 04:08:09 +0000 UTC"}, + {in: "2014-04-26 05:24:37 PM", out: "2014-04-26 17:24:37 +0000 UTC"}, + {in: "2014-4-2 04:08:09 AM", out: "2014-04-02 04:08:09 +0000 UTC"}, + {in: "2014-04-02 04:08:09.123 AM", out: "2014-04-02 04:08:09.123 +0000 UTC"}, + {in: "2014-04-02 04:08:09.123 PM", out: "2014-04-02 16:08:09.123 +0000 UTC"}, + // yyyy-mm-dd hh:mm:ss,000 + {in: "2014-05-11 08:20:13,787", out: "2014-05-11 08:20:13.787 +0000 UTC"}, + // yyyy-mm-dd hh:mm:ss +0000 + {in: "2012-08-03 18:31:59 +0000", out: "2012-08-03 18:31:59 +0000 UTC"}, + {in: "2012-08-03 13:31:59 -0600", out: "2012-08-03 19:31:59 +0000 UTC"}, + {in: "2012-08-03 18:31:59.257000000 +0000", out: "2012-08-03 18:31:59.257 +0000 UTC"}, + {in: "2012-08-03 8:1:59.257000000 +0000", out: "2012-08-03 08:01:59.257 +0000 UTC"}, + {in: "2012-8-03 18:31:59.257000000 +0000", out: "2012-08-03 18:31:59.257 +0000 UTC"}, + {in: "2012-8-3 18:31:59.257000000 +0000", out: "2012-08-03 18:31:59.257 +0000 UTC"}, + {in: "2014-04-26 17:24:37.123456 +0000", out: "2014-04-26 17:24:37.123456 +0000 UTC"}, + {in: "2014-04-26 17:24:37.12 +0000", out: "2014-04-26 17:24:37.12 +0000 UTC"}, + {in: "2014-04-26 17:24:37.1 +0000", out: "2014-04-26 17:24:37.1 +0000 UTC"}, + {in: "2014-05-11 08:20:13 +0000", out: "2014-05-11 08:20:13 +0000 UTC"}, + {in: "2014-05-11 08:20:13 +0530", out: "2014-05-11 02:50:13 +0000 UTC"}, + // yyyy-mm-dd hh:mm:ss +0300 +03 ?? issue author said this is from golang? + {in: "2018-06-29 19:09:57.77297118 +0300 +03", out: "2018-06-29 16:09:57.77297118 +0000 UTC"}, + {in: "2018-06-29 19:09:57.77297118 +0300 +0300", out: "2018-06-29 16:09:57.77297118 +0000 UTC"}, + {in: "2018-06-29 19:09:57 +0300 +03", out: "2018-06-29 16:09:57 +0000 UTC"}, + {in: "2018-06-29 19:09:57 +0300 +0300", out: "2018-06-29 16:09:57 +0000 UTC"}, + + // 13:31:51.999 -07:00 MST + // yyyy-mm-dd hh:mm:ss +00:00 + {in: "2012-08-03 18:31:59 +00:00", out: "2012-08-03 18:31:59 +0000 UTC"}, + {in: "2014-05-01 08:02:13 +00:00", out: "2014-05-01 08:02:13 +0000 UTC"}, + {in: "2014-5-01 08:02:13 +00:00", out: "2014-05-01 08:02:13 +0000 UTC"}, + {in: "2014-05-1 08:02:13 +00:00", out: "2014-05-01 08:02:13 +0000 UTC"}, + {in: "2012-08-03 13:31:59 -06:00", out: "2012-08-03 19:31:59 +0000 UTC"}, + {in: "2012-08-03 18:31:59.257000000 +00:00", out: "2012-08-03 18:31:59.257 +0000 UTC"}, + {in: "2012-08-03 8:1:59.257000000 +00:00", out: "2012-08-03 08:01:59.257 +0000 UTC"}, + {in: "2012-8-03 18:31:59.257000000 +00:00", out: "2012-08-03 18:31:59.257 +0000 UTC"}, + {in: "2012-8-3 18:31:59.257000000 +00:00", out: "2012-08-03 18:31:59.257 +0000 UTC"}, + {in: "2014-04-26 17:24:37.123456 +00:00", out: "2014-04-26 17:24:37.123456 +0000 UTC"}, + {in: "2014-04-26 17:24:37.12 +00:00", out: "2014-04-26 17:24:37.12 +0000 UTC"}, + {in: "2014-04-26 17:24:37.1 +00:00", out: "2014-04-26 17:24:37.1 +0000 UTC"}, + // yyyy-mm-dd hh:mm:ss +0000 TZ + // Golang Native Format + {in: "2012-08-03 18:31:59 +0000 UTC", out: "2012-08-03 18:31:59 +0000 UTC"}, + {in: "2012-08-03 13:31:59 -0600 MST", out: "2012-08-03 19:31:59 +0000 UTC", loc: "America/Denver"}, + {in: "2015-02-18 00:12:00 +0000 UTC", out: "2015-02-18 00:12:00 +0000 UTC"}, + {in: "2015-02-18 00:12:00 +0000 GMT", out: "2015-02-18 00:12:00 +0000 UTC"}, + {in: "2015-02-08 03:02:00 +0200 CEST", out: "2015-02-08 01:02:00 +0000 UTC", loc: "Europe/Berlin"}, + {in: "2015-02-08 03:02:00 +0300 MSK", out: "2015-02-08 00:02:00 +0000 UTC"}, + {in: "2015-2-08 03:02:00 +0300 MSK", out: "2015-02-08 00:02:00 +0000 UTC"}, + {in: "2015-02-8 03:02:00 +0300 MSK", out: "2015-02-08 00:02:00 +0000 UTC"}, + {in: "2015-2-8 03:02:00 +0300 MSK", out: "2015-02-08 00:02:00 +0000 UTC"}, + {in: "2012-08-03 18:31:59.257000000 +0000 UTC", out: "2012-08-03 18:31:59.257 +0000 UTC"}, + {in: "2012-08-03 8:1:59.257000000 +0000 UTC", out: "2012-08-03 08:01:59.257 +0000 UTC"}, + {in: "2012-8-03 18:31:59.257000000 +0000 UTC", out: "2012-08-03 18:31:59.257 +0000 UTC"}, + {in: "2012-8-3 18:31:59.257000000 +0000 UTC", out: "2012-08-03 18:31:59.257 +0000 UTC"}, + {in: "2014-04-26 17:24:37.123456 +0000 UTC", out: "2014-04-26 17:24:37.123456 +0000 UTC"}, + {in: "2014-04-26 17:24:37.12 +0000 UTC", out: "2014-04-26 17:24:37.12 +0000 UTC"}, + {in: "2014-04-26 17:24:37.1 +0000 UTC", out: "2014-04-26 17:24:37.1 +0000 UTC"}, + {in: "2015-02-08 03:02:00 +0200 CEST m=+0.000000001", out: "2015-02-08 01:02:00 +0000 UTC", loc: "Europe/Berlin"}, + {in: "2015-02-08 03:02:00 +0300 MSK m=+0.000000001", out: "2015-02-08 00:02:00 +0000 UTC"}, + {in: "2015-02-08 03:02:00.001 +0300 MSK m=+0.000000001", out: "2015-02-08 00:02:00.001 +0000 UTC"}, + // yyyy-mm-dd hh:mm:ss TZ + {in: "2012-08-03 18:31:59 UTC", out: "2012-08-03 18:31:59 +0000 UTC"}, + {in: "2014-12-16 06:20:00 GMT", out: "2014-12-16 06:20:00 +0000 UTC"}, + {in: "2012-08-03 13:31:59 MST", out: "2012-08-03 20:31:59 +0000 UTC", loc: "America/Denver"}, + {in: "2012-08-03 18:31:59.257000000 UTC", out: "2012-08-03 18:31:59.257 +0000 UTC"}, + {in: "2012-08-03 8:1:59.257000000 UTC", out: "2012-08-03 08:01:59.257 +0000 UTC"}, + {in: "2012-8-03 18:31:59.257000000 UTC", out: "2012-08-03 18:31:59.257 +0000 UTC"}, + {in: "2012-8-3 18:31:59.257000000 UTC", out: "2012-08-03 18:31:59.257 +0000 UTC"}, + {in: "2014-04-26 17:24:37.123456 UTC", out: "2014-04-26 17:24:37.123456 +0000 UTC"}, + {in: "2014-04-26 17:24:37.12 UTC", out: "2014-04-26 17:24:37.12 +0000 UTC"}, + {in: "2014-04-26 17:24:37.1 UTC", out: "2014-04-26 17:24:37.1 +0000 UTC"}, + // This one is pretty special, it is TIMEZONE based but starts with P to emulate collions with PM + {in: "2014-04-26 05:24:37 PST", out: "2014-04-26 05:24:37 +0000 UTC"}, + {in: "2014-04-26 05:24:37 PST", out: "2014-04-26 13:24:37 +0000 UTC", loc: "America/Los_Angeles"}, + // yyyy-mm-dd hh:mm:ss+00:00 + {in: "2012-08-03 18:31:59+00:00", out: "2012-08-03 18:31:59 +0000 UTC"}, + {in: "2017-07-19 03:21:51+00:00", out: "2017-07-19 03:21:51 +0000 UTC"}, + // yyyy:mm:dd hh:mm:ss+00:00 + {in: "2012:08:03 18:31:59+00:00", out: "2012-08-03 18:31:59 +0000 UTC"}, + // dd:mm:yyyy hh:mm:ss+00:00 + {in: "08:03:2012 18:31:59+00:00", out: "2012-08-03 18:31:59 +0000 UTC"}, + // yyyy-mm-dd hh:mm:ss.000+00:00 PST + {in: "2012-08-03 18:31:59.000+00:00 PST", out: "2012-08-03 18:31:59 +0000 UTC", loc: "America/Los_Angeles"}, + // yyyy-mm-dd hh:mm:ss +00:00 TZ + {in: "2012-08-03 18:31:59 +00:00 UTC", out: "2012-08-03 18:31:59 +0000 UTC"}, + {in: "2012-08-03 13:31:51 -07:00 MST", out: "2012-08-03 20:31:51 +0000 UTC", loc: "America/Denver"}, + {in: "2012-08-03 18:31:59.257000000 +00:00 UTC", out: "2012-08-03 18:31:59.257 +0000 UTC"}, + {in: "2012-08-03 13:31:51.123 -08:00 PST", out: "2012-08-03 21:31:51.123 +0000 UTC", loc: "America/Los_Angeles"}, + {in: "2012-08-03 13:31:51.123 +02:00 CEST", out: "2012-08-03 11:31:51.123 +0000 UTC", loc: "Europe/Berlin"}, + {in: "2012-08-03 8:1:59.257000000 +00:00 UTC", out: "2012-08-03 08:01:59.257 +0000 UTC"}, + {in: "2012-8-03 18:31:59.257000000 +00:00 UTC", out: "2012-08-03 18:31:59.257 +0000 UTC"}, + {in: "2012-8-3 18:31:59.257000000 +00:00 UTC", out: "2012-08-03 18:31:59.257 +0000 UTC"}, + {in: "2014-04-26 17:24:37.123456 +00:00 UTC", out: "2014-04-26 17:24:37.123456 +0000 UTC"}, + {in: "2014-04-26 17:24:37.12 +00:00 UTC", out: "2014-04-26 17:24:37.12 +0000 UTC"}, + {in: "2014-04-26 17:24:37.1 +00:00 UTC", out: "2014-04-26 17:24:37.1 +0000 UTC"}, + // yyyy-mm-ddThh:mm:ss + {in: "2009-08-12T22:15:09", out: "2009-08-12 22:15:09 +0000 UTC"}, + {in: "2009-08-08T02:08:08", out: "2009-08-08 02:08:08 +0000 UTC"}, + {in: "2009-08-08T2:8:8", out: "2009-08-08 02:08:08 +0000 UTC"}, + {in: "2009-08-12T22:15:09.123", out: "2009-08-12 22:15:09.123 +0000 UTC"}, + {in: "2009-08-12T22:15:09.123456", out: "2009-08-12 22:15:09.123456 +0000 UTC"}, + {in: "2009-08-12T22:15:09.12", out: "2009-08-12 22:15:09.12 +0000 UTC"}, + {in: "2009-08-12T22:15:09.1", out: "2009-08-12 22:15:09.1 +0000 UTC"}, + {in: "2014-04-26 17:24:37.3186369", out: "2014-04-26 17:24:37.3186369 +0000 UTC"}, + // yyyy-mm-ddThh:mm:ss-07:00 + {in: "2009-08-12T22:15:09-07:00", out: "2009-08-13 05:15:09 +0000 UTC"}, + {in: "2009-08-12T22:15:09-03:00", out: "2009-08-13 01:15:09 +0000 UTC"}, + {in: "2009-08-12T22:15:9-07:00", out: "2009-08-13 05:15:09 +0000 UTC"}, + {in: "2009-08-12T22:15:09.123-07:00", out: "2009-08-13 05:15:09.123 +0000 UTC"}, + {in: "2016-06-21T19:55:00+01:00", out: "2016-06-21 18:55:00 +0000 UTC"}, + {in: "2016-06-21T19:55:00.799+01:00", out: "2016-06-21 18:55:00.799 +0000 UTC"}, + // yyyy-mm-ddThh:mm:ss-07 TZ truncated to 2 digits instead of 4 + {in: "2019-05-29T08:41-04", out: "2019-05-29 12:41:00 +0000 UTC"}, + // yyyy-mm-ddThh:mm:ss-0700 + {in: "2009-08-12T22:15:09-0700", out: "2009-08-13 05:15:09 +0000 UTC"}, + {in: "2009-08-12T22:15:09-0300", out: "2009-08-13 01:15:09 +0000 UTC"}, + {in: "2009-08-12T22:15:9-0700", out: "2009-08-13 05:15:09 +0000 UTC"}, + {in: "2009-08-12T22:15:09.123-0700", out: "2009-08-13 05:15:09.123 +0000 UTC"}, + {in: "2016-06-21T19:55:00+0100", out: "2016-06-21 18:55:00 +0000 UTC"}, + {in: "2016-06-21T19:55:00.799+0100", out: "2016-06-21 18:55:00.799 +0000 UTC"}, + {in: "2016-06-21T19:55:00+0100", out: "2016-06-21 18:55:00 +0000 UTC"}, + {in: "2016-06-21T19:55:00-0700", out: "2016-06-22 02:55:00 +0000 UTC"}, + {in: "2016-06-21T19:55:00.799+0100", out: "2016-06-21 18:55:00.799 +0000 UTC"}, + {in: "2016-06-21T19:55+0100", out: "2016-06-21 18:55:00 +0000 UTC"}, + {in: "2016-06-21T19:55+0130", out: "2016-06-21 18:25:00 +0000 UTC"}, + // yyyy-mm-ddThh:mm:ss:000+0000 - weird format with additional colon in front of milliseconds + {in: "2012-08-17T18:31:59:257+0100", out: "2012-08-17 17:31:59.257 +0000 UTC"}, // https://github.com/araddon/dateparse/issues/117 + {in: "2012-08-17T18:31:59:257", out: "2012-08-17 18:31:59.257 +0000 UTC"}, // https://github.com/araddon/dateparse/issues/137 + + // yyyy-mm-ddThh:mm:ssZ + {in: "2009-08-12T22:15Z", out: "2009-08-12 22:15:00 +0000 UTC"}, + {in: "2009-08-12T22:15:09Z", out: "2009-08-12 22:15:09 +0000 UTC"}, + {in: "2009-08-12T22:15:09.99Z", out: "2009-08-12 22:15:09.99 +0000 UTC"}, + {in: "2009-08-12T22:15:09.9999Z", out: "2009-08-12 22:15:09.9999 +0000 UTC"}, + {in: "2009-08-12T22:15:09.99999999Z", out: "2009-08-12 22:15:09.99999999 +0000 UTC"}, + {in: "2009-08-12T22:15:9.99999999Z", out: "2009-08-12 22:15:09.99999999 +0000 UTC"}, + // yyyy.mm + {in: "2014.05", out: "2014-05-01 00:00:00 +0000 UTC"}, + {in: "2018.09.30", out: "2018-09-30 00:00:00 +0000 UTC"}, + + // mm.dd.yyyy + {in: "3.31.2014", out: "2014-03-31 00:00:00 +0000 UTC"}, + {in: "3.3.2014", out: "2014-03-03 00:00:00 +0000 UTC"}, + {in: "03.31.2014", out: "2014-03-31 00:00:00 +0000 UTC"}, + // mm.dd.yy + {in: "08.21.71", out: "1971-08-21 00:00:00 +0000 UTC"}, + // dd.mm.yyyy + {in: "23.07.1938", out: "1938-07-23 00:00:00 +0000 UTC"}, + {in: "23/07/1938", out: "1938-07-23 00:00:00 +0000 UTC"}, + // yyyymmdd and similar + {in: "2014", out: "2014-01-01 00:00:00 +0000 UTC"}, + {in: "20140601", out: "2014-06-01 00:00:00 +0000 UTC"}, + {in: "20140722105203", out: "2014-07-22 10:52:03 +0000 UTC"}, + {in: "20140722105203.364", out: "2014-07-22 10:52:03.364 +0000 UTC"}, + // yymmdd hh:mm:yy mysql log https://github.com/araddon/dateparse/issues/119 + // 080313 05:21:55 mysqld started + // 080313 5:21:55 InnoDB: Started; log sequence number 0 43655 + {in: "171113 14:14:20", out: "2017-11-13 14:14:20 +0000 UTC"}, + + // all digits: unix secs, ms etc + {in: "1332151919.329", out: "2012-03-19 10:11:59.329 +0000 UTC"}, + {in: "1332151919.32", out: "2012-03-19 10:11:59.32 +0000 UTC"}, + {in: "1332151919.", out: "2012-03-19 10:11:59 +0000 UTC"}, + {in: "1332151919.001", out: "2012-03-19 10:11:59.001 +0000 UTC"}, + {in: "1332151919", out: "2012-03-19 10:11:59 +0000 UTC"}, + {in: "1332151919", out: "2012-03-19 10:11:59 +0000 UTC", loc: "America/Denver"}, + {in: "1384216367111", out: "2013-11-12 00:32:47.111 +0000 UTC"}, + {in: "1384216367111222", out: "2013-11-12 00:32:47.111222 +0000 UTC"}, + {in: "1384216367111222333", out: "2013-11-12 00:32:47.111222333 +0000 UTC"}, + + {in: "Wed, 8 Feb 2023 19:00:46 +1100 (AEDT)", out: "2023-02-08 08:00:46 +0000 UTC"}, + {in: "FRI, 16 AUG 2013 9:39:51 +1000", out: "2013-08-15 23:39:51 +0000 UTC"}, + {in: "Mon, 1 Dec 2008 14:48:22 GMT-07:00", out: "2008-12-01 21:48:22 +0000 UTC"}, + + // dd[th,nd,st,rd] Month yyyy + {in: "1st September 2012", out: "2012-09-01 00:00:00 +0000 UTC"}, + {in: "2nd September 2012", out: "2012-09-02 00:00:00 +0000 UTC"}, + {in: "3rd September 2012", out: "2012-09-03 00:00:00 +0000 UTC"}, + {in: "4th September 2012", out: "2012-09-04 00:00:00 +0000 UTC"}, + {in: "2nd January 2018", out: "2018-01-02 00:00:00 +0000 UTC"}, + {in: "3nd Feb 2018 13:58:24", out: "2018-02-03 13:58:24 +0000 UTC"}, + } // Lets ensure we are operating on UTC time.Local = time.UTC zeroTime := time.Time{}.Unix() - ts, err := ParseAny("INVALID") - assert.Equal(t, zeroTime, ts.Unix()) - assert.NotEqual(t, nil, err) + t.Run("Invalid", func(t *testing.T) { + ts, err := ParseAny("INVALID") + assert.Equal(t, zeroTime, ts.Unix()) + assert.NotEqual(t, nil, err) - assert.Equal(t, true, testDidPanic("NOT GONNA HAPPEN")) - // https://github.com/golang/go/issues/5294 - _, err = ParseAny(time.RFC3339) - assert.NotEqual(t, nil, err) + assert.Equal(t, true, testDidPanic("NOT GONNA HAPPEN")) + // https://github.com/golang/go/issues/5294 + _, err = ParseAny(time.RFC3339) + assert.NotEqual(t, nil, err) + }) for _, th := range testInputs { - if len(th.loc) > 0 { - loc, err := time.LoadLocation(th.loc) - if err != nil { - t.Fatalf("Expected to load location %q but got %v", th.loc, err) - } - ts, err = ParseIn(th.in, loc) - if err != nil { - t.Fatalf("expected to parse %q but got %v", th.in, err) - } - got := fmt.Sprintf("%v", ts.In(time.UTC)) - assert.Equal(t, th.out, got, "Expected %q but got %q from %q", th.out, got, th.in) - if th.out != got { - panic("whoops") + t.Run(th.in, func(t *testing.T) { + var ts time.Time + defer func() { + if r := recover(); r != nil { + t.Fatalf("error: %s", r) + } + }() + if len(th.loc) > 0 { + loc, err := time.LoadLocation(th.loc) + if err != nil { + t.Fatalf("Expected to load location %q but got %v", th.loc, err) + } + ts, err = ParseIn(th.in, loc) + if err != nil { + t.Fatalf("expected to parse %q but got %v", th.in, err) + } + got := fmt.Sprintf("%v", ts.In(time.UTC)) + assert.Equal(t, th.out, got, "Expected %q but got %q from %q", th.out, got, th.in) + if th.out != got { + t.Fatalf("whoops, got %s, expected %s", got, th.out) + } + } else { + ts = MustParse(th.in, RetryAmbiguousDateWithSwap(true)) + got := fmt.Sprintf("%v", ts.In(time.UTC)) + assert.Equal(t, th.out, got, "Expected %q but got %q from %q", th.out, got, th.in) + if th.out != got { + t.Fatalf("whoops, got %s, expected %s", got, th.out) + } } - } else { - ts = MustParse(th.in, RetryAmbiguousDateWithSwap(true)) - got := fmt.Sprintf("%v", ts.In(time.UTC)) - assert.Equal(t, th.out, got, "Expected %q but got %q from %q", th.out, got, th.in) - if th.out != got { - panic("whoops") - } - } + }) } // some errors - assert.Equal(t, true, testDidPanic(`{"ts":"now"}`)) + t.Run("", func(t *testing.T) { + assert.Equal(t, true, testDidPanic(`{"ts":"now"}`)) + }) - _, err = ParseAny("138421636711122233311111") // too many digits - assert.NotEqual(t, nil, err) + t.Run("too many digits", func(t *testing.T) { + _, err := ParseAny("138421636711122233311111") // too many digits + assert.NotEqual(t, nil, err) + }) - _, err = ParseAny("-1314") - assert.NotEqual(t, nil, err) + t.Run("negative number", func(t *testing.T) { + _, err := ParseAny("-1314") + assert.NotEqual(t, nil, err) + }) - _, err = ParseAny("2014-13-13 08:20:13,787") // month 13 doesn't exist so error - assert.NotEqual(t, nil, err) + t.Run("month doesn't exist", func(t *testing.T) { + _, err := ParseAny("2014-13-13 08:20:13,787") // month 13 doesn't exist so error + assert.NotEqual(t, nil, err) + }) } func testDidPanic(datestr string) (paniced bool) { @@ -512,7 +538,10 @@ func TestPStruct(t *testing.T) { denverLoc, err := time.LoadLocation("America/Denver") assert.Equal(t, nil, err) - p := newParser("08.21.71", denverLoc) + p, err := newParser("08.21.71", denverLoc) + if err != nil { + t.Fatalf("Parser build error: %s", err) + } p.setMonth() assert.Equal(t, 0, p.moi)