100% test coverage and simplification

This commit is contained in:
Aaron Raddon 2017-07-13 19:57:15 -07:00
parent 13f5ac295e
commit b2d4996d99
4 changed files with 332 additions and 445 deletions

14
.travis.yml Normal file
View File

@ -0,0 +1,14 @@
language: go
go:
- 1.8.x
- tip
before_install:
- go get -t -v ./...
script:
- go test -race -coverprofile=coverage.txt -covermode=atomic
after_success:
- bash <(curl -s https://codecov.io/bash)

View File

@ -6,6 +6,8 @@ a Scan/Lex based approach to minimize shotgun based parse attempts.
See [bench_test.go](https://github.com/araddon/dateparse/blob/master/bench_test.go) for performance comparison. See [bench_test.go](https://github.com/araddon/dateparse/blob/master/bench_test.go) for performance comparison.
[![Codecov](https://img.shields.io/codecov/c/github/araddon/dateparse.svg)]()
See example https://github.com/araddon/dateparse/blob/master/example/main.go See example https://github.com/araddon/dateparse/blob/master/example/main.go
```go ```go
package main package main

View File

@ -5,7 +5,6 @@ import (
"strconv" "strconv"
"time" "time"
"unicode" "unicode"
"unicode/utf8"
) )
type DateState int type DateState int
@ -36,8 +35,6 @@ const (
ST_DIGITDASHTZ ST_DIGITDASHTZ
ST_DIGITDASHTZDIGIT ST_DIGITDASHTZDIGIT
ST_DIGITDASHTDELTA ST_DIGITDASHTDELTA
ST_DIGITCOMMA
ST_DIGITCOLON
ST_DIGITSLASH ST_DIGITSLASH
ST_DIGITSLASHWS ST_DIGITSLASHWS
ST_DIGITSLASHWSCOLON ST_DIGITSLASHWSCOLON
@ -55,8 +52,6 @@ const (
ST_ALPHAWSALPHACOLONALPHAOFFSET ST_ALPHAWSALPHACOLONALPHAOFFSET
ST_ALPHAWSALPHACOLONALPHAOFFSETALPHA ST_ALPHAWSALPHACOLONALPHAOFFSETALPHA
ST_ALPHACOMMA ST_ALPHACOMMA
ST_ALPHACOMMADASH
ST_ALPHACOMMADASHDASH
ST_WEEKDAYCOMMA ST_WEEKDAYCOMMA
ST_WEEKDAYCOMMADELTA ST_WEEKDAYCOMMADELTA
ST_WEEKDAYABBREVCOMMA ST_WEEKDAYABBREVCOMMA
@ -65,8 +60,6 @@ const (
var ( var (
shortDates = []string{"01/02/2006", "1/2/2006", "06/01/02", "01/02/06", "1/2/06"} shortDates = []string{"01/02/2006", "1/2/2006", "06/01/02", "01/02/06", "1/2/06"}
//weekdays = map[string]bool{"Monday": true, "Tuesday": true, "Wednesday": true, "Thursday": true, "Friday": true, "Saturday": true, "Sunday": true}
//weekdayAbbrev = map[string]bool{"Mon": true, "Tue": true, "Wed": true, "Thu": true, "Fri": true, "Sat": true, "Sun": true}
) )
// Parse a date, and panic if it can't be parsed // Parse a date, and panic if it can't be parsed
@ -91,10 +84,11 @@ func ParseAny(datestr string) (time.Time, error) {
// we figure it out and then attempt a parse // we figure it out and then attempt a parse
iterRunes: iterRunes:
for i := 0; i < len(datestr); i++ { for i := 0; i < len(datestr); i++ {
r, bytesConsumed := utf8.DecodeRuneInString(datestr[i:]) r := rune(datestr[i])
if bytesConsumed > 1 { // r, bytesConsumed := utf8.DecodeRuneInString(datestr[ri:])
i += (bytesConsumed - 1) // if bytesConsumed > 1 {
} // ri += (bytesConsumed - 1)
// }
switch state { switch state {
case ST_START: case ST_START:
@ -111,12 +105,8 @@ iterRunes:
continue continue
} }
switch r { switch r {
case ',': case '-', '\u2212':
state = ST_DIGITCOMMA
case '-':
state = ST_DIGITDASH state = ST_DIGITDASH
case ':':
state = ST_DIGITCOLON
case '/': case '/':
state = ST_DIGITSLASH state = ST_DIGITSLASH
firstSlash = i firstSlash = i
@ -149,24 +139,19 @@ iterRunes:
switch r { switch r {
case 'A', 'P': case 'A', 'P':
if len(datestr) == len("2014-04-26 03:24:37 PM") { if len(datestr) == len("2014-04-26 03:24:37 PM") {
if t, err := time.Parse("2006-01-02 03:04:05 PM", datestr); err == nil { return time.Parse("2006-01-02 03:04:05 PM", datestr)
return t, nil
} else {
return time.Time{}, err
}
} }
case ',': case ',':
if len(datestr) == len("2014-05-11 08:20:13,787") { 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? // go doesn't seem to parse this one natively? or did i miss it?
if t, err := time.Parse("2006-01-02 03:04:05", datestr[:i]); err == nil { t, err := time.Parse("2006-01-02 03:04:05", datestr[:i])
if err == nil {
ms, err := strconv.Atoi(datestr[i+1:]) ms, err := strconv.Atoi(datestr[i+1:])
if err == nil { if err == nil {
return time.Unix(0, t.UnixNano()+int64(ms)*1e6), nil return time.Unix(0, t.UnixNano()+int64(ms)*1e6), nil
} }
return time.Time{}, err
} else {
return time.Time{}, err
} }
return t, err
} }
case '.': case '.':
state = ST_DIGITDASHWSDOT state = ST_DIGITDASHWSDOT
@ -220,10 +205,10 @@ iterRunes:
// ST_DIGITDASHTDASH // ST_DIGITDASHTDASH
// 2017-06-25T17:46:57.45706582-07:00 // 2017-06-25T17:46:57.45706582-07:00
// 2017-06-25T17:46:57+04:00 // 2017-06-25T17:46:57+04:00
switch { switch r {
case r == '-', r == '+': case '-', '+':
state = ST_DIGITDASHTDELTA state = ST_DIGITDASHTDELTA
case r == 'Z': case 'Z':
state = ST_DIGITDASHTZ state = ST_DIGITDASHTZ
} }
case ST_DIGITDASHTZ: case ST_DIGITDASHTZ:
@ -289,7 +274,6 @@ iterRunes:
return time.Parse("02 Jan 2006, 15:04", datestr) return time.Parse("02 Jan 2006, 15:04", datestr)
case len(datestr) == len("02 Jan 2006, 15:04:05"): case len(datestr) == len("02 Jan 2006, 15:04:05"):
return time.Parse("02 Jan 2006, 15:04:05", datestr) return time.Parse("02 Jan 2006, 15:04:05", datestr)
default:
} }
case ST_ALPHA: // starts alpha case ST_ALPHA: // starts alpha
// ST_ALPHAWS // ST_ALPHAWS
@ -338,7 +322,7 @@ iterRunes:
state = ST_WEEKDAYCOMMADELTA state = ST_WEEKDAYCOMMADELTA
} }
case r == '+': case r == '+':
state = ST_WEEKDAYABBREVCOMMADELTA state = ST_WEEKDAYCOMMADELTA
} }
case ST_WEEKDAYABBREVCOMMA: // Starts alpha then comma case ST_WEEKDAYABBREVCOMMA: // Starts alpha then comma
// Mon, 02-Jan-06 15:04:05 MST // Mon, 02-Jan-06 15:04:05 MST
@ -369,19 +353,6 @@ iterRunes:
case unicode.IsDigit(r): case unicode.IsDigit(r):
state = ST_ALPHAWSDIGITCOMMA state = ST_ALPHAWSDIGITCOMMA
} }
case ST_ALPHACOMMA: // Starts alpha then comma
// Mon, 02 Jan 2006 15:04:05 MST
// Mon, 02 Jan 2006 15:04:05 -0700
switch {
case r == '-':
state = ST_ALPHACOMMADASH
}
case ST_ALPHACOMMADASH: // Starts alpha then comma and one dash
// Mon, 02 Jan 2006 15:04:05 -0700
switch {
case r == '-':
state = ST_ALPHACOMMADASHDASH
}
case ST_ALPHAWSDIGITCOMMA: // Starts Alpha, whitespace, digit, comma case ST_ALPHAWSDIGITCOMMA: // Starts Alpha, whitespace, digit, comma
// May 8, 2009 5:57:51 PM // May 8, 2009 5:57:51 PM
@ -428,29 +399,24 @@ iterRunes:
switch state { switch state {
case ST_DIGIT: case ST_DIGIT:
// unixy timestamps ish // unixy timestamps ish
// 13980450781991351 nanoseconds // 1499979655583057426 nanoseconds
// 13980450781991 microseconds // 1499979795437000 micro-seconds
// 1499979795437 milliseconds
// 1384216367189 // 1384216367189
// 1332151919 seconds // 1332151919 seconds
// 20140601 yyyymmdd // 20140601 yyyymmdd
// 2014 yyyy // 2014 yyyy
if len(datestr) >= len("13980450781991351") { if len(datestr) > len("1499979795437000") {
if nanoSecs, err := strconv.ParseInt(datestr, 10, 64); err == nil { if nanoSecs, err := strconv.ParseInt(datestr, 10, 64); err == nil {
return time.Unix(0, nanoSecs), nil return time.Unix(0, nanoSecs), nil
} else {
return time.Time{}, err
} }
} else if len(datestr) >= len("13980450781991") { } else if len(datestr) > len("1499979795437") {
if microSecs, err := strconv.ParseInt(datestr, 10, 64); err == nil { if microSecs, err := strconv.ParseInt(datestr, 10, 64); err == nil {
return time.Unix(0, microSecs*1000), nil return time.Unix(0, microSecs*1000), nil
} else {
return time.Time{}, err
} }
} else if len(datestr) >= len("1384216367189") { } else if len(datestr) > len("1332151919") {
if miliSecs, err := strconv.ParseInt(datestr, 10, 64); err == nil { if miliSecs, err := strconv.ParseInt(datestr, 10, 64); err == nil {
return time.Unix(0, miliSecs*1000*1000), nil return time.Unix(0, miliSecs*1000*1000), nil
} else {
return time.Time{}, err
} }
} else if len(datestr) == len("20140601") { } else if len(datestr) == len("20140601") {
return time.Parse("20060102", datestr) return time.Parse("20060102", datestr)
@ -459,8 +425,6 @@ iterRunes:
} else { } else {
if secs, err := strconv.ParseInt(datestr, 10, 64); err == nil { if secs, err := strconv.ParseInt(datestr, 10, 64); err == nil {
return time.Unix(secs, 0), nil return time.Unix(secs, 0), nil
} else {
return time.Time{}, err
} }
} }
case ST_DIGITDASH: // starts digit then dash 02- case ST_DIGITDASH: // starts digit then dash 02-
@ -482,17 +446,20 @@ iterRunes:
// 2006-01-02T15:04:05+07:00 // 2006-01-02T15:04:05+07:00
// 2006-01-02T15:04:05-07:00 // 2006-01-02T15:04:05-07:00
return time.Parse("2006-01-02T15:04:05-07:00", datestr) return time.Parse("2006-01-02T15:04:05-07:00", datestr)
case ST_DIGITDASHTZDIGIT:
// With a time-zone at end after Z
// 2006-01-02T15:04:05.999999999Z07:00
// 2006-01-02T15:04:05Z07:00
if len(datestr) == len("2006-01-02T15:04:05Z07:00") {
return time.Parse("2006-01-02T15:04:05Z07:00", datestr)
}
case ST_DIGITDASHT: // starts digit then dash 02- then T case ST_DIGITDASHT: // starts digit then dash 02- then T
// 2006-01-02T15:04:05.999999 // 2006-01-02T15:04:05.999999
// 2006-01-02T15:04:05.999999 // 2006-01-02T15:04:05.999999
return time.Parse("2006-01-02T15:04:05", datestr) return time.Parse("2006-01-02T15:04:05", datestr)
case ST_DIGITDASHTZDIGIT:
// With a time-zone at end after Z
// 2006-01-02T15:04:05.999999999Z07:00
// 2006-01-02T15:04:05Z07:00
// RFC3339 = "2006-01-02T15:04:05Z07:00"
// RFC3339Nano = "2006-01-02T15:04:05.999999999Z07:00"
return time.Time{}, fmt.Errorf("RFC339 Dates may not contain both Z & Offset for %q see https://github.com/golang/go/issues/5294", datestr)
case ST_DIGITDASHTZ: // starts digit then dash 02- then T Then Z case ST_DIGITDASHTZ: // starts digit then dash 02- then T Then Z
// 2006-01-02T15:04:05.999999999Z // 2006-01-02T15:04:05.999999999Z
// 2006-01-02T15:04:05.99999999Z // 2006-01-02T15:04:05.99999999Z
@ -565,11 +532,11 @@ iterRunes:
// 2014-04-26 17:24:37.3186369 +0000 UTC // 2014-04-26 17:24:37.3186369 +0000 UTC
// 2017-01-27 00:07:31.945167 +0000 UTC // 2017-01-27 00:07:31.945167 +0000 UTC
// 2016-03-14 00:00:00.000 +0000 UTC // 2016-03-14 00:00:00.000 +0000 UTC
t, err := time.Parse("2006-01-02 15:04:05 -0700 UTC", datestr) return time.Parse("2006-01-02 15:04:05 -0700 UTC", datestr)
if err == nil { // if err == nil {
return t, nil // return t, nil
} // }
return time.Parse("2006-01-02 15:04:05 -0700 GMT", datestr) // return time.Parse("2006-01-02 15:04:05 -0700 GMT", datestr)
case ST_ALPHAWSALPHACOLON: case ST_ALPHAWSALPHACOLON:
// Mon Jan _2 15:04:05 2006 // Mon Jan _2 15:04:05 2006
@ -612,8 +579,6 @@ iterRunes:
return t, nil return t, nil
} }
} }
return time.Time{}, fmt.Errorf("Unrecognized dateformat: %v", datestr)
} }
case ST_DIGITSLASHWSCOLON: // starts digit then slash 02/ more digits/slashes then whitespace case ST_DIGITSLASHWSCOLON: // starts digit then slash 02/ more digits/slashes then whitespace
@ -622,77 +587,43 @@ iterRunes:
// 2014/4/8 22:05 // 2014/4/8 22:05
// 2014/04/08 22:05 // 2014/04/08 22:05
var t time.Time
var err error
if firstSlash == 4 { if firstSlash == 4 {
switch len(datestr) { for _, layout := range []string{"2006/01/02 15:04", "2006/1/2 15:04", "2006/01/2 15:04", "2006/1/02 15:04"} {
case len("2006/01/02 15:04"): if t, err := time.Parse(layout, datestr); err == nil {
t, err = time.Parse("2006/01/02 15:04", datestr)
case len("2006/01/2 15:04"):
if t, err = time.Parse("2006/01/2 15:04", datestr); err != nil {
t, err = time.Parse("2006/1/02 15:04", datestr)
} else if t, err = time.Parse("2006/1/02 15:04", datestr); err != nil {
t, err = time.Parse("2006/1/02 15:04", datestr)
}
default:
t, err = time.Parse("2006/1/2 15:04", datestr)
}
} else {
switch len(datestr) {
case len("01/02/2006 15:04"):
t, err = time.Parse("01/02/2006 15:04", datestr)
case len("01/2/2006 15:04"):
if t, err = time.Parse("01/2/2006 15:04", datestr); err != nil {
t, err = time.Parse("1/02/2006 15:04", datestr)
} else if t, err = time.Parse("1/02/2006 15:04", datestr); err != nil {
t, err = time.Parse("1/02/2006 15:04", datestr)
}
default:
t, err = time.Parse("1/2/2006 15:04", datestr)
}
}
if err == nil {
return t, nil return t, nil
} }
return time.Time{}, err }
} else {
for _, layout := range []string{"01/02/2006 15:04", "01/2/2006 15:04", "1/02/2006 15:04", "1/2/2006 15:04"} {
if t, err := time.Parse(layout, datestr); err == nil {
return t, nil
}
}
}
case ST_DIGITSLASHWSCOLONAMPM: // starts digit then slash 02/ more digits/slashes then whitespace case ST_DIGITSLASHWSCOLONAMPM: // starts digit then slash 02/ more digits/slashes then whitespace
// 4/8/2014 22:05 PM // 4/8/2014 22:05 PM
// 04/08/2014 22:05 PM // 04/08/2014 22:05 PM
// 04/08/2014 1:05 PM
// 2014/4/8 22:05 PM // 2014/4/8 22:05 PM
// 2014/04/08 22:05 PM // 2014/04/08 22:05 PM
var t time.Time
var err error
if firstSlash == 4 { if firstSlash == 4 {
switch len(datestr) { for _, layout := range []string{"2006/01/02 03:04 PM", "2006/01/2 03:04 PM", "2006/1/02 03:04 PM", "2006/1/2 03:04 PM",
case len("2006/01/02 15:04 PM"): "2006/01/02 3:04 PM", "2006/01/2 3:04 PM", "2006/1/02 3:04 PM", "2006/1/2 3:04 PM"} {
t, err = time.Parse("2006/01/02 03:04 PM", datestr) if t, err := time.Parse(layout, datestr); err == nil {
case len("2006/01/2 15:04 PM"):
if t, err = time.Parse("2006/01/2 03:04 PM", datestr); err != nil {
t, err = time.Parse("2006/1/02 03:04 PM", datestr)
}
default:
t, err = time.Parse("2006/1/2 03:04 PM", datestr)
}
} else {
switch len(datestr) {
case len("01/02/2006 15:04 PM"):
t, err = time.Parse("01/02/2006 03:04 PM", datestr)
case len("01/2/2006 15:04 PM"):
if t, err = time.Parse("01/2/2006 03:04 PM", datestr); err != nil {
t, err = time.Parse("1/02/2006 03:04 PM", datestr)
}
default:
t, err = time.Parse("1/2/2006 3:04 PM", datestr)
}
}
if err == nil {
return t, nil return t, nil
} }
return time.Time{}, err }
} else {
for _, layout := range []string{"01/02/2006 03:04 PM", "01/2/2006 03:04 PM", "1/02/2006 03:04 PM", "1/2/2006 03:04 PM",
"01/02/2006 3:04 PM", "01/2/2006 3:04 PM", "1/02/2006 3:04 PM", "1/2/2006 3:04 PM"} {
if t, err := time.Parse(layout, datestr); err == nil {
return t, nil
}
}
}
case ST_DIGITSLASHWSCOLONCOLON: // starts digit then slash 02/ more digits/slashes then whitespace double colons case ST_DIGITSLASHWSCOLONCOLON: // starts digit then slash 02/ more digits/slashes then whitespace double colons
// 2014/07/10 06:55:38.156283 // 2014/07/10 06:55:38.156283
@ -700,41 +631,19 @@ iterRunes:
// 3/1/2012 10:11:59 // 3/1/2012 10:11:59
// 03/1/2012 10:11:59 // 03/1/2012 10:11:59
// 3/01/2012 10:11:59 // 3/01/2012 10:11:59
var t time.Time
var err error
if firstSlash == 4 { if firstSlash == 4 {
switch len(datestr) { for _, layout := range []string{"2006/01/02 15:04:05", "2006/1/02 15:04:05", "2006/01/2 15:04:05", "2006/1/2 15:04:05"} {
case len("2014/07/10 06:55:38.156283"): if t, err := time.Parse(layout, datestr); err == nil {
t, err = time.Parse("2006/01/02 15:04:05.000000", datestr)
case len("2006/01/02 15:04:05"):
t, err = time.Parse("2006/01/02 15:04:05", datestr)
case len("2006/01/2 15:04:05"):
if t, err = time.Parse("2006/01/2 15:04:05", datestr); err != nil {
t, err = time.Parse("2006/1/02 15:04:05", datestr)
}
default:
t, err = time.Parse("2006/1/2 15:04:05", datestr)
}
} else {
switch len(datestr) {
case len("07/10/2014 06:55:38.156283"):
t, err = time.Parse("01/02/2006 15:04:05.000000", datestr)
case len("01/02/2006 15:04:05"):
t, err = time.Parse("01/02/2006 15:04:05", datestr)
case len("01/2/2006 15:04:05"):
if t, err = time.Parse("01/2/2006 15:04:05", datestr); err != nil {
t, err = time.Parse("1/02/2006 15:04:05", datestr)
}
default:
t, err = time.Parse("1/2/2006 15:04:05", datestr)
}
}
if err == nil {
return t, nil return t, nil
} }
return time.Time{}, err }
} else {
for _, layout := range []string{"01/02/2006 15:04:05", "1/02/2006 15:04:05", "01/2/2006 15:04:05", "1/2/2006 15:04:05"} {
if t, err := time.Parse(layout, datestr); err == nil {
return t, nil
}
}
}
case ST_DIGITSLASHWSCOLONCOLONAMPM: // starts digit then slash 02/ more digits/slashes then whitespace double colons case ST_DIGITSLASHWSCOLONCOLONAMPM: // starts digit then slash 02/ more digits/slashes then whitespace double colons
// 2014/07/10 06:55:38.156283 PM // 2014/07/10 06:55:38.156283 PM
@ -743,40 +652,20 @@ iterRunes:
// 03/1/2012 10:11:59 PM // 03/1/2012 10:11:59 PM
// 3/01/2012 10:11:59 PM // 3/01/2012 10:11:59 PM
var t time.Time
var err error
if firstSlash == 4 { if firstSlash == 4 {
switch len(datestr) { for _, layout := range []string{"2006/01/02 03:04:05 PM", "2006/1/02 03:04:05 PM", "2006/01/2 03:04:05 PM", "2006/1/2 03:04:05 PM",
case len("2014/07/10 06:55:38.156283 PM"): "2006/01/02 3:04:05 PM", "2006/1/02 3:04:05 PM", "2006/01/2 3:04:05 PM", "2006/1/2 3:04:05 PM"} {
t, err = time.Parse("2006/01/02 03:04:05.000000 PM", datestr) if t, err := time.Parse(layout, datestr); err == nil {
case len("2006/01/02 15:04:05 PM"):
t, err = time.Parse("2006/01/02 03:04:05 PM", datestr)
case len("2006/01/2 15:04:05 PM"):
if t, err = time.Parse("2006/01/2 03:04:05 PM", datestr); err != nil {
t, err = time.Parse("2006/1/02 03:04:05 PM", datestr)
}
default:
t, err = time.Parse("2006/1/2 03:04:05 PM", datestr)
}
} else {
switch len(datestr) {
case len("07/10/2014 06:55:38.156283 PM"):
t, err = time.Parse("01/02/2006 03:04:05.000000 PM", datestr)
case len("01/02/2006 15:04:05 PM"):
t, err = time.Parse("01/02/2006 03:04:05 PM", datestr)
case len("01/2/2006 15:04:05 PM"):
if t, err = time.Parse("01/2/2006 03:04:05 PM", datestr); err != nil {
t, err = time.Parse("1/02/2006 03:04:05 PM", datestr)
}
default:
t, err = time.Parse("1/2/2006 03:04:05 PM", datestr)
}
}
if err == nil {
return t, nil return t, nil
} }
return time.Time{}, err }
} else {
for _, layout := range []string{"01/02/2006 03:04:05 PM", "1/02/2006 03:04:05 PM", "01/2/2006 03:04:05 PM", "1/2/2006 03:04:05 PM"} {
if t, err := time.Parse(layout, datestr); err == nil {
return t, nil
}
}
}
case ST_WEEKDAYCOMMADELTA: case ST_WEEKDAYCOMMADELTA:
// Monday, 02 Jan 2006 15:04:05 -0700 // Monday, 02 Jan 2006 15:04:05 -0700
@ -789,22 +678,8 @@ iterRunes:
case ST_WEEKDAYABBREVCOMMADELTA: case ST_WEEKDAYABBREVCOMMADELTA:
// Mon, 02 Jan 2006 15:04:05 -0700 // Mon, 02 Jan 2006 15:04:05 -0700
// Thu, 13 Jul 2017 08:58:40 +0100 // Thu, 13 Jul 2017 08:58:40 +0100
return time.Parse("Mon, 02 Jan 2006 15:04:05 -0700", datestr)
case ST_ALPHACOMMA: // Starts alpha then comma but no DASH
// Mon, 02 Jan 2006 15:04:05 MST
// Jan 2, 2006 3:04:05 PM
return time.Parse("Jan 2, 2006 3:04:05 PM", datestr)
case ST_ALPHACOMMADASH: // Starts alpha then comma and one dash
// Mon, 02 Jan 2006 15:04:05 -0700
// RFC1123Z = "Mon, 02 Jan 2006 15:04:05 -0700" // RFC1123 with numeric zone // RFC1123Z = "Mon, 02 Jan 2006 15:04:05 -0700" // RFC1123 with numeric zone
// TODO: this doesn't work??? return time.Parse("Mon, 02 Jan 2006 15:04:05 -0700", datestr)
return time.Parse(time.RFC1123Z, datestr)
case ST_ALPHACOMMADASHDASH: // Starts alpha then comma and two dash'es
// Monday, 02-Jan-06 15:04:05 MST
return time.Parse("Monday, 02-Jan-06 15:04:05 MST", datestr)
} }
return time.Time{}, fmt.Errorf("Could not find date format for %s", datestr) return time.Time{}, fmt.Errorf("Could not find date format for %s", datestr)

View File

@ -2,9 +2,10 @@ package dateparse
import ( import (
"fmt" "fmt"
"runtime"
"testing" "testing"
"time" "time"
"github.com/stretchr/testify/assert"
) )
/* /*
@ -52,33 +53,19 @@ import (
2006 2006
*/ */
func tt(t *testing.T, result bool, cd int, args ...interface{}) { func testMust() (err error) {
fn := func() { defer func() {
t.Errorf("! Failure") if r := recover(); r != nil {
if len(args) > 0 { err = fmt.Errorf("yes, paniced %v", r)
t.Error("!", " -", fmt.Sprint(args...))
}
}
if !result {
_, file, line, _ := runtime.Caller(cd + 1)
t.Errorf("%s:%d", file, line)
fn()
t.FailNow()
} }
}()
MustParse("NOT GONNA HAPPEN")
return nil
} }
func assert(t *testing.T, result bool, v ...interface{}) {
tt(t, result, 1, v...)
}
func assertf(t *testing.T, result bool, f string, v ...interface{}) {
tt(t, result, 1, fmt.Sprintf(f, v...))
}
func TestParse(t *testing.T) { func TestParse(t *testing.T) {
mstZone, err := time.LoadLocation("America/Denver") mstZone, err := time.LoadLocation("America/Denver")
assert(t, err == nil) assert.Equal(t, nil, err)
n := time.Now() n := time.Now()
if fmt.Sprintf("%v", n) == fmt.Sprintf("%v", n.In(mstZone)) { if fmt.Sprintf("%v", n) == fmt.Sprintf("%v", n.In(mstZone)) {
t.Logf("you are testing and in MST %v", mstZone) t.Logf("you are testing and in MST %v", mstZone)
@ -86,18 +73,25 @@ func TestParse(t *testing.T) {
zeroTime := time.Time{}.Unix() zeroTime := time.Time{}.Unix()
ts, err := ParseAny("INVALID") ts, err := ParseAny("INVALID")
assert(t, ts.Unix() == zeroTime) assert.Equal(t, zeroTime, ts.Unix())
assert(t, err != nil) assert.NotEqual(t, nil, err)
ts, err = ParseAny("May 8, 2009 5:57:51 PM") err = testMust()
assert(t, "2009-05-08 17:57:51 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC))) assert.NotEqual(t, nil, err)
// TODO: Is a utf8 date valid?
// ts = MustParse("2014-04\u221226")
// assert.Equal(t, "2014-04-26 00:00:00 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
ts = MustParse("May 8, 2009 5:57:51 PM")
assert.Equal(t, "2009-05-08 17:57:51 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
// ANSIC = "Mon Jan _2 15:04:05 2006" // ANSIC = "Mon Jan _2 15:04:05 2006"
ts, err = ParseAny("Mon Jan 2 15:04:05 2006") ts = MustParse("Mon Jan 2 15:04:05 2006")
assert(t, "2006-01-02 15:04:05 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC))) assert.Equal(t, "2006-01-02 15:04:05 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
// UnixDate = "Mon Jan _2 15:04:05 MST 2006" // UnixDate = "Mon Jan _2 15:04:05 MST 2006"
ts, err = ParseAny("Mon Jan 2 15:04:05 MST 2006") ts = MustParse("Mon Jan 2 15:04:05 MST 2006")
// The time-zone of local machine appears to effect the results? // The time-zone of local machine appears to effect the results?
// Why is the zone/offset for MST not always the same depending on local time zone? // Why is the zone/offset for MST not always the same depending on local time zone?
// Why is offset = 0 at all? // Why is offset = 0 at all?
@ -106,334 +100,336 @@ func TestParse(t *testing.T) {
_, offset := ts.Zone() _, offset := ts.Zone()
// WHY doesn't this work? seems to be underlying issue in go not finding // WHY doesn't this work? seems to be underlying issue in go not finding
// the MST? // the MST?
//assert(t, offset != 0, "Should have found zone/offset !=0 ", offset) //assert.Equal(t, offset != 0, "Should have found zone/offset !=0 ", offset)
if offset == 0 { if offset == 0 {
assert(t, "2006-01-02 15:04:05 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC))) assert.Equal(t, "2006-01-02 15:04:05 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
} else { } else {
// for some reason i don't understand the offset is != 0 // for some reason i don't understand the offset is != 0
// IF you have your local time-zone set to US MST? // IF you have your local time-zone set to US MST?
assert(t, "2006-01-02 22:04:05 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC))) assert.Equal(t, "2006-01-02 22:04:05 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
} }
// RubyDate = "Mon Jan 02 15:04:05 -0700 2006" // RubyDate = "Mon Jan 02 15:04:05 -0700 2006"
ts, err = ParseAny("Mon Jan 02 15:04:05 -0700 2006") ts = MustParse("Mon Jan 02 15:04:05 -0700 2006")
assertf(t, "2006-01-02 22:04:05 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)), "%v", ts.In(time.UTC)) assert.Equal(t, "2006-01-02 22:04:05 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)), "%v")
// RFC850 = "Monday, 02-Jan-06 15:04:05 MST" // RFC850 = "Monday, 02-Jan-06 15:04:05 MST"
ts, err = ParseAny("Monday, 02-Jan-06 15:04:05 MST") ts = MustParse("Monday, 02-Jan-06 15:04:05 MST")
_, offset = ts.Zone() _, offset = ts.Zone()
if offset == 0 { if offset == 0 {
assert(t, "2006-01-02 15:04:05 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)), ts.In(time.UTC)) assert.Equal(t, "2006-01-02 15:04:05 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
} else { } else {
assert(t, "2006-01-02 22:04:05 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)), ts.In(time.UTC)) assert.Equal(t, "2006-01-02 22:04:05 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
} }
ts = MustParse("Monday, 02-Jan-06 15:04:05 MST")
assert.Equal(t, "2006-01-02 15:04:05 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
// ST_WEEKDAYCOMMADELTA
// Monday, 02 Jan 2006 15:04:05 -0700
// Monday, 02 Jan 2006 15:04:05 +0100
ts = MustParse("Monday, 02 Jan 2006 15:04:05 +0100")
assert.Equal(t, "2006-01-02 14:04:05 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
ts = MustParse("Monday, 02 Jan 2006 15:04:05 -0100")
assert.Equal(t, "2006-01-02 16:04:05 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
// Another weird one, year on the end after UTC? // Another weird one, year on the end after UTC?
ts, err = ParseAny("Mon Aug 10 15:44:11 UTC+0100 2015") ts = MustParse("Mon Aug 10 15:44:11 UTC+0100 2015")
assert(t, err == nil) assert.Equal(t, "2015-08-10 15:44:11 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2015-08-10 15:44:11 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
// Easily the worst Date format i have ever seen // Easily the worst Date format i have ever seen
// "Fri Jul 03 2015 18:04:07 GMT+0100 (GMT Daylight Time)" // "Fri Jul 03 2015 18:04:07 GMT+0100 (GMT Daylight Time)"
ts, err = ParseAny("Fri Jul 03 2015 18:04:07 GMT+0100 (GMT Daylight Time)") ts = MustParse("Fri Jul 03 2015 18:04:07 GMT+0100 (GMT Daylight Time)")
assert(t, "2015-07-03 17:04:07 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC))) assert.Equal(t, "2015-07-03 17:04:07 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("Mon, 02 Jan 2006 15:04:05 MST") ts = MustParse("Mon, 02 Jan 2006 15:04:05 MST")
assertf(t, err == nil, "%v", err)
_, offset = ts.Zone() _, offset = ts.Zone()
if offset == 0 { if offset == 0 {
assert(t, "2006-01-02 15:04:05 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)), ts.In(time.UTC)) assert.Equal(t, "2006-01-02 15:04:05 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
} else { } else {
assert(t, "2006-01-02 22:04:05 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)), ts.In(time.UTC)) assert.Equal(t, "2006-01-02 22:04:05 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
} }
ts, err = ParseAny("Thu, 13 Jul 2017 08:58:40 +0100") ts = MustParse("Mon, 02-Jan-06 15:04:05 MST")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2006-01-02 15:04:05 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2017-07-13 07:58:40 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("Mon, 02 Jan 2006 15:04:05 -0700") ts = MustParse("Thu, 13 Jul 2017 08:58:40 +0100")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2017-07-13 07:58:40 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2006-01-02 22:04:05 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts = MustParse("Mon, 02 Jan 2006 15:04:05 -0700")
assert.Equal(t, "2006-01-02 22:04:05 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
// not sure if this is anything close to a standard, never seen it before // not sure if this is anything close to a standard, never seen it before
ts, err = ParseAny("12 Feb 2006, 19:17") ts = MustParse("12 Feb 2006, 19:17")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2006-02-12 19:17:00 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2006-02-12 19:17:00 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("2015-02-18 00:12:00 +0000 GMT") ts = MustParse("12 Feb 2006, 19:17:22")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2006-02-12 19:17:22 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2015-02-18 00:12:00 +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 // Golang Native Format
ts, err = ParseAny("2015-02-18 00:12:00 +0000 UTC") ts = MustParse("2015-02-18 00:12:00 +0000 UTC")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2015-02-18 00:12:00 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2015-02-18 00:12:00 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
//--------------------------------------------- //---------------------------------------------
// mm/dd/yyyy ? // mm/dd/yyyy ?
ts, err = ParseAny("3/31/2014") ts = MustParse("3/31/2014")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2014-03-31 00:00:00 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2014-03-31 00:00:00 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("03/31/2014") ts = MustParse("03/31/2014")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2014-03-31 00:00:00 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2014-03-31 00:00:00 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
// what type of date is this? 08/21/71 // what type of date is this? 08/21/71
ts, err = ParseAny("08/21/71") ts = MustParse("08/21/71")
assertf(t, err == nil, "%v", err) assert.Equal(t, "1971-08-21 00:00:00 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "1971-08-21 00:00:00 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
// m/d/yy // m/d/yy
ts, err = ParseAny("8/1/71") ts = MustParse("8/1/71")
assertf(t, err == nil, "%v", err) assert.Equal(t, "1971-08-01 00:00:00 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "1971-08-01 00:00:00 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("4/8/2014 22:05") ts = MustParse("4/8/2014 22:05")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2014-04-08 22:05:00 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2014-04-08 22:05:00 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("04/08/2014 22:05") ts = MustParse("04/08/2014 22:05")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2014-04-08 22:05:00 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2014-04-08 22:05:00 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("04/2/2014 4:00:51") ts = MustParse("04/2/2014 4:00:51")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2014-04-02 04:00:51 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2014-04-02 04:00:51 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("8/8/1965 01:00:01 PM") ts = MustParse("8/8/1965 01:00:01 PM")
assert(t, "1965-08-08 13:00:01 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC))) assert.Equal(t, "1965-08-08 13:00:01 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("8/8/1965 12:00:01 AM") ts = MustParse("8/8/1965 12:00:01 AM")
assert(t, "1965-08-08 00:00:01 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC))) assert.Equal(t, "1965-08-08 00:00:01 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("8/8/1965 01:00 PM") ts = MustParse("8/8/1965 01:00 PM")
assert(t, "1965-08-08 13:00:00 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC))) assert.Equal(t, "1965-08-08 13:00:00 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("8/8/1965 1:00 PM") ts = MustParse("08/8/1965 01:00 PM")
assert(t, "1965-08-08 13:00:00 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC))) assert.Equal(t, "1965-08-08 13:00:00 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("8/8/1965 12:00 AM") ts = MustParse("8/08/1965 1:00 PM")
assert(t, "1965-08-08 00:00:00 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC))) assert.Equal(t, "1965-08-08 13:00:00 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("4/02/2014 03:00:51") ts = MustParse("8/8/1965 12:00 AM")
assertf(t, err == nil, "%v", err) assert.Equal(t, "1965-08-08 00:00:00 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2014-04-02 03:00:51 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("03/19/2012 10:11:59") ts = MustParse("8/13/1965 01:00 PM")
assertf(t, err == nil, "%v", err) assert.Equal(t, "1965-08-13 13:00:00 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2012-03-19 10:11:59 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("03/19/2012 10:11:59.3186369") ts = MustParse("4/02/2014 03:00:51")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2014-04-02 03:00:51 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2012-03-19 10:11:59.3186369 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts = MustParse("03/19/2012 10:11:59")
assert.Equal(t, "2012-03-19 10:11:59 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
ts = MustParse("03/19/2012 10:11:59.3186369")
assert.Equal(t, "2012-03-19 10:11:59.3186369 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
//--------------------------------------------- //---------------------------------------------
// yyyy/mm/dd ? // yyyy/mm/dd ?
ts, err = ParseAny("2014/3/31") ts = MustParse("2014/3/31")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2014-03-31 00:00:00 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2014-03-31 00:00:00 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("2014/03/31") ts = MustParse("2014/03/31")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2014-03-31 00:00:00 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2014-03-31 00:00:00 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("2014/4/8 22:05") ts = MustParse("2014/4/8 22:05")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2014-04-08 22:05:00 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2014-04-08 22:05:00 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("2014/04/08 22:05") ts = MustParse("2014/04/08 22:05")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2014-04-08 22:05:00 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2014-04-08 22:05:00 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("2014/04/2 03:00:51") ts = MustParse("2014/04/2 03:00:51")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2014-04-02 03:00:51 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2014-04-02 03:00:51 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("2014/4/02 03:00:51") ts = MustParse("2014/4/02 03:00:51")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2014-04-02 03:00:51 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2014-04-02 03:00:51 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("2012/03/19 10:11:59") ts = MustParse("2012/03/19 10:11:59")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2012-03-19 10:11:59 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2012-03-19 10:11:59 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("2012/03/19 10:11:59.3186369") ts = MustParse("2012/03/19 10:11:59.318")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2012-03-19 10:11:59.318 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2012-03-19 10:11:59.3186369 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts = MustParse("2012/03/19 10:11:59.3186369")
assert.Equal(t, "2012-03-19 10:11:59.3186369 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
ts = MustParse("2012/03/19 10:11:59.318636945")
assert.Equal(t, "2012-03-19 10:11:59.318636945 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
ts = MustParse("2012/03/19 10:11 PM")
assert.Equal(t, "2012-03-19 22:11:00 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
ts = MustParse("2012/03/19 1:11 PM")
assert.Equal(t, "2012-03-19 13:11:00 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
ts = MustParse("2012/3/19 10:11 PM")
assert.Equal(t, "2012-03-19 22:11:00 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
ts = MustParse("2012/3/3 10:11 PM")
assert.Equal(t, "2012-03-03 22:11:00 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
ts = MustParse("2012/03/19 10:11:59 PM")
assert.Equal(t, "2012-03-19 22:11:59 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
ts = MustParse("2012/3/3 10:11:59 PM")
assert.Equal(t, "2012-03-03 22:11:59 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
ts = MustParse("2012/03/03 10:11:59.345 PM")
assert.Equal(t, "2012-03-03 22:11:59.345 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
//--------------------------------------------- //---------------------------------------------
// yyyy-mm-dd ? // yyyy-mm-dd ?
ts, err = ParseAny("2009-08-12T22:15:09-07:00") ts = MustParse("2009-08-12T22:15:09-07:00")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2009-08-13 05:15:09 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2009-08-13 05:15:09 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("2009-08-12T22:15:09.123-07:00")
assertf(t, err == nil, "%v", err)
assertf(t, "2009-08-13 05:15:09.123 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)), "%v", ts.In(time.UTC))
ts, err = ParseAny("2009-08-12T22:15Z") ts = MustParse("2009-08-12T22:15:09.123-07:00")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2009-08-13 05:15:09.123 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)), "%v", ts.In(time.UTC))
assertf(t, "2009-08-12 22:15:00 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)), "%v", ts.In(time.UTC))
ts, err = ParseAny("2009-08-12T22:15:09Z") ts = MustParse("2009-08-12T22:15Z")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2009-08-12 22:15:00 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)), "%v", ts.In(time.UTC))
assertf(t, "2009-08-12 22:15:09 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)), "%v", ts.In(time.UTC))
ts, err = ParseAny("2009-08-12T22:15:09.99Z") ts = MustParse("2009-08-12T22:15:09Z")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2009-08-12 22:15:09 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)), "%v", ts.In(time.UTC))
assert(t, "2009-08-12 22:15:09.99 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("2009-08-12T22:15:09.9999Z") ts = MustParse("2009-08-12T22:15:09.99Z")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2009-08-12 22:15:09.99 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2009-08-12 22:15:09.9999 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("2009-08-12T22:15:09.99999999Z") ts = MustParse("2009-08-12T22:15:09.9999Z")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2009-08-12 22:15:09.9999 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2009-08-12 22:15:09.99999999 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("2009-08-12T22:15:09.123") ts = MustParse("2009-08-12T22:15:09.99999999Z")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2009-08-12 22:15:09.99999999 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2009-08-12 22:15:09.123 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("2009-08-12T22:15:09.123456")
assertf(t, err == nil, "%v", err)
assert(t, "2009-08-12 22:15:09.123456 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("2009-08-12T22:15:09.12") // https://github.com/golang/go/issues/5294
assertf(t, err == nil, "%v", err) _, err = ParseAny(time.RFC3339)
assert(t, "2009-08-12 22:15:09.12 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC))) assert.NotEqual(t, nil, err)
ts, err = ParseAny("2009-08-12T22:15:09.1") ts = MustParse("2009-08-12T22:15:09.123")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2009-08-12 22:15:09.123 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2009-08-12 22:15:09.1 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("2009-08-12T22:15:09") ts = MustParse("2009-08-12T22:15:09.123456")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2009-08-12 22:15:09.123456 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2009-08-12 22:15:09 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("2014-04-26 17:24:37.3186369") ts = MustParse("2009-08-12T22:15:09.12")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2009-08-12 22:15:09.12 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2014-04-26 17:24:37.3186369 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts = MustParse("2009-08-12T22:15:09.1")
assert.Equal(t, "2009-08-12 22:15:09.1 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
ts = MustParse("2009-08-12T22:15:09")
assert.Equal(t, "2009-08-12 22:15:09 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
ts = MustParse("2014-04-26 17:24:37.3186369")
assert.Equal(t, "2014-04-26 17:24:37.3186369 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
// 2015-06-25 01:25:37.115208593 +0000 UTC // 2015-06-25 01:25:37.115208593 +0000 UTC
ts, err = ParseAny("2012-08-03 18:31:59.257000000 +0000 UTC") ts = MustParse("2012-08-03 18:31:59.257000000 +0000 UTC")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2012-08-03 18:31:59.257 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2012-08-03 18:31:59.257 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("2015-09-30 18:48:56.35272715 +0000 UTC") ts = MustParse("2015-09-30 18:48:56.35272715 +0000 UTC")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2015-09-30 18:48:56.35272715 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2015-09-30 18:48:56.35272715 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("2017-01-27 00:07:31.945167") ts = MustParse("2017-01-27 00:07:31.945167")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2017-01-27 00:07:31.945167 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2017-01-27 00:07:31.945167 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("2012-08-03 18:31:59.257000000") ts = MustParse("2012-08-03 18:31:59.257000000")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2012-08-03 18:31:59.257 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2012-08-03 18:31:59.257 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("2013-04-01 22:43:22") ts = MustParse("2013-04-01 22:43:22")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2013-04-01 22:43:22 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2013-04-01 22:43:22 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("2014-04-26 17:24:37.123") ts = MustParse("2014-04-26 17:24:37.123")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2014-04-26 17:24:37.123 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2014-04-26 17:24:37.123 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("2014-04-26 17:24:37.123456 UTC") ts = MustParse("2014-04-26 17:24:37.123456 +0000 UTC")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2014-04-26 17:24:37.123456 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2014-04-26 17:24:37.123456 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("2014-04-26 17:24:37.123 UTC") ts = MustParse("2014-04-26 17:24:37.123456 UTC")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2014-04-26 17:24:37.123456 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2014-04-26 17:24:37.123 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("2014-04-26 17:24:37.12 UTC") ts = MustParse("2014-04-26 17:24:37.123 UTC")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2014-04-26 17:24:37.123 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2014-04-26 17:24:37.12 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("2014-04-26 17:24:37.1 UTC") ts = MustParse("2014-04-26 17:24:37.12 UTC")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2014-04-26 17:24:37.12 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2014-04-26 17:24:37.1 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("2014-04-26 17:24:37.123 +0800") ts = MustParse("2014-04-26 17:24:37.1 UTC")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2014-04-26 17:24:37.1 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2014-04-26 09:24:37.123 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("2014-04-26 17:24:37.123 -0800") ts = MustParse("2014-04-26 17:24:37.123 +0800")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2014-04-26 09:24:37.123 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2014-04-27 01:24:37.123 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("2014-04-26 17:24:37.123456 +0800") ts = MustParse("2014-04-26 17:24:37.123 -0800")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2014-04-27 01:24:37.123 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2014-04-26 09:24:37.123456 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("2014-04-26 17:24:37.123456 -0800") ts = MustParse("2014-04-26 17:24:37.123456 +0800")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2014-04-26 09:24:37.123456 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2014-04-27 01:24:37.123456 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("2014-12-16 06:20:00 UTC") ts = MustParse("2014-04-26 17:24:37.123456 -0800")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2014-04-27 01:24:37.123456 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2014-12-16 06:20:00 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("2014-12-16 06:20:00 GMT") ts = MustParse("2014-12-16 06:20:00 UTC")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2014-12-16 06:20:00 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2014-12-16 06:20:00 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("2014-04-26 05:24:37 PM") ts = MustParse("2014-12-16 06:20:00 GMT")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2014-12-16 06:20:00 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2014-04-26 17:24:37 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("2014-04-26") ts = MustParse("2014-12-16 06:20:00 +0000 UTC")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2014-12-16 06:20:00 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2014-04-26 00:00:00 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("2014-04") ts = MustParse("2014-04-26 05:24:37 PM")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2014-04-26 17:24:37 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2014-04-01 00:00:00 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("2014-05-11 08:20:13,787") ts = MustParse("2014-04-26")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2014-04-26 00:00:00 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2014-05-11 08:20:13.787 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("2014-05-11 08:20:13 +00:00") ts = MustParse("2014-04")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2014-04-01 00:00:00 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2014-05-11 08:20:13 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("2016-06-21T19:55:00+01:00") ts = MustParse("2014-05-11 08:20:13,787")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2014-05-11 08:20:13.787 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2016-06-21 18:55:00 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("2016-06-21T19:55:00.799+01:00") _, err = ParseAny("2014-13-13 08:20:13,787") // month 13 doesn't exist
assertf(t, err == nil, "%v", err) assert.NotEqual(t, nil, err)
assert(t, "2016-06-21 18:55:00.799 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("2014-05-11 08:20:13 +0000") ts = MustParse("2014-05-11 08:20:13 +00:00")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2014-05-11 08:20:13 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2014-05-11 08:20:13 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts = MustParse("2016-06-21T19:55:00+01:00")
assert.Equal(t, "2016-06-21 18:55:00 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
ts = MustParse("2016-06-21T19:55:00.799+01:00")
assert.Equal(t, "2016-06-21 18:55:00.799 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
ts = MustParse("2014-05-11 08:20:13 +0000")
assert.Equal(t, "2014-05-11 08:20:13 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
// yyyymmdd and similar // yyyymmdd and similar
ts, err = ParseAny("2014") ts = MustParse("2014")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2014-01-01 00:00:00 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2014-01-01 00:00:00 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("20140601") ts = MustParse("20140601")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2014-06-01 00:00:00 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2014-06-01 00:00:00 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("1332151919") ts = MustParse("1332151919")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2012-03-19 10:11:59 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2012-03-19 10:11:59 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts, err = ParseAny("1384216367189") ts = MustParse("1384216367111")
assertf(t, err == nil, "%v", err) assert.Equal(t, "2013-11-12 00:32:47.111 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
assert(t, "2013-11-12 00:32:47.189 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
ts = MustParse("1384216367111222")
assert.Equal(t, "2013-11-12 00:32:47.111222 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
// Nanoseconds
ts = MustParse("1384216367111222333")
assert.Equal(t, "2013-11-12 00:32:47.111222333 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
_, err = ParseAny("138421636711122233311111") // too many digits
assert.NotEqual(t, nil, err)
} }
// func TestWIP(t *testing.T) {
// ts, err := ParseAny("2013-04-01 22:43:22")
// assertf(t, err == nil, "%v", err)
// assert(t, "2013-04-01 22:43:22 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC)))
// }