support jun. 7, 1985 format closes #61

This commit is contained in:
Aaron Raddon 2018-06-08 18:01:07 -07:00
parent 4c29e1d266
commit 52b556944e
4 changed files with 100 additions and 68 deletions

View File

@ -74,6 +74,7 @@ var examples = []string{
"May 8, 2009 5:57:51 PM", "May 8, 2009 5:57:51 PM",
"oct 7, 1970", "oct 7, 1970",
"oct 7, '70", "oct 7, '70",
"oct. 7, '70",
"Mon Jan 2 15:04:05 2006", "Mon Jan 2 15:04:05 2006",
"Mon Jan 2 15:04:05 MST 2006", "Mon Jan 2 15:04:05 MST 2006",
"Mon Jan 02 15:04:05 -0700 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 | | 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, 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 |
| 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 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 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 | | 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 | | 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 | 2012-03-19 10:11:59 +0000 UTC |
| 2012/03/19 10:11:59.3186369 | 2012-03-19 10:11:59.3186369 +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 | | 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-07:00 | 2009-08-12 22:15:09 -0700 -0700 |
| 2009-08-12T22:15:09 | 2009-08-12 22:15:09 +0000 UTC | | 2009-08-12T22:15:09 | 2009-08-12 22:15:09 +0000 UTC |

View File

@ -13,6 +13,7 @@ var examples = []string{
"May 8, 2009 5:57:51 PM", "May 8, 2009 5:57:51 PM",
"oct 7, 1970", "oct 7, 1970",
"oct 7, '70", "oct 7, '70",
"oct. 7, 1970",
"Mon Jan 2 15:04:05 2006", "Mon Jan 2 15:04:05 2006",
"Mon Jan 2 15:04:05 MST 2006", "Mon Jan 2 15:04:05 MST 2006",
"Mon Jan 02 15:04:05 -0700 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 | | 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, 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 |
| 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 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 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 | | Mon Jan 02 15:04:05 -0700 2006 | 2006-01-02 15:04:05 -0700 -0700 |

View File

@ -60,6 +60,7 @@ const (
dateAlphaWsMonth dateAlphaWsMonth
dateAlphaWsAlpha dateAlphaWsAlpha
dateAlphaWsAlphaYearmaybe dateAlphaWsAlphaYearmaybe
dateAlphaPeriodWsDigit
dateWeekdayComma dateWeekdayComma
dateWeekdayAbbrevComma dateWeekdayAbbrevComma
) )
@ -103,6 +104,10 @@ var (
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")
) )
func unknownErr(datestr string) error {
return fmt.Errorf("Could not find format for %q", datestr)
}
// ParseAny parse an unknown date format, detect the layout. // ParseAny parse an unknown date format, detect the layout.
// Normal parse. Equivalent Timezone rules as time.Parse(). // Normal parse. Equivalent Timezone rules as time.Parse().
// NOTE: please see readme on mmdd vs ddmm ambiguous dates. // 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) return time.ParseInLocation(string(p.format), p.datestr, p.loc)
} }
func parseTime(datestr string, loc *time.Location) (*parser, error) { func parseTime(datestr string, loc *time.Location) (*parser, error) {
p := newParser(datestr, loc) p := newParser(datestr, loc)
@ -380,7 +386,7 @@ iterRunes:
} else if unicode.IsLetter(r) { } else if unicode.IsLetter(r) {
p.stateDate = dateAlpha p.stateDate = dateAlpha
} else { } else {
return nil, fmt.Errorf("unrecognized first character '%s' in %v", string(r), datestr) return nil, unknownErr(datestr)
} }
case dateDigit: case dateDigit:
@ -448,7 +454,7 @@ iterRunes:
// Chinese Year // Chinese Year
p.stateDate = dateDigitChineseYear p.stateDate = dateDigitChineseYear
case ',': case ',':
return nil, fmt.Errorf("Unrecognized format %q", datestr) return nil, unknownErr(datestr)
default: default:
//if unicode.IsDigit(r) { //if unicode.IsDigit(r) {
continue continue
@ -649,6 +655,8 @@ iterRunes:
// April 8, 2009 // April 8, 2009
// dateAlphaWsMonthTime // dateAlphaWsMonthTime
// January 02, 2006 at 3:04pm MST-07 // January 02, 2006 at 3:04pm MST-07
// dateAlphaPeriodWsDigit
// oct. 1, 1970
// dateWeekdayComma // dateWeekdayComma
// Monday, 02 Jan 2006 15:04:05 MST // Monday, 02 Jan 2006 15:04:05 MST
// Monday, 02-Jan-06 15:04:05 MST // Monday, 02-Jan-06 15:04:05 MST
@ -696,73 +704,16 @@ iterRunes:
p.set(0, "Mon") p.set(0, "Mon")
} else { } else {
p.stateDate = dateWeekdayComma p.stateDate = dateWeekdayComma
//p.set(0, "Monday")
p.skip = i + 2 p.skip = i + 2
i++ i++
// TODO: lets just make this "skip" as we don't need // TODO: lets just make this "skip" as we don't need
// the mon, monday, they are all superfelous and not needed // the mon, monday, they are all superfelous and not needed
// just lay down the skip, no need to fill and then skip // just lay down the skip, no need to fill and then skip
} }
} case r == '.':
case dateAlphaWsMonth: p.stateDate = dateAlphaPeriodWsDigit
// April 8, 2009 p.molen = i
if r == ',' { p.set(0, "Jan")
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 dateAlphaWs: case dateAlphaWs:
@ -780,7 +731,6 @@ iterRunes:
case unicode.IsLetter(r): case unicode.IsLetter(r):
p.set(0, "Mon") p.set(0, "Mon")
p.stateDate = dateAlphaWsAlpha p.stateDate = dateAlphaWsAlpha
//p.moi = i
p.set(i, "Jan") p.set(i, "Jan")
case unicode.IsDigit(r): case unicode.IsDigit(r):
p.set(0, "Jan") p.set(0, "Jan")
@ -792,6 +742,7 @@ iterRunes:
// May 8, 2009 5:57:51 PM // May 8, 2009 5:57:51 PM
// oct 1, 1970 // oct 1, 1970
// oct 7, '70 // oct 7, '70
// oct. 7, 1970
//gou.Debugf("%d %s dateAlphaWsDigit %s %s", i, string(r), p.ds(), p.ts()) //gou.Debugf("%d %s dateAlphaWsDigit %s %s", i, string(r), p.ds(), p.ts())
if r == ',' { if r == ',' {
p.daylen = i - p.dayi p.daylen = i - p.dayi
@ -843,6 +794,7 @@ iterRunes:
p.dayi = i p.dayi = i
} }
} }
case dateAlphaWsAlphaYearmaybe: case dateAlphaWsAlphaYearmaybe:
// x // x
// Mon Jan _2 15:04:05 2006 // Mon Jan _2 15:04:05 2006
@ -859,6 +811,79 @@ iterRunes:
break 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: default:
break iterRunes break iterRunes
} }
@ -1509,5 +1534,5 @@ iterRunes:
} }
return nil, fmt.Errorf("Could not find date format for %s", datestr) return nil, unknownErr(datestr)
} }

View File

@ -11,8 +11,7 @@ import (
func TestOne(t *testing.T) { func TestOne(t *testing.T) {
time.Local = time.UTC time.Local = time.UTC
var ts time.Time var ts time.Time
// ts = MustParse("jun. 7, 2012")
ts = MustParse("June 7, 2012")
assert.Equal(t, "2012-06-07 00:00:00 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC))) 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, 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, '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: "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: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: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: "2009-15-12T22:15Z", err: true},
{in: "5,000-9,999", err: true}, {in: "5,000-9,999", err: true},
{in: "xyzq-baad"}, {in: "xyzq-baad"},
{in: "oct.-7-1970", err: true},
} }
func TestParseErrors(t *testing.T) { func TestParseErrors(t *testing.T) {