diff --git a/parseany.go b/parseany.go index d59b441..ecd69fa 100644 --- a/parseany.go +++ b/parseany.go @@ -1292,7 +1292,6 @@ iterRunes: // 17:57:51 MST 2009 p.tzi = i p.stateTime = timeWsAlpha - //break iterTimeRunes } else if unicode.IsDigit(r) { // 00:12:00 2008 p.stateTime = timeWsYear @@ -1322,6 +1321,7 @@ iterRunes: p.offseti = i case ' ': // 17:57:51 MST 2009 + // 17:57:51 MST p.tzlen = i - p.tzi if p.tzlen == 4 { p.set(p.tzi, " MST") @@ -1441,6 +1441,7 @@ iterRunes: p.setYear() } case unicode.IsLetter(r): + // 15:04:05 -0700 MST if p.tzi == 0 { p.tzi = i } @@ -1626,6 +1627,17 @@ iterRunes: } switch p.stateTime { + case timeWsAlpha: + switch len(p.datestr) - p.tzi { + case 3: + // 13:31:51.999 +01:00 CET + p.set(p.tzi, "MST") + case 4: + p.set(p.tzi, "MST") + p.extra = len(p.datestr) - 1 + p.trimExtra() + } + case timeWsAlphaWs: p.yearlen = i - p.yeari p.setYear() @@ -1662,6 +1674,17 @@ iterRunes: case timeWsOffsetWs: // 17:57:51 -0700 2009 // 00:12:00 +0000 UTC + if p.tzi > 0 { + switch len(p.datestr) - p.tzi { + case 3: + // 13:31:51.999 +01:00 CET + p.set(p.tzi, "MST") + case 4: + // 13:31:51.999 +01:00 CEST + p.set(p.tzi, "MST ") + } + + } case timeWsOffsetColon: // 17:57:51 -07:00 p.set(p.offseti, "-07:00") @@ -2115,7 +2138,7 @@ func (p *parser) parse() (time.Time, error) { } if p.loc == nil { - //gou.Debugf("parse layout=%q input=%q \ntx, err := time.Parse(%q, %q)", string(p.format), p.datestr, string(p.format), p.datestr) + // gou.Debugf("parse layout=%q input=%q \ntx, err := time.Parse(%q, %q)", string(p.format), p.datestr, string(p.format), p.datestr) return time.Parse(string(p.format), p.datestr) } //gou.Debugf("parse layout=%q input=%q \ntx, err := time.ParseInLocation(%q, %q, %v)", string(p.format), p.datestr, string(p.format), p.datestr, p.loc) diff --git a/parseany_test.go b/parseany_test.go index cacb53e..377e915 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("2019-05-29T08:41-04") - assert.Equal(t, "2019-05-29 12:41:00 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC))) + ts = MustParse("Thu, 17 Dec 2020 15:39:13 GMT") + assert.Equal(t, "2020-12-17 15:39:13 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC))) } type dateTest struct { @@ -107,9 +107,10 @@ var testInputs = []dateTest{ {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 PST", out: "2015-07-03 15:08:08 +0000 UTC", loc: "America/Los_Angeles"}, + //{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"}, @@ -126,7 +127,7 @@ var testInputs = []dateTest{ {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 15:08:08 +0000 UTC", loc: "America/Los_Angeles"}, + {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"}, @@ -326,7 +327,7 @@ var testInputs = []dateTest{ {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 12:24:37 +0000 UTC", loc: "America/Los_Angeles"}, + {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"}, @@ -520,6 +521,8 @@ func TestParseErrors(t *testing.T) { } func TestParseLayout(t *testing.T) { + + time.Local = time.UTC // These tests are verifying that the layout returned by ParseFormat // are correct. Above tests correct parsing, this tests correct // re-usable formatting string @@ -546,10 +549,11 @@ func TestParseLayout(t *testing.T) { // yyyy-mm-dd hh:mm:ss +00:00 {in: "2012-08-03 18:31:59 +00:00", out: "2006-01-02 15:04:05 -07:00"}, // yyyy-mm-dd hh:mm:ss +0000 TZ - // Golang Native Format - {in: "2012-08-03 18:31:59 +0000 UTC", out: "2006-01-02 15:04:05 -0700 UTC"}, + // Golang Native Format = "2006-01-02 15:04:05.999999999 -0700 MST" + {in: "2012-08-03 18:31:59 +0000 UTC", out: "2006-01-02 15:04:05 -0700 MST"}, // yyyy-mm-dd hh:mm:ss TZ - {in: "2012-08-03 18:31:59 UTC", out: "2006-01-02 15:04:05 UTC"}, + {in: "2012-08-03 18:31:59 UTC", out: "2006-01-02 15:04:05 MST"}, + {in: "2012-08-03 18:31:59 CEST", out: "2006-01-02 15:04:05 MST"}, // yyyy-mm-ddThh:mm:ss-07:00 {in: "2009-08-12T22:15:09-07:00", out: "2006-01-02T15:04:05-07:00"}, // yyyy-mm-ddThh:mm:ss-0700