diff --git a/.gitignore b/.gitignore index 386a0f3..05f3653 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ dist vendor dateparse/dateparse +example/example diff --git a/README.md b/README.md index e7a71f6..0704587 100644 --- a/README.md +++ b/README.md @@ -312,6 +312,30 @@ var examples = []string{ "1384216367189", "1384216367111222", "1384216367111222333", + // syslog RFC3164 (and non-conformant variants) + "Apr 9 12:37:24", + "Apr 9 12:37:24-10", + "Apr 9 12:37:24-1000", + "Apr 9 12:37:24 UTC-10", + "Apr 9 12:37:24 MST", + "Apr 9 12:37:24 MST-07:00", + "Apr 9 12:37:24 TZ-10", + "Apr 9 12:37:24 TZ+02:00", + "Apr 9 12:37:24+10", + "Apr 9 12:37:24+10:00", + "Apr 9 12:37:24 CEST", + "Apr 9 12:37:24 CEST+0200", + "Apr 9 12:37:24 2025", + "Apr 9 12:37:24 2025 +02:00", + "Apr 9 2025 12:37:24", + "Apr 9 2025 12:37:24 -0700", + // syslog RFC5424 (and non-conformant variants) + "2025-04-09T12:37:24Z", + "2025-04-09T12:37:24.123Z", + "2025-04-09T12:37:24.123456Z", + "2025-04-09T12:37:24-10:00", + "2025-04-09T12:37:24.123 +0200", + "2025-04-09T12:37:24.123456 -0700 MDT", } var ( @@ -377,10 +401,10 @@ func main() { | 1st February 2018 13:58:24 | 2018-02-01 13:58:24 +0000 UTC | | Mon, 02 Jan 2006 15:04:05 MST | 2006-01-02 15:04:05 +0000 MST | | Mon, 02 Jan 2006 15:04:05 -0700 | 2006-01-02 15:04:05 -0700 -0700 | -| Tue, 11 Jul 2017 16:28:13 +0200 (CEST) | 2017-07-11 16:28:13 +0200 +0200 | +| Tue, 11 Jul 2017 16:28:13 +0200 (CEST) | 2017-07-11 16:28:13 +0200 CEST | | Mon 30 Sep 2018 09:09:09 PM UTC | 2018-09-30 21:09:09 +0000 UTC | | Sun, 07 Jun 2020 00:00:00 +0100 | 2020-06-07 00:00:00 +0100 +0100 | -| Wed, 8 Feb 2023 19:00:46 +1100 (AEDT) | 2023-02-08 19:00:46 +1100 +1100 | +| Wed, 8 Feb 2023 19:00:46 +1100 (AEDT) | 2023-02-08 19:00:46 +1100 AEDT | | 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 | | Monday Jan 02 15:04:05 -0700 2006 | 2006-01-02 15:04:05 -0700 -0700 | @@ -526,6 +550,28 @@ func main() { | 1384216367189 | 2013-11-12 00:32:47.189 +0000 UTC | | 1384216367111222 | 2013-11-12 00:32:47.111222 +0000 UTC | | 1384216367111222333 | 2013-11-12 00:32:47.111222333 +0000 UTC | +| Apr 9 12:37:24 | 0000-04-09 12:37:24 +0000 UTC | +| Apr 9 12:37:24-10 | 0000-04-09 12:37:24 -1000 -1000 | +| Apr 9 12:37:24-1000 | 0000-04-09 12:37:24 -1000 -1000 | +| Apr 9 12:37:24 UTC-10 | 0000-04-09 12:37:24 -1000 -1000 | +| Apr 9 12:37:24 MST | 0000-04-09 12:37:24 +0000 MST | +| Apr 9 12:37:24 MST-07:00 | 0000-04-09 12:37:24 -0700 MST | +| Apr 9 12:37:24 TZ-10 | 0000-04-09 12:37:24 -1000 -1000 | +| Apr 9 12:37:24 TZ+02:00 | 0000-04-09 12:37:24 +0200 +0200 | +| Apr 9 12:37:24+10 | 0000-04-09 12:37:24 +1000 +1000 | +| Apr 9 12:37:24+10:00 | 0000-04-09 12:37:24 +1000 +1000 | +| Apr 9 12:37:24 CEST | 0000-04-09 12:37:24 +0000 CEST | +| Apr 9 12:37:24 CEST+0200 | 0000-04-09 12:37:24 +0200 CEST | +| Apr 9 12:37:24 2025 | 2025-04-09 12:37:24 +0000 UTC | +| Apr 9 12:37:24 2025 +02:00 | 2025-04-09 12:37:24 +0200 +0200 | +| Apr 9 2025 12:37:24 | 2025-04-09 12:37:24 +0000 UTC | +| Apr 9 2025 12:37:24 -0700 | 2025-04-09 12:37:24 -0700 -0700 | +| 2025-04-09T12:37:24Z | 2025-04-09 12:37:24 +0000 UTC | +| 2025-04-09T12:37:24.123Z | 2025-04-09 12:37:24.123 +0000 UTC | +| 2025-04-09T12:37:24.123456Z | 2025-04-09 12:37:24.123456 +0000 UTC | +| 2025-04-09T12:37:24-10:00 | 2025-04-09 12:37:24 -1000 -1000 | +| 2025-04-09T12:37:24.123 +0200 | 2025-04-09 12:37:24.123 +0200 +0200 | +| 2025-04-09T12:37:24.123456 -0700 MDT | 2025-04-09 12:37:24.123456 -0700 MDT | +------------------------------------------------------------+-----------------------------------------+ */ diff --git a/example/main.go b/example/main.go index 7956573..1d9494c 100644 --- a/example/main.go +++ b/example/main.go @@ -220,6 +220,30 @@ var examples = []string{ "1384216367189", "1384216367111222", "1384216367111222333", + // syslog RFC3164 (and non-conformant variants) + "Apr 9 12:37:24", + "Apr 9 12:37:24-10", + "Apr 9 12:37:24-1000", + "Apr 9 12:37:24 UTC-10", + "Apr 9 12:37:24 MST", + "Apr 9 12:37:24 MST-07:00", + "Apr 9 12:37:24 TZ-10", + "Apr 9 12:37:24 TZ+02:00", + "Apr 9 12:37:24+10", + "Apr 9 12:37:24+10:00", + "Apr 9 12:37:24 CEST", + "Apr 9 12:37:24 CEST+0200", + "Apr 9 12:37:24 2025", + "Apr 9 12:37:24 2025 +02:00", + "Apr 9 2025 12:37:24", + "Apr 9 2025 12:37:24 -0700", + // syslog RFC5424 (and non-conformant variants) + "2025-04-09T12:37:24Z", + "2025-04-09T12:37:24.123Z", + "2025-04-09T12:37:24.123456Z", + "2025-04-09T12:37:24-10:00", + "2025-04-09T12:37:24.123 +0200", + "2025-04-09T12:37:24.123456 -0700 MDT", } var ( diff --git a/parseany.go b/parseany.go index fc2b2b5..2297079 100644 --- a/parseany.go +++ b/parseany.go @@ -1934,7 +1934,7 @@ iterRunes: switch r { case '+', '-': tzNameLower := strings.ToLower(p.datestr[p.tzi:i]) - if tzNameLower == "gmt" || tzNameLower == "utc" { + if tzNameLower == "gmt" || tzNameLower == "utc" || tzNameLower == "tz" { // This is a special form where the actual timezone isn't UTC, but is rather // specifying that the correct offset is a specified numeric offset from UTC: // 06:20:00 UTC-05 diff --git a/parseany_test.go b/parseany_test.go index a9f1368..c158a2a 100644 --- a/parseany_test.go +++ b/parseany_test.go @@ -789,6 +789,31 @@ var testInputs = []dateTest{ {in: " 2018-01-02 17:08:09 -07:00", out: "2018-01-03 00:08:09 +0000 UTC"}, {in: " 2018-01-02 17:08:09 -07:00", out: "2018-01-03 00:08:09 +0000 UTC"}, {in: " 2018-01-02 17:08:09 -07:00", out: "2018-01-03 00:08:09 +0000 UTC"}, + + //syslog RFC3164 formats and non-conformant variants observed in the wild + {in: "Apr 9 12:37:24", out: "0000-04-09 12:37:24 +0000 UTC"}, + {in: "Apr 9 12:37:24-10", out: "0000-04-09 22:37:24 +0000 UTC"}, + {in: "Apr 9 12:37:24-1000", out: "0000-04-09 22:37:24 +0000 UTC"}, + {in: "Apr 9 12:37:24 UTC-10", out: "0000-04-09 22:37:24 +0000 UTC"}, + {in: "Apr 9 12:37:24 MST", out: "0000-04-09 12:37:24 +0000 UTC", zname: "MST"}, + {in: "Apr 9 12:37:24 MST-07:00", out: "0000-04-09 19:37:24 +0000 UTC", zname: "MST"}, + {in: "Apr 9 12:37:24 TZ-10", out: "0000-04-09 22:37:24 +0000 UTC"}, + {in: "Apr 9 12:37:24 TZ+02:00", out: "0000-04-09 10:37:24 +0000 UTC"}, + {in: "Apr 9 12:37:24+10", out: "0000-04-09 02:37:24 +0000 UTC"}, + {in: "Apr 9 12:37:24+10:00", out: "0000-04-09 02:37:24 +0000 UTC"}, + {in: "Apr 9 12:37:24 CEST", out: "0000-04-09 12:37:24 +0000 UTC", zname: "CEST"}, + {in: "Apr 9 12:37:24 CEST+0200", out: "0000-04-09 10:37:24 +0000 UTC", zname: "CEST"}, + {in: "Apr 9 12:37:24 2025", out: "2025-04-09 12:37:24 +0000 UTC"}, + {in: "Apr 9 12:37:24 2025 +02:00", out: "2025-04-09 10:37:24 +0000 UTC"}, + {in: "Apr 9 2025 12:37:24", out: "2025-04-09 12:37:24 +0000 UTC"}, + {in: "Apr 9 2025 12:37:24 -0700", out: "2025-04-09 19:37:24 +0000 UTC"}, + //syslog RFC5424 formats and non-conformant variants observed in the wild + {in: "2025-04-09T12:37:24Z", out: "2025-04-09 12:37:24 +0000 UTC"}, + {in: "2025-04-09T12:37:24.123Z", out: "2025-04-09 12:37:24.123 +0000 UTC"}, + {in: "2025-04-09T12:37:24.123456Z", out: "2025-04-09 12:37:24.123456 +0000 UTC"}, + {in: "2025-04-09T12:37:24-10:00", out: "2025-04-09 22:37:24 +0000 UTC"}, + {in: "2025-04-09T12:37:24.123 +0200", out: "2025-04-09 10:37:24.123 +0000 UTC"}, + {in: "2025-04-09T12:37:24.123456 -0700 MDT", out: "2025-04-09 19:37:24.123456 +0000 UTC", zname: "MDT"}, } func TestParse(t *testing.T) { @@ -1025,6 +1050,8 @@ var testParseErrors = []dateTest{ {in: "Fri Jul 3 2015 06:04:07 UTC (GMT", err: true}, {in: "Fri Jul 3 2015 06:04:07 PST (Pacific (Daylight) Time)", err: true}, {in: "Fri Jul 3 2015 06:04:07 CEST (Central European Summer Time) extra", err: true}, + // Special TZ indicator must be followed by an offset + {in: "Apr 9 12:37:24 TZ", err: true}, } func TestParseErrors(t *testing.T) {