diff --git a/v3/clock/rfc822.go b/v3/clock/rfc822.go index 446b58b4..c6a4dc25 100644 --- a/v3/clock/rfc822.go +++ b/v3/clock/rfc822.go @@ -16,6 +16,27 @@ func NewRFC822Time(t Time) RFC822Time { return RFC822Time{Time: t.Truncate(Second)} } +// ParseRFC822Time parses an RFC822 time string. +func ParseRFC822Time(s string) (Time, error) { + t, err := Parse("Mon, 2 Jan 2006 15:04:05 MST", s) + if err == nil { + return t, nil + } + if parseErr, ok := err.(*ParseError); !ok || parseErr.LayoutElem != "MST" { + return Time{}, parseErr + } + if t, err = Parse("Mon, 2 Jan 2006 15:04:05 -0700", s); err == nil { + return t, nil + } + if parseErr, ok := err.(*ParseError); !ok || parseErr.LayoutElem != "" { + return Time{}, parseErr + } + if t, err = Parse("Mon, 2 Jan 2006 15:04:05 -0700 (MST)", s); err == nil { + return t, nil + } + return Time{}, err +} + // NewRFC822Time creates RFC822Time from a Unix timestamp (seconds from Epoch). func NewRFC822TimeFromUnix(timestamp int64) RFC822Time { return RFC822Time{Time: Unix(timestamp, 0).UTC()} @@ -30,15 +51,11 @@ func (t *RFC822Time) UnmarshalJSON(s []byte) error { if err != nil { return err } - if t.Time, err = Parse("Mon, 2 Jan 2006 15:04:05 MST", q); err == nil { - return nil - } - if err, ok := err.(*ParseError); !ok || err.LayoutElem != "MST" { - return err - } - if t.Time, err = Parse("Mon, 2 Jan 2006 15:04:05 -0700", q); err != nil { + parsed, err := ParseRFC822Time(q) + if err != nil { return err } + t.Time = parsed return nil } diff --git a/v3/clock/rfc822_test.go b/v3/clock/rfc822_test.go index 49bca502..ae5761d4 100644 --- a/v3/clock/rfc822_test.go +++ b/v3/clock/rfc822_test.go @@ -91,6 +91,22 @@ func TestRFC822Unmarshaling(t *testing.T) { inRFC822: "Sun, 1 Sep 2019 11:20:07 +0300", outRFC3339: "2019-09-01T11:20:07+03:00", outRFC822: "Sun, 01 Sep 2019 11:20:07 MSK", + }, { + inRFC822: "Sun, 1 Sep 2019 11:20:07 UTC", + outRFC3339: "2019-09-01T11:20:07Z", + outRFC822: "Sun, 01 Sep 2019 11:20:07 UTC", + }, { + inRFC822: "Sun, 1 Sep 2019 11:20:07 UTC", + outRFC3339: "2019-09-01T11:20:07Z", + outRFC822: "Sun, 01 Sep 2019 11:20:07 UTC", + }, { + inRFC822: "Sun, 1 Sep 2019 11:20:07 GMT", + outRFC3339: "2019-09-01T11:20:07Z", + outRFC822: "Sun, 01 Sep 2019 11:20:07 GMT", + }, { + inRFC822: "Fri, 21 Nov 1997 09:55:06 -0600 (MDT)", + outRFC3339: "1997-11-21T09:55:06-06:00", + outRFC822: "Fri, 21 Nov 1997 09:55:06 MDT", }} { tcDesc := fmt.Sprintf("Test case #%d: %v", i, tc) var ts testStruct @@ -113,10 +129,10 @@ func TestRFC822UnmarshalingError(t *testing.T) { outError string }{{ inEncoded: `{"ts": "Thu, 29 Aug 2019 11:20:07"}`, - outError: `parsing time "Thu, 29 Aug 2019 11:20:07" as "Mon, 02 Jan 2006 15:04:05 -0700": cannot parse "" as "-0700"`, + outError: `parsing time "Thu, 29 Aug 2019 11:20:07" as "Mon, 2 Jan 2006 15:04:05 -0700": cannot parse "" as "-0700"`, }, { inEncoded: `{"ts": "foo"}`, - outError: `parsing time "foo" as "Mon, 02 Jan 2006 15:04:05 MST": cannot parse "foo" as "Mon"`, + outError: `parsing time "foo" as "Mon, 2 Jan 2006 15:04:05 MST": cannot parse "foo" as "Mon"`, }, { inEncoded: `{"ts": 42}`, outError: "invalid syntax",