diff --git a/README.md b/README.md index 8945a07..c8251f6 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,7 @@ import ( "github.com/araddon/dateparse" ) + var examples = []string{ "May 8, 2009 5:57:51 PM", "Mon Jan 2 15:04:05 2006", @@ -27,12 +28,12 @@ var examples = []string{ "Mon Jan 02 15:04:05 -0700 2006", "Monday, 02-Jan-06 15:04:05 MST", "Mon, 02 Jan 2006 15:04:05 MST", + "Tue, 11 Jul 2017 16:28:13 +0200 (CEST)", + "Mon, 02 Jan 2006 15:04:05 -0700", "Mon Aug 10 15:44:11 UTC+0100 2015", "Fri Jul 03 2015 18:04:07 GMT+0100 (GMT Daylight Time)", - "Mon, 02 Jan 2006 15:04:05 -0700", "12 Feb 2006, 19:17", - "2015-02-18 00:12:00 +0000 GMT", - "2015-02-18 00:12:00 +0000 UTC", + // mm/dd/yy "3/31/2014", "03/31/2014", "08/21/71", @@ -48,7 +49,7 @@ var examples = []string{ "4/02/2014 03:00:51", "03/19/2012 10:11:59", "03/19/2012 10:11:59.3186369", - // yyyy/mm/dd + // yyyy/mm/dd "2014/3/31", "2014/03/31", "2014/4/8 22:05", @@ -57,22 +58,26 @@ var examples = []string{ "2014/4/02 03:00:51", "2012/03/19 10:11:59", "2012/03/19 10:11:59.3186369", - // yyyy-mm-dd + // yyyy-mm-ddThh + "2006-01-02T15:04:05+0000", "2009-08-12T22:15:09-07:00", - "2009-08-12T22:15:09Z", "2009-08-12T22:15:09", + "2009-08-12T22:15:09Z", + // yyyy-mm-dd hh:mm:ss "2014-04-26 17:24:37.3186369", - "2014-04-26 17:24:37.318636", - "2012-08-03 18:31:59.257000000 +0000 UTC", - "2015-09-30 18:48:56.35272715 +0000 UTC", "2012-08-03 18:31:59.257000000", - "2013-04-01 22:43:22", "2014-04-26 17:24:37.123", + "2013-04-01 22:43:22", "2014-12-16 06:20:00 UTC", "2014-12-16 06:20:00 GMT", "2014-04-26 05:24:37 PM", "2014-04-26 13:13:43 +0800", "2014-04-26 13:13:44 +09:00", + "2012-08-03 18:31:59.257000000 +0000 UTC", + "2015-09-30 18:48:56.35272715 +0000 UTC", + "2015-02-18 00:12:00 +0000 GMT", + "2015-02-18 00:12:00 +0000 UTC", + "2017-07-19 03:21:51+00:00", "2014-04-26", "2014-04", "2014", @@ -84,6 +89,7 @@ var examples = []string{ "1384216367189", } + func main() { table := termtables.CreateTable() diff --git a/dateparse/main.go b/dateparse/main.go new file mode 100644 index 0000000..9cb5298 --- /dev/null +++ b/dateparse/main.go @@ -0,0 +1,50 @@ +package main + +import ( + "flag" + "fmt" + "time" + + "github.com/apcera/termtables" + "github.com/araddon/dateparse" +) + +var ( + timezone = "" + datestr = "" +) + +func main() { + flag.StringVar(&timezone, "timezone", "UTC", "Timezone aka `America/Los_Angeles` formatted time-zone") + flag.Parse() + + if len(flag.Args()) == 0 { + fmt.Println(`Must pass ./dateparse "2009-08-12T22:15:09.99Z"`) + return + } + datestr = flag.Args()[0] + + table := termtables.CreateTable() + + table.AddHeaders("Input", "Timezone", "Parsed, and Output as %v") + + zonename, _ := time.Now().In(time.Local).Zone() + + table.AddRow(datestr, fmt.Sprintf("%v", zonename), fmt.Sprintf("%v", dateparse.MustParse(datestr))) + + if timezone != "" { + // NOTE: This is very, very important to understand + // time-parsing in go + loc, err := time.LoadLocation(timezone) + if err != nil { + panic(err.Error()) + } + time.Local = loc + table.AddRow(datestr, fmt.Sprintf("%v", timezone), fmt.Sprintf("%v", dateparse.MustParse(datestr))) + } + + time.Local = time.UTC + table.AddRow(datestr, "UTC", fmt.Sprintf("%v", dateparse.MustParse(datestr))) + + fmt.Println(table.Render()) +} diff --git a/example/main.go b/example/main.go index cd73cf9..d1dd24d 100644 --- a/example/main.go +++ b/example/main.go @@ -21,8 +21,7 @@ var examples = []string{ "Mon Aug 10 15:44:11 UTC+0100 2015", "Fri Jul 03 2015 18:04:07 GMT+0100 (GMT Daylight Time)", "12 Feb 2006, 19:17", - "2015-02-18 00:12:00 +0000 GMT", - "2015-02-18 00:12:00 +0000 UTC", + // mm/dd/yy "3/31/2014", "03/31/2014", "08/21/71", @@ -38,7 +37,7 @@ var examples = []string{ "4/02/2014 03:00:51", "03/19/2012 10:11:59", "03/19/2012 10:11:59.3186369", - // yyyy/mm/dd + // yyyy/mm/dd "2014/3/31", "2014/03/31", "2014/4/8 22:05", @@ -47,24 +46,26 @@ var examples = []string{ "2014/4/02 03:00:51", "2012/03/19 10:11:59", "2012/03/19 10:11:59.3186369", - // yyyy-mm-ddT - "2009-08-12T22:15:09-07:00", - "2009-08-12T22:15:09Z", - "2009-08-12T22:15:09", + // yyyy-mm-ddThh "2006-01-02T15:04:05+0000", + "2009-08-12T22:15:09-07:00", + "2009-08-12T22:15:09", + "2009-08-12T22:15:09Z", // yyyy-mm-dd hh:mm:ss "2014-04-26 17:24:37.3186369", - "2014-04-26 17:24:37.318636", - "2012-08-03 18:31:59.257000000 +0000 UTC", - "2015-09-30 18:48:56.35272715 +0000 UTC", "2012-08-03 18:31:59.257000000", - "2013-04-01 22:43:22", "2014-04-26 17:24:37.123", + "2013-04-01 22:43:22", "2014-12-16 06:20:00 UTC", "2014-12-16 06:20:00 GMT", "2014-04-26 05:24:37 PM", "2014-04-26 13:13:43 +0800", "2014-04-26 13:13:44 +09:00", + "2012-08-03 18:31:59.257000000 +0000 UTC", + "2015-09-30 18:48:56.35272715 +0000 UTC", + "2015-02-18 00:12:00 +0000 GMT", + "2015-02-18 00:12:00 +0000 UTC", + "2017-07-19 03:21:51+00:00", "2014-04-26", "2014-04", "2014", @@ -108,67 +109,67 @@ func main() { } /* -+-------------------------------------------------------+------------------------------------------+ -| Input | Parsed, and Output as %v | -+-------------------------------------------------------+------------------------------------------+ -| May 8, 2009 5:57:51 PM | 2009-05-08 17:57:51 +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 | -| Monday, 02-Jan-06 15:04:05 MST | 2006-01-02 15:04:05 +0000 MST | -| Mon, 02 Jan 2006 15:04:05 MST | 2006-01-02 15:04:05 +0000 MST | -| Tue, 11 Jul 2017 16:28:13 +0200 (CEST) | 2017-07-11 16:28:13 +0200 +0200 | -| Mon, 02 Jan 2006 15:04:05 -0700 | 2006-01-02 15:04:05 -0700 -0700 | -| Mon Aug 10 15:44:11 UTC+0100 2015 | 2015-08-10 15:44:11 +0000 UTC | -| Fri Jul 03 2015 18:04:07 GMT+0100 (GMT Daylight Time) | 2015-07-03 18:04:07 +0100 GMT | -| 12 Feb 2006, 19:17 | 2006-02-12 19:17:00 +0000 UTC | -| 2015-02-18 00:12:00 +0000 GMT | 2015-02-18 00:12:00 +0000 +0000 | -| 2015-02-18 00:12:00 +0000 UTC | 2015-02-18 00:12:00 +0000 +0000 | -| 3/31/2014 | 2014-03-31 00:00:00 +0000 UTC | -| 03/31/2014 | 2014-03-31 00:00:00 +0000 UTC | -| 08/21/71 | 1971-08-21 00:00:00 +0000 UTC | -| 8/1/71 | 1971-08-01 00:00:00 +0000 UTC | -| 4/8/2014 22:05 | 2014-04-08 22:05:00 +0000 UTC | -| 04/08/2014 22:05 | 2014-04-08 22:05:00 +0000 UTC | -| 04/2/2014 03:00:51 | 2014-04-02 03:00:51 +0000 UTC | -| 8/8/1965 12:00:00 AM | 1965-08-08 00:00:00 +0000 UTC | -| 8/8/1965 01:00:01 PM | 1965-08-08 13:00:01 +0000 UTC | -| 8/8/1965 01:00 PM | 1965-08-08 13:00:00 +0000 UTC | -| 8/8/1965 1:00 PM | 1965-08-08 13:00:00 +0000 UTC | -| 8/8/1965 12:00 AM | 1965-08-08 00:00:00 +0000 UTC | -| 4/02/2014 03:00:51 | 2014-04-02 03:00:51 +0000 UTC | -| 03/19/2012 10:11:59 | 2012-03-19 10:11:59 +0000 UTC | -| 03/19/2012 10:11:59.3186369 | 2012-03-19 10:11:59.3186369 +0000 UTC | -| 2014/3/31 | 2014-03-31 00:00:00 +0000 UTC | -| 2014/03/31 | 2014-03-31 00:00:00 +0000 UTC | -| 2014/4/8 22:05 | 2014-04-08 22:05:00 +0000 UTC | -| 2014/04/08 22:05 | 2014-04-08 22:05:00 +0000 UTC | -| 2014/04/2 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.3186369 | 2012-03-19 10:11:59.3186369 +0000 UTC | -| 2009-08-12T22:15:09-07:00 | 2009-08-12 22:15:09 -0700 PDT | -| 2009-08-12T22:15:09Z | 2009-08-12 22:15:09 +0000 UTC | -| 2009-08-12T22:15:09 | 2009-08-12 22:15:09 +0000 UTC | -| 2006-01-02T15:04:05+0000 | 2006-01-02 15:04:05 +0000 +0000 | -| 2014-04-26 17:24:37.3186369 | 2014-04-26 17:24:37.3186369 +0000 UTC | -| 2014-04-26 17:24:37.318636 | 2014-04-26 17:24:37.318636 +0000 UTC | -| 2012-08-03 18:31:59.257000000 +0000 UTC | 2012-08-03 18:31:59.257 +0000 +0000 | -| 2015-09-30 18:48:56.35272715 +0000 UTC | 2015-09-30 18:48:56.35272715 +0000 +0000 | -| 2012-08-03 18:31:59.257000000 | 2012-08-03 18:31:59.257 +0000 UTC | -| 2013-04-01 22:43:22 | 2013-04-01 22:43:22 +0000 UTC | -| 2014-04-26 17:24:37.123 | 2014-04-26 17:24:37.123 +0000 UTC | -| 2014-12-16 06:20:00 UTC | 2014-12-16 06:20:00 +0000 UTC | -| 2014-12-16 06:20:00 GMT | 2014-12-16 06:20:00 +0000 UTC | -| 2014-04-26 05:24:37 PM | 2014-04-26 17:24:37 +0000 UTC | -| 2014-04-26 13:13:43 +0800 | 2014-04-26 13:13:43 +0800 +0800 | -| 2014-04-26 13:13:44 +09:00 | 2014-04-26 13:13:44 +0900 +0900 | -| 2014-04-26 | 2014-04-26 00:00:00 +0000 UTC | -| 2014-04 | 2014-04-01 00:00:00 +0000 UTC | -| 2014 | 2014-01-01 00:00:00 +0000 UTC | -| 2014-05-11 08:20:13,787 | 2014-05-11 01:20:13.787 -0700 PDT | -| 20140601 | 2014-06-01 00:00:00 +0000 UTC | -| 1332151919 | 2012-03-19 03:11:59 -0700 PDT | -| 1384216367189 | 2013-11-11 16:32:47.189 -0800 PST | -+-------------------------------------------------------+------------------------------------------+ ++-------------------------------------------------------+----------------------------------------+ +| Input | Parsed, and Output as %v | ++-------------------------------------------------------+----------------------------------------+ +| May 8, 2009 5:57:51 PM | 2009-05-08 17:57:51 +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 | +| Monday, 02-Jan-06 15:04:05 MST | 2006-01-02 15:04:05 +0000 MST | +| Mon, 02 Jan 2006 15:04:05 MST | 2006-01-02 15:04:05 +0000 MST | +| Tue, 11 Jul 2017 16:28:13 +0200 (CEST) | 2017-07-11 16:28:13 +0200 +0200 | +| Mon, 02 Jan 2006 15:04:05 -0700 | 2006-01-02 15:04:05 -0700 -0700 | +| Mon Aug 10 15:44:11 UTC+0100 2015 | 2015-08-10 15:44:11 +0000 UTC | +| Fri Jul 03 2015 18:04:07 GMT+0100 (GMT Daylight Time) | 2015-07-03 18:04:07 +0100 GMT | +| 12 Feb 2006, 19:17 | 2006-02-12 19:17:00 +0000 UTC | +| 3/31/2014 | 2014-03-31 00:00:00 +0000 UTC | +| 03/31/2014 | 2014-03-31 00:00:00 +0000 UTC | +| 08/21/71 | 1971-08-21 00:00:00 +0000 UTC | +| 8/1/71 | 1971-08-01 00:00:00 +0000 UTC | +| 4/8/2014 22:05 | 2014-04-08 22:05:00 +0000 UTC | +| 04/08/2014 22:05 | 2014-04-08 22:05:00 +0000 UTC | +| 04/2/2014 03:00:51 | 2014-04-02 03:00:51 +0000 UTC | +| 8/8/1965 12:00:00 AM | 1965-08-08 00:00:00 +0000 UTC | +| 8/8/1965 01:00:01 PM | 1965-08-08 13:00:01 +0000 UTC | +| 8/8/1965 01:00 PM | 1965-08-08 13:00:00 +0000 UTC | +| 8/8/1965 1:00 PM | 1965-08-08 13:00:00 +0000 UTC | +| 8/8/1965 12:00 AM | 1965-08-08 00:00:00 +0000 UTC | +| 4/02/2014 03:00:51 | 2014-04-02 03:00:51 +0000 UTC | +| 03/19/2012 10:11:59 | 2012-03-19 10:11:59 +0000 UTC | +| 03/19/2012 10:11:59.3186369 | 2012-03-19 10:11:59.3186369 +0000 UTC | +| 2014/3/31 | 2014-03-31 00:00:00 +0000 UTC | +| 2014/03/31 | 2014-03-31 00:00:00 +0000 UTC | +| 2014/4/8 22:05 | 2014-04-08 22:05:00 +0000 UTC | +| 2014/04/08 22:05 | 2014-04-08 22:05:00 +0000 UTC | +| 2014/04/2 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.3186369 | 2012-03-19 10:11:59.3186369 +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 | +| 2009-08-12T22:15:09Z | 2009-08-12 22:15:09 +0000 UTC | +| 2014-04-26 17:24:37.3186369 | 2014-04-26 17:24:37.3186369 +0000 UTC | +| 2012-08-03 18:31:59.257000000 | 2012-08-03 18:31:59.257 +0000 UTC | +| 2014-04-26 17:24:37.123 | 2014-04-26 17:24:37.123 +0000 UTC | +| 2013-04-01 22:43:22 | 2013-04-01 22:43:22 +0000 UTC | +| 2014-12-16 06:20:00 UTC | 2014-12-16 06:20:00 +0000 UTC | +| 2014-12-16 06:20:00 GMT | 2014-12-16 06:20:00 +0000 UTC | +| 2014-04-26 05:24:37 PM | 2014-04-26 17:24:37 +0000 UTC | +| 2014-04-26 13:13:43 +0800 | 2014-04-26 13:13:43 +0800 +0800 | +| 2014-04-26 13:13:44 +09:00 | 2014-04-26 13:13:44 +0900 +0900 | +| 2012-08-03 18:31:59.257000000 +0000 UTC | 2012-08-03 18:31:59.257 +0000 UTC | +| 2015-09-30 18:48:56.35272715 +0000 UTC | 2015-09-30 18:48:56.35272715 +0000 UTC | +| 2015-02-18 00:12:00 +0000 GMT | 2015-02-18 00:12:00 +0000 UTC | +| 2015-02-18 00:12:00 +0000 UTC | 2015-02-18 00:12:00 +0000 UTC | +| 2017-07-19 03:21:51+00:00 | 2017-07-19 03:21:51 +0000 UTC | +| 2014-04-26 | 2014-04-26 00:00:00 +0000 UTC | +| 2014-04 | 2014-04-01 00:00:00 +0000 UTC | +| 2014 | 2014-01-01 00:00:00 +0000 UTC | +| 2014-05-11 08:20:13,787 | 2014-05-11 08:20:13.787 +0000 UTC | +| 20140601 | 2014-06-01 00:00:00 +0000 UTC | +| 1332151919 | 2012-03-19 10:11:59 +0000 UTC | +| 1384216367189 | 2013-11-12 00:32:47.189 +0000 UTC | ++-------------------------------------------------------+----------------------------------------+ */ diff --git a/parseany.go b/parseany.go index bbc31dd..121a084 100644 --- a/parseany.go +++ b/parseany.go @@ -26,11 +26,18 @@ const ( ST_DIGIT ST_DIGITDASH ST_DIGITDASHWS - ST_DIGITDASHWSALPHA + ST_DIGITDASHWSWS + ST_DIGITDASHWSWSAMPMMAYBE + ST_DIGITDASHWSWSOFFSET + ST_DIGITDASHWSWSOFFSETALPHA + ST_DIGITDASHWSWSOFFSETCOLONALPHA + ST_DIGITDASHWSWSOFFSETCOLON + ST_DIGITDASHWSOFFSET + ST_DIGITDASHWSWSALPHA ST_DIGITDASHWSDOT ST_DIGITDASHWSDOTALPHA - ST_DIGITDASHWSDOTPLUS - ST_DIGITDASHWSDOTPLUSALPHA + ST_DIGITDASHWSDOTOFFSET + ST_DIGITDASHWSDOTOFFSETALPHA ST_DIGITDASHT ST_DIGITDASHTZ ST_DIGITDASHTZDIGIT @@ -52,7 +59,6 @@ const ( ST_ALPHAWSALPHACOLONALPHA ST_ALPHAWSALPHACOLONALPHAOFFSET ST_ALPHAWSALPHACOLONALPHAOFFSETALPHA - ST_ALPHACOMMA ST_WEEKDAYCOMMA ST_WEEKDAYCOMMADELTA ST_WEEKDAYABBREVCOMMA @@ -123,6 +129,7 @@ iterRunes: // 2017-01-27 00:07:31.945167 // 2016-03-14 00:00:00.000 // 2014-05-11 08:20:13,787 + // 2017-07-19 03:21:51+00:00 // 2006-01-02 // 2013-04-01 22:43:22 // 2014-04-26 05:24:37 PM @@ -132,18 +139,31 @@ iterRunes: case r == 'T': state = ST_DIGITDASHT } - case ST_DIGITDASHWS: // starts digit then dash 02- then whitespace + case ST_DIGITDASHWS: // 2013-04-01 22:43:22 // 2014-05-11 08:20:13,787 - // 2014-04-26 05:24:37 PM - // 2014-12-16 06:20:00 UTC - // 2015-02-18 00:12:00 +0000 UTC - // 2015-06-25 01:25:37.115208593 +0000 UTC + // ST_DIGITDASHWSWS + // 2014-04-26 05:24:37 PM + // 2014-12-16 06:20:00 UTC + // 2015-02-18 00:12:00 +0000 UTC + // 2006-01-02 15:04:05 -0700 + // 2006-01-02 15:04:05 -07:00 + // ST_DIGITDASHWSOFFSET + // 2017-07-19 03:21:51+00:00 + // ST_DIGITDASHWSDOT + // 2014-04-26 17:24:37.3186369 + // 2017-01-27 00:07:31.945167 + // 2012-08-03 18:31:59.257000000 + // 2016-03-14 00:00:00.000 + // ST_DIGITDASHWSDOTOFFSET + // 2017-01-27 00:07:31.945167 +0000 + // 2016-03-14 00:00:00.000 +0000 + // ST_DIGITDASHWSDOTOFFSETALPHA + // 2017-01-27 00:07:31.945167 +0000 UTC + // 2016-03-14 00:00:00.000 +0000 UTC + // ST_DIGITDASHWSDOTALPHA + // 2014-12-16 06:20:00.000 UTC switch r { - case 'A', 'P': - if len(datestr) == len("2014-04-26 03:24:37 PM") { - return time.Parse("2006-01-02 03:04:05 PM", datestr) - } case ',': if len(datestr) == len("2014-05-11 08:20:13,787") { // go doesn't seem to parse this one natively? or did i miss it? @@ -156,38 +176,107 @@ iterRunes: } return t, err } + case '-', '+': + state = ST_DIGITDASHWSOFFSET case '.': state = ST_DIGITDASHWSDOT + case ' ': + state = ST_DIGITDASHWSWS + } + + case ST_DIGITDASHWSWS: + // ST_DIGITDASHWSWSALPHA + // 2014-12-16 06:20:00 UTC + // ST_DIGITDASHWSWSAMPMMAYBE + // 2014-04-26 05:24:37 PM + // ST_DIGITDASHWSWSOFFSET + // 2006-01-02 15:04:05 -0700 + // ST_DIGITDASHWSWSOFFSETCOLON + // 2006-01-02 15:04:05 -07:00 + // ST_DIGITDASHWSWSOFFSETCOLONALPHA + // 2015-02-18 00:12:00 +00:00 UTC + // ST_DIGITDASHWSWSOFFSETALPHA + // 2015-02-18 00:12:00 +0000 UTC + switch r { + case 'A', 'P': + state = ST_DIGITDASHWSWSAMPMMAYBE + case '+', '-': + state = ST_DIGITDASHWSWSOFFSET default: if unicode.IsLetter(r) { // 2014-12-16 06:20:00 UTC - state = ST_DIGITDASHWSALPHA + state = ST_DIGITDASHWSWSALPHA break iterRunes } } + + case ST_DIGITDASHWSWSAMPMMAYBE: + if r == 'M' { + return time.Parse("2006-01-02 03:04:05 PM", datestr) + } + state = ST_DIGITDASHWSWSALPHA + + case ST_DIGITDASHWSWSOFFSET: + // ST_DIGITDASHWSWSOFFSET + // 2006-01-02 15:04:05 -0700 + // ST_DIGITDASHWSWSOFFSETCOLON + // 2006-01-02 15:04:05 -07:00 + // ST_DIGITDASHWSWSOFFSETCOLONALPHA + // 2015-02-18 00:12:00 +00:00 UTC + // ST_DIGITDASHWSWSOFFSETALPHA + // 2015-02-18 00:12:00 +0000 UTC + if r == ':' { + state = ST_DIGITDASHWSWSOFFSETCOLON + } else if unicode.IsLetter(r) { + // 2015-02-18 00:12:00 +0000 UTC + state = ST_DIGITDASHWSWSOFFSETALPHA + break iterRunes + } + + case ST_DIGITDASHWSWSOFFSETCOLON: + // ST_DIGITDASHWSWSOFFSETCOLON + // 2006-01-02 15:04:05 -07:00 + // ST_DIGITDASHWSWSOFFSETCOLONALPHA + // 2015-02-18 00:12:00 +00:00 UTC + if unicode.IsLetter(r) { + // 2015-02-18 00:12:00 +00:00 UTC + state = ST_DIGITDASHWSWSOFFSETCOLONALPHA + break iterRunes + } + case ST_DIGITDASHWSDOT: // 2014-04-26 17:24:37.3186369 // 2017-01-27 00:07:31.945167 // 2012-08-03 18:31:59.257000000 // 2016-03-14 00:00:00.000 + // ST_DIGITDASHWSDOTOFFSET + // 2017-01-27 00:07:31.945167 +0000 + // 2016-03-14 00:00:00.000 +0000 + // ST_DIGITDASHWSDOTOFFSETALPHA + // 2017-01-27 00:07:31.945167 +0000 UTC + // 2016-03-14 00:00:00.000 +0000 UTC + // ST_DIGITDASHWSDOTALPHA + // 2014-12-16 06:20:00.000 UTC if unicode.IsLetter(r) { // 2014-12-16 06:20:00.000 UTC state = ST_DIGITDASHWSDOTALPHA break iterRunes } else if r == '+' || r == '-' { - state = ST_DIGITDASHWSDOTPLUS + state = ST_DIGITDASHWSDOTOFFSET } - case ST_DIGITDASHWSDOTPLUS: - // 2014-04-26 17:24:37.3186369 - // 2017-01-27 00:07:31.945167 - // 2012-08-03 18:31:59.257000000 - // 2016-03-14 00:00:00.000 + case ST_DIGITDASHWSDOTOFFSET: + // 2017-01-27 00:07:31.945167 +0000 + // 2016-03-14 00:00:00.000 +0000 + // ST_DIGITDASHWSDOTOFFSETALPHA + // 2017-01-27 00:07:31.945167 +0000 UTC + // 2016-03-14 00:00:00.000 +0000 UTC if unicode.IsLetter(r) { // 2014-12-16 06:20:00.000 UTC - state = ST_DIGITDASHWSDOTPLUSALPHA + // 2017-01-27 00:07:31.945167 +0000 UTC + // 2016-03-14 00:00:00.000 +0000 UTC + state = ST_DIGITDASHWSDOTOFFSETALPHA break iterRunes } - case ST_DIGITDASHT: // starts digit then dash 02- then T // ST_DIGITDASHT // 2006-01-02T15:04:05 @@ -505,34 +594,49 @@ iterRunes: } case ST_DIGITDASHWS: // starts digit then dash 02- then whitespace 1 << 2 << 5 + 3 // 2013-04-01 22:43:22 + return time.Parse("2006-01-02 15:04:05", datestr) + + case ST_DIGITDASHWSWSOFFSET: // 2006-01-02 15:04:05 -0700 + return time.Parse("2006-01-02 15:04:05 -0700", datestr) + + case ST_DIGITDASHWSWSOFFSETCOLON: // 2006-01-02 15:04:05 -07:00 - switch len(datestr) { - case len("2006-01-02 15:04:05"): - return time.Parse("2006-01-02 15:04:05", datestr) - case len("2006-01-02 15:04:05 -0700"): - return time.Parse("2006-01-02 15:04:05 -0700", datestr) - case len("2006-01-02 15:04:05 -07:00"): - return time.Parse("2006-01-02 15:04:05 -07:00", datestr) - } - case ST_DIGITDASHWSALPHA: // starts digit then dash 02- then whitespace 1 << 2 << 5 + 3 - // 2014-12-16 06:20:00 UTC + return time.Parse("2006-01-02 15:04:05 -07:00", datestr) + + case ST_DIGITDASHWSWSOFFSETALPHA: // 2015-02-18 00:12:00 +0000 UTC - // 2015-06-25 01:25:37.115208593 +0000 UTC - switch len(datestr) { - case len("2006-01-02 15:04:05 UTC"): - t, err := time.Parse("2006-01-02 15:04:05 UTC", datestr) - if err == nil { - return t, nil - } - return time.Parse("2006-01-02 15:04:05 GMT", datestr) - case len("2015-02-18 00:12:00 +0000 UTC"): - t, err := time.Parse("2006-01-02 15:04:05 -0700 UTC", datestr) - if err == nil { - return t, nil - } - return time.Parse("2006-01-02 15:04:05 -0700 GMT", datestr) + t, err := time.Parse("2006-01-02 15:04:05 -0700 UTC", datestr) + if err == nil { + return t, nil } + return time.Parse("2006-01-02 15:04:05 +0000 GMT", datestr) + + case ST_DIGITDASHWSWSOFFSETCOLONALPHA: + // 2015-02-18 00:12:00 +00:00 UTC + return time.Parse("2006-01-02 15:04:05 -07:00 UTC", datestr) + + case ST_DIGITDASHWSOFFSET: + // 2017-07-19 03:21:51+00:00 + return time.Parse("2006-01-02 15:04:05-07:00", datestr) + + case ST_DIGITDASHWSWSALPHA: + // 2014-12-16 06:20:00 UTC + t, err := time.Parse("2006-01-02 15:04:05 UTC", datestr) + if err == nil { + return t, nil + } + t, err = time.Parse("2006-01-02 15:04:05 GMT", datestr) + if err == nil { + return t, nil + } + if len(datestr) > len("2006-01-02 03:04:05") { + t, err = time.Parse("2006-01-02 03:04:05", datestr[:len("2006-01-02 03:04:05")]) + if err == nil { + return t, nil + } + } + case ST_DIGITDASHWSDOT: // 2012-08-03 18:31:59.257000000 // 2014-04-26 17:24:37.3186369 @@ -547,23 +651,19 @@ iterRunes: // 2016-03-14 00:00:00.000 UTC return time.Parse("2006-01-02 15:04:05 UTC", datestr) - case ST_DIGITDASHWSDOTPLUS: + case ST_DIGITDASHWSDOTOFFSET: // 2012-08-03 18:31:59.257000000 +0000 // 2014-04-26 17:24:37.3186369 +0000 // 2017-01-27 00:07:31.945167 +0000 // 2016-03-14 00:00:00.000 +0000 return time.Parse("2006-01-02 15:04:05 -0700", datestr) - case ST_DIGITDASHWSDOTPLUSALPHA: + case ST_DIGITDASHWSDOTOFFSETALPHA: // 2012-08-03 18:31:59.257000000 +0000 UTC // 2014-04-26 17:24:37.3186369 +0000 UTC // 2017-01-27 00:07:31.945167 +0000 UTC // 2016-03-14 00:00:00.000 +0000 UTC return time.Parse("2006-01-02 15:04:05 -0700 UTC", datestr) - // if err == nil { - // return t, nil - // } - // return time.Parse("2006-01-02 15:04:05 -0700 GMT", datestr) case ST_ALPHAWSALPHACOLON: // Mon Jan _2 15:04:05 2006 diff --git a/parseany_test.go b/parseany_test.go index 19f4887..2b4e432 100644 --- a/parseany_test.go +++ b/parseany_test.go @@ -169,13 +169,6 @@ func TestParse(t *testing.T) { ts = MustParse("12 Feb 2006, 19:17:22") assert.Equal(t, "2006-02-12 19:17:22 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC))) - ts = MustParse("2015-02-18 00:12:00 +0000 GMT") - assert.Equal(t, "2015-02-18 00:12:00 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC))) - - // Golang Native Format - ts = MustParse("2015-02-18 00:12:00 +0000 UTC") - assert.Equal(t, "2015-02-18 00:12:00 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC))) - //--------------------------------------------- // mm/dd/yyyy ? @@ -377,6 +370,19 @@ func TestParse(t *testing.T) { ts = MustParse("2014-04-26 17:24:37.123456 -0800") assert.Equal(t, "2014-04-27 01:24:37.123456 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC))) + ts = MustParse("2017-07-19 03:21:51+00:00") + assert.Equal(t, "2017-07-19 03:21:51 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC))) + + ts = MustParse("2017-07-19 03:21:51 +00:00 UTC") + assert.Equal(t, "2017-07-19 03:21:51 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC))) + + ts = MustParse("2015-02-18 00:12:00 +0000 GMT") + assert.Equal(t, "2015-02-18 00:12:00 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC))) + + // Golang Native Format + ts = MustParse("2015-02-18 00:12:00 +0000 UTC") + assert.Equal(t, "2015-02-18 00:12:00 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC))) + ts = MustParse("2014-12-16 06:20:00 UTC") assert.Equal(t, "2014-12-16 06:20:00 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC))) @@ -389,6 +395,10 @@ func TestParse(t *testing.T) { ts = MustParse("2014-04-26 05:24:37 PM") assert.Equal(t, "2014-04-26 17:24:37 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC))) + // This one is pretty special, it is TIMEZONE based but starts with P to emulate collions with PM + ts = MustParse("2014-04-26 05:24:37 PST") + assert.Equal(t, "2014-04-26 05:24:37 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC))) + ts = MustParse("2014-04-26") assert.Equal(t, "2014-04-26 00:00:00 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))