From 313f117957491554554aef8ae0df7aea692e585c Mon Sep 17 00:00:00 2001 From: Aaron Raddon Date: Thu, 22 Nov 2018 13:54:48 -0800 Subject: [PATCH] new date formats closes #73 and closes #74 --- README.md | 4 + example/main.go | 8 ++ parseany.go | 306 +++++++++++++++++++++++++++++++++++++++-------- parseany_test.go | 45 +++++-- 4 files changed, 307 insertions(+), 56 deletions(-) diff --git a/README.md b/README.md index 80345d9..ebaf18e 100644 --- a/README.md +++ b/README.md @@ -197,13 +197,17 @@ func main() { | Thu, 4 Jan 2018 17:53:36 +0000 | 2018-01-04 17:53:36 +0000 UTC | | Mon Aug 10 15:44:11 UTC+0100 2015 | 2015-08-10 15:44:11 +0000 UTC | | Fri Jul 03 2015 18:04:07 GMT+0100 (GMT Daylight Time) | 2015-07-03 18:04:07 +0100 GMT | +| September 17, 2012 10:09am | 2012-09-17 10:09:00 +0000 UTC | | September 17, 2012 at 10:09am PST-08 | 2012-09-17 10:09:00 -0800 PST | +| September 17, 2012, 10:10:09 | 2012-09-17 10:10:09 +0000 UTC | | October 7, 1970 | 1970-10-07 00:00:00 +0000 UTC | +| October 7th, 1970 | 1970-10-07 00:00:00 +0000 UTC | | 12 Feb 2006, 19:17 | 2006-02-12 19:17:00 +0000 UTC | | 12 Feb 2006 19:17 | 2006-02-12 19:17:00 +0000 UTC | | 7 oct 70 | 1970-10-07 00:00:00 +0000 UTC | | 7 oct 1970 | 1970-10-07 00:00:00 +0000 UTC | | 03 February 2013 | 2013-02-03 00:00:00 +0000 UTC | +| 1 July 2013 | 2013-07-01 00:00:00 +0000 UTC | | 2013-Feb-03 | 2013-02-03 00:00:00 +0000 UTC | | 3/31/2014 | 2014-03-31 00:00:00 +0000 UTC | | 03/31/2014 | 2014-03-31 00:00:00 +0000 UTC | diff --git a/example/main.go b/example/main.go index 6325af6..f110736 100644 --- a/example/main.go +++ b/example/main.go @@ -25,8 +25,11 @@ var examples = []string{ "Thu, 4 Jan 2018 17:53:36 +0000", "Mon Aug 10 15:44:11 UTC+0100 2015", "Fri Jul 03 2015 18:04:07 GMT+0100 (GMT Daylight Time)", + "September 17, 2012 10:09am", "September 17, 2012 at 10:09am PST-08", + "September 17, 2012, 10:10:09", "October 7, 1970", + "October 7th, 1970", "12 Feb 2006, 19:17", "12 Feb 2006 19:17", "7 oct 70", @@ -155,13 +158,17 @@ func main() { | Thu, 4 Jan 2018 17:53:36 +0000 | 2018-01-04 17:53:36 +0000 UTC | | Mon Aug 10 15:44:11 UTC+0100 2015 | 2015-08-10 15:44:11 +0000 UTC | | Fri Jul 03 2015 18:04:07 GMT+0100 (GMT Daylight Time) | 2015-07-03 18:04:07 +0100 GMT | +| September 17, 2012 10:09am | 2012-09-17 10:09:00 +0000 UTC | | September 17, 2012 at 10:09am PST-08 | 2012-09-17 10:09:00 -0800 PST | +| September 17, 2012, 10:10:09 | 2012-09-17 10:10:09 +0000 UTC | | October 7, 1970 | 1970-10-07 00:00:00 +0000 UTC | +| October 7th, 1970 | 1970-10-07 00:00:00 +0000 UTC | | 12 Feb 2006, 19:17 | 2006-02-12 19:17:00 +0000 UTC | | 12 Feb 2006 19:17 | 2006-02-12 19:17:00 +0000 UTC | | 7 oct 70 | 1970-10-07 00:00:00 +0000 UTC | | 7 oct 1970 | 1970-10-07 00:00:00 +0000 UTC | | 03 February 2013 | 2013-02-03 00:00:00 +0000 UTC | +| 1 July 2013 | 2013-07-01 00:00:00 +0000 UTC | | 2013-Feb-03 | 2013-02-03 00:00:00 +0000 UTC | | 3/31/2014 | 2014-03-31 00:00:00 +0000 UTC | | 03/31/2014 | 2014-03-31 00:00:00 +0000 UTC | @@ -225,4 +232,5 @@ func main() { | 1384216367111222 | 2013-11-12 00:32:47.111222 +0000 UTC | | 1384216367111222333 | 2013-11-12 00:32:47.111222333 +0000 UTC | +-------------------------------------------------------+-----------------------------------------+ + */ diff --git a/parseany.go b/parseany.go index 93652b4..d6d205e 100644 --- a/parseany.go +++ b/parseany.go @@ -36,31 +36,35 @@ type dateState uint8 type timeState uint8 const ( - dateStart dateState = iota + dateStart dateState = iota // 0 dateDigit dateYearDash dateYearDashAlphaDash dateYearDashDash - dateYearDashDashWs + dateYearDashDashWs // 5 dateYearDashDashT dateDigitDash dateDigitDashAlpha dateDigitDashAlphaDash - dateDigitDot + dateDigitDot // 10 dateDigitDotDot dateDigitSlash dateDigitChineseYear dateDigitChineseYearWs - dateDigitWs + dateDigitWs // 15 dateDigitWsMoYear dateDigitWsMolong dateAlpha dateAlphaWs - dateAlphaWsDigit - dateAlphaWsDigitComma - dateAlphaWsDigitCommaWs - dateAlphaWsDigitCommaWsYear + dateAlphaWsDigit // 20 + dateAlphaWsDigitMore + dateAlphaWsDigitMoreWs + dateAlphaWsDigitMoreWsYear dateAlphaWsMonth + dateAlphaWsMonthMore + dateAlphaWsMonthSuffix + dateAlphaWsMore + dateAlphaWsAtTime dateAlphaWsAlpha dateAlphaWsAlphaYearmaybe dateAlphaPeriodWsDigit @@ -470,7 +474,6 @@ iterRunes: // we can parse may with either. BUT, that means the // format may not be correct? // mo := strings.ToLower(datestr[p.daylen+1 : i]) - // gou.Warnf("mo = %q", mo) p.moi = p.daylen + 1 p.molen = i - p.moi p.set(p.moi, "Jan") @@ -532,8 +535,10 @@ iterRunes: // oct 1, 1970 // dateAlphaWsMonth // April 8, 2009 - // dateAlphaWsMonthTime - // January 02, 2006 at 3:04pm MST-07 + // dateAlphaWsMore + // dateAlphaWsAtTime + // January 02, 2006 at 3:04pm MST-07 + // // dateAlphaPeriodWsDigit // oct. 1, 1970 // dateWeekdayComma @@ -549,32 +554,35 @@ iterRunes: // Mon, 02-Jan-06 15:04:05 MST switch { case r == ' ': + // X + // April 8, 2009 if i > 3 { - prefix := strings.ToLower(datestr[0:i]) - for _, month := range months { - if prefix == month { - // len(" 31, 2018") = 9 - if len(datestr[i:]) < 10 { - // April 8, 2009 - p.dayi = i + 1 - p.stateDate = dateAlphaWsMonth - break - } + // Check to see if the alpha is name of month? or Day? + month := strings.ToLower(datestr[0:i]) + if isMonthFull(month) { + p.fullMonth = month + // len(" 31, 2018") = 9 + if len(datestr[i:]) < 10 { + // April 8, 2009 + p.stateDate = dateAlphaWsMonth + } else { + p.stateDate = dateAlphaWsMore } + p.dayi = i + 1 + break } - if p.stateDate != dateAlphaWsMonth { - // September 17, 2012 at 5:00pm UTC-05 - // This one doesn't follow standard parse methodologies. the "January" - // is difficult to use the format string replace method because of its variable-length (march, june) - // so we just use this format here. If we see more similar to this we will do something else. - p.format = []byte("January 02, 2006 at 3:04pm MST-07") - return p, nil - } + } else { + // This is possibly ambiguous? May will parse as either though. + // So, it could return in-correct format. + // May 05, 2005, 05:05:05 + // May 05 2005, 05:05:05 + // Jul 05, 2005, 05:05:05 p.stateDate = dateAlphaWs } case r == ',': + // Mon, 02 Jan 2006 // p.moi = 0 // p.molen = i if i == 3 { @@ -613,6 +621,7 @@ iterRunes: // Mon Aug 10 15:44:11 UTC+0100 2015 // dateAlphaWsDigit // May 8, 2009 5:57:51 PM + // May 8 2009 5:57:51 PM // oct 1, 1970 // oct 7, '70 switch { @@ -628,34 +637,49 @@ iterRunes: case dateAlphaWsDigit: // May 8, 2009 5:57:51 PM + // May 8 2009 5:57:51 PM // oct 1, 1970 // oct 7, '70 // oct. 7, 1970 - //gou.Debugf("%d %s dateAlphaWsDigit %s %s", i, string(r), p.ds(), p.ts()) if r == ',' { p.daylen = i - p.dayi p.setDay() - p.stateDate = dateAlphaWsDigitComma + p.stateDate = dateAlphaWsDigitMore + } else if r == ' ' { + p.daylen = i - p.dayi + p.setDay() + p.yeari = i + 1 + p.stateDate = dateAlphaWsDigitMoreWs + } else if unicode.IsLetter(r) { + p.stateDate = dateAlphaWsMonthSuffix + i-- } - case dateAlphaWsDigitComma: + case dateAlphaWsDigitMore: // x // May 8, 2009 5:57:51 PM + // May 05, 2005, 05:05:05 + // May 05 2005, 05:05:05 // oct 1, 1970 // oct 7, '70 if r == ' ' { - p.stateDate = dateAlphaWsDigitCommaWs p.yeari = i + 1 + p.stateDate = dateAlphaWsDigitMoreWs } - case dateAlphaWsDigitCommaWs: + case dateAlphaWsDigitMoreWs: // x // May 8, 2009 5:57:51 PM + // May 05, 2005, 05:05:05 // oct 1, 1970 // oct 7, '70 switch r { case '\'': p.yeari = i + 1 - case ' ': - p.stateDate = dateAlphaWsDigitCommaWsYear + case ' ', ',': + // x + // May 8, 2009 5:57:51 PM + // x + // May 8, 2009, 5:57:51 PM + p.stateDate = dateAlphaWsDigitMoreWsYear p.yearlen = i - p.yeari p.setYear() p.stateTime = timeStart @@ -670,7 +694,6 @@ iterRunes: // Fri Jul 03 2015 18:04:07 GMT+0100 (GMT Daylight Time) if r == ' ' { if p.dayi > 0 { - p.daylen = i - p.dayi p.setDay() p.yeari = i + 1 @@ -701,13 +724,114 @@ iterRunes: case dateAlphaWsMonth: // April 8, 2009 - if r == ',' { - if i-p.dayi == 2 { - p.format = []byte("January 02, 2006") - return p, nil + // April 8 2009 + switch r { + case ' ', ',': + // x + // June 8, 2009 + // x + // June 8 2009 + if p.daylen == 0 { + p.daylen = i - p.dayi + p.setDay() } - p.format = []byte("January 2, 2006") - return p, nil + case 's', 'S', 'r', 'R', 't', 'T', 'n', 'N': + // st, rd, nd, st + i-- + p.stateDate = dateAlphaWsMonthSuffix + default: + if p.daylen > 0 && p.yeari == 0 { + p.yeari = i + } + } + case dateAlphaWsMonthMore: + // X + // January 02, 2006, 15:04:05 + // January 02 2006, 15:04:05 + // January 02, 2006 15:04:05 + // January 02 2006 15:04:05 + switch r { + case ',': + p.yearlen = i - p.yeari + p.setYear() + p.stateTime = timeStart + i++ + break iterRunes + case ' ': + p.yearlen = i - p.yeari + p.setYear() + p.stateTime = timeStart + break iterRunes + } + case dateAlphaWsMonthSuffix: + // x + // April 8th, 2009 + // April 8th 2009 + switch r { + case 't', 'T': + if p.nextIs(i, 'h') || p.nextIs(i, 'h') { + if len(datestr) > i+2 { + return parseTime(fmt.Sprintf("%s%s", p.datestr[0:i], p.datestr[i+2:]), loc) + } + } + case 'n', 'N': + if p.nextIs(i, 'd') || p.nextIs(i, 'D') { + if len(datestr) > i+2 { + return parseTime(fmt.Sprintf("%s%s", p.datestr[0:i], p.datestr[i+2:]), loc) + } + } + case 's', 'S': + if p.nextIs(i, 't') || p.nextIs(i, 'T') { + if len(datestr) > i+2 { + return parseTime(fmt.Sprintf("%s%s", p.datestr[0:i], p.datestr[i+2:]), loc) + } + } + // case ',': + // // x + // // April 8th, 2009 + // case ' ': + // // x + // // April 8th 2009 + // // p.yeari = i + 1 + // p.yeari = i + 1 + // p.stateDate = dateAlphaWsMonthMore + } + case dateAlphaWsMore: + // January 02, 2006, 15:04:05 + // January 02 2006, 15:04:05 + // January 2nd, 2006, 15:04:05 + // January 2nd 2006, 15:04:05 + // September 17, 2012 at 5:00pm UTC-05 + switch { + case r == ',': + // x + // January 02, 2006, 15:04:05 + if p.nextIs(i, ' ') { + p.daylen = i - p.dayi + p.setDay() + p.yeari = i + 2 + p.stateDate = dateAlphaWsMonthMore + i++ + } + + case r == ' ': + // x + // January 02 2006, 15:04:05 + p.daylen = i - p.dayi + p.setDay() + p.yeari = i + 1 + p.stateDate = dateAlphaWsMonthMore + case unicode.IsDigit(r): + // XX + // January 02, 2006, 15:04:05 + continue + case unicode.IsLetter(r): + // X + // January 2nd, 2006, 15:04:05 + p.daylen = i - p.dayi + p.setDay() + p.stateDate = dateAlphaWsMonthSuffix + i-- } case dateAlphaPeriodWsDigit: @@ -736,7 +860,6 @@ iterRunes: p.daylen = i - p.dayi p.setDay() } else if p.yeari == 0 { - p.yeari = i + 1 p.molen = i - p.moi p.set(p.moi, "Jan") @@ -805,6 +928,7 @@ iterRunes: // timeWs // 05:24:37 PM // 06:20:00 UTC + // 06:20:00 UTC-05 // 00:12:00 +0000 UTC // 22:18:00 +0000 UTC m=+0.000000001 // 15:04:05 -0700 @@ -864,6 +988,38 @@ iterRunes: } else { p.seclen = i - p.seci } + case 'a', 'A': + if p.nextIs(i, 't') || p.nextIs(i, 'T') { + // x + // September 17, 2012 at 5:00pm UTC-05 + i++ // skip t + if p.nextIs(i, ' ') { + // x + // September 17, 2012 at 5:00pm UTC-05 + i++ // skip ' + p.houri = 0 // reset hour + } + } else { + switch { + case r == 'a' && p.nextIs(i, 'm'): + p.coalesceTime(i) + p.set(i, "am") + case r == 'A' && p.nextIs(i, 'M'): + p.coalesceTime(i) + p.set(i, "PM") + } + } + + case 'p', 'P': + // Could be AM/PM + switch { + case r == 'p' && p.nextIs(i, 'm'): + p.coalesceTime(i) + p.set(i, "pm") + case r == 'P' && p.nextIs(i, 'M'): + p.coalesceTime(i) + p.set(i, "PM") + } case ' ': p.coalesceTime(i) p.stateTime = timeWs @@ -875,7 +1031,6 @@ iterRunes: p.seci = i + 1 p.minlen = i - p.mini } - } case timeOffset: // 19:55:00+0100 @@ -888,6 +1043,7 @@ iterRunes: case timeWs: // timeWsAlpha // 06:20:00 UTC + // 06:20:00 UTC-05 // 15:44:11 UTC+0100 2015 // 18:04:07 GMT+0100 (GMT Daylight Time) // 17:57:51 MST 2009 @@ -916,6 +1072,7 @@ iterRunes: default: if unicode.IsLetter(r) { // 06:20:00 UTC + // 06:20:00 UTC-05 // 15:44:11 UTC+0100 2015 // 17:57:51 MST 2009 p.tzi = i @@ -929,6 +1086,7 @@ iterRunes: } case timeWsAlpha: // 06:20:00 UTC + // 06:20:00 UTC-05 // timeWsAlphaWs // 17:57:51 MST 2009 // timeWsAlphaZoneOffset @@ -962,6 +1120,7 @@ iterRunes: // 17:57:51 MST 2009 case timeWsAlphaZoneOffset: + // 06:20:00 UTC-05 // timeWsAlphaZoneOffset // timeWsAlphaZoneOffsetWs // timeWsAlphaZoneOffsetWsExtra @@ -1258,6 +1417,14 @@ iterRunes: p.setYear() case timeWsAlphaZoneOffsetWsExtra: p.trimExtra() + case timeWsAlphaZoneOffset: + // 06:20:00 UTC-05 + if i-p.offseti < 4 { + p.set(p.offseti, "-07") + } else { + p.set(p.offseti, "-0700") + } + case timePeriod: p.mslen = i - p.msi case timeOffset: @@ -1411,14 +1578,23 @@ iterRunes: p.format = []byte("2 January 2006") return p, nil // parse("2 January 2006", datestr, loc) - case dateAlphaWsDigitCommaWs: + case dateAlphaWsMonth: + p.yearlen = i - p.yeari + p.setYear() + return p, nil + + case dateAlphaWsMonthMore: + return p, nil + + case dateAlphaWsDigitMoreWs: // oct 1, 1970 p.yearlen = i - p.yeari p.setYear() return p, nil - case dateAlphaWsDigitCommaWsYear: + case dateAlphaWsDigitMoreWsYear: // May 8, 2009 5:57:51 PM + // Jun 7, 2005, 05:57:51 return p, nil case dateAlphaWsAlpha: @@ -1468,6 +1644,7 @@ type parser struct { stateTime timeState format []byte datestr string + fullMonth string skip int extra int part1Len int @@ -1503,6 +1680,14 @@ func newParser(dateStr string, loc *time.Location) *parser { p.format = []byte(dateStr) return &p } + +func (p *parser) nextIs(i int, b byte) bool { + if len(p.datestr) > i+1 && p.datestr[i+1] == b { + return true + } + return false +} + func (p *parser) set(start int, val string) { if start < 0 { return @@ -1598,6 +1783,11 @@ func (p *parser) coalesceTime(end int) { } } } +func (p *parser) setFullMonth(month string) { + if p.moi == 0 { + p.format = []byte(fmt.Sprintf("%s%s", "January", p.format[len(month):])) + } +} func (p *parser) trimExtra() { if p.extra > 0 && len(p.format) > p.extra { @@ -1606,10 +1796,24 @@ 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 } + if len(p.fullMonth) > 0 { + p.setFullMonth(p.fullMonth) + } if p.skip > 0 && len(p.format) > p.skip { p.format = p.format[p.skip:] p.datestr = p.datestr[p.skip:] @@ -1620,3 +1824,11 @@ func (p *parser) parse() (time.Time, error) { } return time.ParseInLocation(string(p.format), p.datestr, p.loc) } +func isMonthFull(alpha string) bool { + for _, month := range months { + if alpha == month { + return true + } + } + return false +} diff --git a/parseany_test.go b/parseany_test.go index 200b68c..01ae099 100644 --- a/parseany_test.go +++ b/parseany_test.go @@ -11,8 +11,8 @@ import ( func TestOne(t *testing.T) { time.Local = time.UTC var ts time.Time - ts = MustParse("1 May 2013") - assert.Equal(t, "2013-05-01 00:00:00 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC))) + ts = MustParse("September 17, 2012, 10:10:09") + assert.Equal(t, "2012-09-17 10:10:09 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC))) } type dateTest struct { @@ -33,6 +33,7 @@ var testInputs = []dateTest{ {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"}, @@ -54,7 +55,7 @@ var testInputs = []dateTest{ {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"}, @@ -64,13 +65,42 @@ var testInputs = []dateTest{ {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 time + // 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] 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: "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: "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"}, // ? {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 PST", out: "2015-07-03 15:08:08 +0000 UTC", loc: "America/Los_Angeles"}, @@ -341,11 +371,6 @@ var testInputs = []dateTest{ {in: "1384216367111222333", out: "2013-11-12 00:32:47.111222333 +0000 UTC"}, } -/* - {in: , out: }, - - -*/ func TestParse(t *testing.T) { // Lets ensure we are operating on UTC @@ -437,6 +462,7 @@ var testParseErrors = []dateTest{ {in: "xyzq-baad"}, {in: "oct.-7-1970", err: true}, {in: "septe. 7, 1970", err: true}, + {in: "SeptemberRR 7th, 1970", err: true}, {in: "29-06-2016", err: true}, // this is just testing the empty space up front {in: " 2018-01-02 17:08:09 -07:00", err: true}, @@ -458,6 +484,7 @@ var testParseFormat = []dateTest{ // {in: "oct 7, 1970", out: "Jan 2, 2006"}, {in: "sept. 7, 1970", out: "Jan. 2, 2006"}, + {in: "May 05, 2015, 05:05:07", out: "Jan 02, 2006, 15:04:05"}, // 03 February 2013 {in: "03 February 2013", out: "02 January 2006"}, // 13:31:51.999 -07:00 MST