diff --git a/README.md b/README.md index 296617a..628af14 100644 --- a/README.md +++ b/README.md @@ -74,6 +74,7 @@ var examples = []string{ "May 8, 2009 5:57:51 PM", "oct 7, 1970", "oct 7, '70", + "oct. 7, '70", "Mon Jan 2 15:04:05 2006", "Mon Jan 2 15:04:05 MST 2006", "Mon Jan 02 15:04:05 -0700 2006", @@ -197,6 +198,7 @@ func main() { | May 8, 2009 5:57:51 PM | 2009-05-08 17:57:51 +0000 UTC | | oct 7, 1970 | 1970-10-07 00:00:00 +0000 UTC | | oct 7, '70 | 1970-10-07 00:00:00 +0000 UTC | +| oct. 7, '70 | 1970-10-07 00:00:00 +0000 UTC | | Mon Jan 2 15:04:05 2006 | 2006-01-02 15:04:05 +0000 UTC | | Mon Jan 2 15:04:05 MST 2006 | 2006-01-02 15:04:05 +0000 MST | | Mon Jan 02 15:04:05 -0700 2006 | 2006-01-02 15:04:05 -0700 -0700 | @@ -239,7 +241,7 @@ func main() { | 2014/4/02 03:00:51 | 2014-04-02 03:00:51 +0000 UTC | | 2012/03/19 10:11:59 | 2012-03-19 10:11:59 +0000 UTC | | 2012/03/19 10:11:59.3186369 | 2012-03-19 10:11:59.3186369 +0000 UTC | -| 2014年04月08日 | 2014-04-08 00:00:00 +0000 UTC | +| 2014年04月08日 | 2014-04-08 00:00:00 +0000 UTC | | 2006-01-02T15:04:05+0000 | 2006-01-02 15:04:05 +0000 UTC | | 2009-08-12T22:15:09-07:00 | 2009-08-12 22:15:09 -0700 -0700 | | 2009-08-12T22:15:09 | 2009-08-12 22:15:09 +0000 UTC | diff --git a/example/main.go b/example/main.go index 6ce8592..104d1a0 100644 --- a/example/main.go +++ b/example/main.go @@ -13,6 +13,7 @@ var examples = []string{ "May 8, 2009 5:57:51 PM", "oct 7, 1970", "oct 7, '70", + "oct. 7, 1970", "Mon Jan 2 15:04:05 2006", "Mon Jan 2 15:04:05 MST 2006", "Mon Jan 02 15:04:05 -0700 2006", @@ -136,6 +137,7 @@ func main() { | May 8, 2009 5:57:51 PM | 2009-05-08 17:57:51 +0000 UTC | | oct 7, 1970 | 1970-10-07 00:00:00 +0000 UTC | | oct 7, '70 | 1970-10-07 00:00:00 +0000 UTC | +| oct. 7, '70 | 1970-10-07 00:00:00 +0000 UTC | | Mon Jan 2 15:04:05 2006 | 2006-01-02 15:04:05 +0000 UTC | | Mon Jan 2 15:04:05 MST 2006 | 2006-01-02 15:04:05 +0000 MST | | Mon Jan 02 15:04:05 -0700 2006 | 2006-01-02 15:04:05 -0700 -0700 | diff --git a/parseany.go b/parseany.go index dd8c93a..ed908bc 100644 --- a/parseany.go +++ b/parseany.go @@ -60,6 +60,7 @@ const ( dateAlphaWsMonth dateAlphaWsAlpha dateAlphaWsAlphaYearmaybe + dateAlphaPeriodWsDigit dateWeekdayComma dateWeekdayAbbrevComma ) @@ -103,6 +104,10 @@ var ( ErrAmbiguousMMDD = fmt.Errorf("This date has ambiguous mm/dd vs dd/mm type format") ) +func unknownErr(datestr string) error { + return fmt.Errorf("Could not find format for %q", datestr) +} + // ParseAny parse an unknown date format, detect the layout. // Normal parse. Equivalent Timezone rules as time.Parse(). // NOTE: please see readme on mmdd vs ddmm ambiguous dates. @@ -355,6 +360,7 @@ func (p *parser) parse() (time.Time, error) { } return time.ParseInLocation(string(p.format), p.datestr, p.loc) } + func parseTime(datestr string, loc *time.Location) (*parser, error) { p := newParser(datestr, loc) @@ -380,7 +386,7 @@ iterRunes: } else if unicode.IsLetter(r) { p.stateDate = dateAlpha } else { - return nil, fmt.Errorf("unrecognized first character '%s' in %v", string(r), datestr) + return nil, unknownErr(datestr) } case dateDigit: @@ -448,7 +454,7 @@ iterRunes: // Chinese Year p.stateDate = dateDigitChineseYear case ',': - return nil, fmt.Errorf("Unrecognized format %q", datestr) + return nil, unknownErr(datestr) default: //if unicode.IsDigit(r) { continue @@ -649,6 +655,8 @@ iterRunes: // April 8, 2009 // dateAlphaWsMonthTime // January 02, 2006 at 3:04pm MST-07 + // dateAlphaPeriodWsDigit + // oct. 1, 1970 // dateWeekdayComma // Monday, 02 Jan 2006 15:04:05 MST // Monday, 02-Jan-06 15:04:05 MST @@ -696,73 +704,16 @@ iterRunes: p.set(0, "Mon") } else { p.stateDate = dateWeekdayComma - //p.set(0, "Monday") p.skip = i + 2 i++ // TODO: lets just make this "skip" as we don't need // the mon, monday, they are all superfelous and not needed // just lay down the skip, no need to fill and then skip } - } - case dateAlphaWsMonth: - // April 8, 2009 - if r == ',' { - if i-p.dayi == 2 { - p.format = []byte("January 02, 2006") - return p, nil - } - p.format = []byte("January 2, 2006") - return p, nil - } - case dateWeekdayComma: - // Monday, 02 Jan 2006 15:04:05 MST - // Monday, 02 Jan 2006 15:04:05 -0700 - // Monday, 02 Jan 2006 15:04:05 +0100 - // Monday, 02-Jan-06 15:04:05 MST - if p.dayi == 0 { - p.dayi = i - } - switch r { - case ' ', '-': - if p.moi == 0 { - p.moi = i + 1 - 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") - } else { - p.stateTime = timeStart - break iterRunes - } - } - case dateWeekdayAbbrevComma: - // Mon, 02 Jan 2006 15:04:05 MST - // Mon, 02 Jan 2006 15:04:05 -0700 - // Thu, 13 Jul 2017 08:58:40 +0100 - // 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 - switch r { - case ' ', '-': - if p.dayi == 0 { - p.dayi = i + 1 - } else if p.moi == 0 { - p.daylen = i - p.dayi - p.setDay() - p.moi = i + 1 - } else if p.yeari == 0 { - p.molen = i - p.moi - p.set(p.moi, "Jan") - p.yeari = i + 1 - } else { - p.yearlen = i - p.yeari - p.setYear() - p.stateTime = timeStart - break iterRunes - } + case r == '.': + p.stateDate = dateAlphaPeriodWsDigit + p.molen = i + p.set(0, "Jan") } case dateAlphaWs: @@ -780,7 +731,6 @@ iterRunes: case unicode.IsLetter(r): p.set(0, "Mon") p.stateDate = dateAlphaWsAlpha - //p.moi = i p.set(i, "Jan") case unicode.IsDigit(r): p.set(0, "Jan") @@ -792,6 +742,7 @@ iterRunes: // 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 @@ -843,6 +794,7 @@ iterRunes: p.dayi = i } } + case dateAlphaWsAlphaYearmaybe: // x // Mon Jan _2 15:04:05 2006 @@ -859,6 +811,79 @@ iterRunes: break iterRunes } + case dateAlphaWsMonth: + // April 8, 2009 + if r == ',' { + if i-p.dayi == 2 { + p.format = []byte("January 02, 2006") + return p, nil + } + p.format = []byte("January 2, 2006") + return p, nil + } + + case dateAlphaPeriodWsDigit: + // oct. 7, '70 + switch { + case r == ' ': + // continue + case unicode.IsDigit(r): + p.stateDate = dateAlphaWsDigit + p.dayi = i + default: + return p, unknownErr(datestr) + } + case dateWeekdayComma: + // Monday, 02 Jan 2006 15:04:05 MST + // Monday, 02 Jan 2006 15:04:05 -0700 + // Monday, 02 Jan 2006 15:04:05 +0100 + // Monday, 02-Jan-06 15:04:05 MST + if p.dayi == 0 { + p.dayi = i + } + switch r { + case ' ', '-': + if p.moi == 0 { + p.moi = i + 1 + 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") + } else { + p.stateTime = timeStart + break iterRunes + } + } + case dateWeekdayAbbrevComma: + // Mon, 02 Jan 2006 15:04:05 MST + // Mon, 02 Jan 2006 15:04:05 -0700 + // Thu, 13 Jul 2017 08:58:40 +0100 + // 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 + switch r { + case ' ', '-': + if p.dayi == 0 { + p.dayi = i + 1 + } else if p.moi == 0 { + p.daylen = i - p.dayi + p.setDay() + p.moi = i + 1 + } else if p.yeari == 0 { + p.molen = i - p.moi + p.set(p.moi, "Jan") + p.yeari = i + 1 + } else { + p.yearlen = i - p.yeari + p.setYear() + p.stateTime = timeStart + break iterRunes + } + } + default: break iterRunes } @@ -1509,5 +1534,5 @@ iterRunes: } - return nil, fmt.Errorf("Could not find date format for %s", datestr) + return nil, unknownErr(datestr) } diff --git a/parseany_test.go b/parseany_test.go index 867c7ff..0758048 100644 --- a/parseany_test.go +++ b/parseany_test.go @@ -11,8 +11,7 @@ import ( func TestOne(t *testing.T) { time.Local = time.UTC var ts time.Time - // - ts = MustParse("June 7, 2012") + ts = MustParse("jun. 7, 2012") assert.Equal(t, "2012-06-07 00:00:00 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC))) } @@ -25,6 +24,9 @@ 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: "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"}, @@ -417,6 +419,7 @@ var testParseErrors = []dateTest{ {in: "2009-15-12T22:15Z", err: true}, {in: "5,000-9,999", err: true}, {in: "xyzq-baad"}, + {in: "oct.-7-1970", err: true}, } func TestParseErrors(t *testing.T) {