From 2ac499f3844a9eaa019a05f907ce890ee8baa710 Mon Sep 17 00:00:00 2001 From: junichif Date: Mon, 13 Feb 2017 16:49:48 -0800 Subject: [PATCH 1/2] fix slash am/pm times --- parseany.go | 185 +++++++++++++++++++++-------------------------- parseany_test.go | 14 +++- 2 files changed, 96 insertions(+), 103 deletions(-) diff --git a/parseany.go b/parseany.go index 58c296e..27e89b9 100644 --- a/parseany.go +++ b/parseany.go @@ -25,8 +25,11 @@ const ( ST_DIGITSLASH ST_DIGITSLASHWS ST_DIGITSLASHWSCOLON + ST_DIGITSLASHWSCOLONAM + ST_DIGITSLASHWSCOLONPM ST_DIGITSLASHWSCOLONCOLON - ST_DIGITSLASHWSCOLONCOLONAMPM + ST_DIGITSLASHWSCOLONCOLONAM + ST_DIGITSLASHWSCOLONCOLONPM ST_DIGITALPHA ST_ALPHA ST_ALPHAWS @@ -247,6 +250,10 @@ iterRunes: switch r { case ':': state = ST_DIGITSLASHWSCOLONCOLON + case 'A': + state = ST_DIGITSLASHWSCOLONAM + case 'P': + state = ST_DIGITSLASHWSCOLONPM } case ST_DIGITSLASHWSCOLONCOLON: // starts digit then slash 02/ more digits/slashes then whitespace // 2014/07/10 06:55:38.156283 @@ -256,8 +263,10 @@ iterRunes: // 4/8/2014 22:05 // 3/1/2012 10:11:59 AM switch r { - case 'A', 'P': - state = ST_DIGITSLASHWSCOLONCOLONAMPM + case 'A': + state = ST_DIGITSLASHWSCOLONCOLONAM + case 'P': + state = ST_DIGITSLASHWSCOLONCOLONPM } case ST_DIGITALPHA: // 12 Feb 2006, 19:17 @@ -605,131 +614,103 @@ iterRunes: 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, ST_DIGITSLASHWSCOLONAM, ST_DIGITSLASHWSCOLONPM: // starts digit then slash 02/ more digits/slashes then whitespace // 4/8/2014 22:05 // 04/08/2014 22:05 // 2014/4/8 22:05 // 2014/04/08 22:05 + // 2014/04/08 08:05 PM + + var t time.Time + var err error + var add time.Duration + + if state == ST_DIGITSLASHWSCOLONAM { + datestr = strings.Replace(datestr, " AM", "", -1) + } else if state == ST_DIGITSLASHWSCOLONPM { + datestr = strings.Replace(datestr, " PM", "", -1) + add = time.Duration(12 * time.Hour) + } + if firstSlash == 4 { - if len(datestr) == len("2006/01/02 15:04") { - if t, err := time.Parse("2006/01/02 15:04", datestr); err == nil { - return t, nil - } else { - return time.Time{}, err - } - } else if len(datestr) == len("2006/01/2 15:04") { - if t, err := time.Parse("2006/01/2 15:04", datestr); err == nil { - return t, nil - } else { - if t, err := time.Parse("2006/1/02 15:04", datestr); err == nil { - return t, nil - } else { - return time.Time{}, err - } - } - } else { - if t, err := time.Parse("2006/1/2 15:04", datestr); err == nil { - return t, nil - } else { - return time.Time{}, err + switch len(datestr) { + case len("2006/01/02 15:04"): + 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) } + default: + t, err = time.Parse("2006/1/2 15:04", datestr) } } else { - if len(datestr) == len("01/02/2006 15:04") { - if t, err := time.Parse("01/02/2006 15:04", datestr); err == nil { - return t, nil - } else { - return time.Time{}, err - } - } else if len(datestr) == len("01/2/2006 15:04") { - if t, err := time.Parse("01/2/2006 15:04", datestr); err == nil { - return t, nil - } else { - if t, err := time.Parse("1/02/2006 15:04", datestr); err == nil { - return t, nil - } else { - return time.Time{}, err - } - } - } else { - if t, err := time.Parse("1/2/2006 15:04", datestr); err == nil { - return t, nil - } else { - return time.Time{}, err + 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) } + default: + t, err = time.Parse("1/2/2006 15:04", datestr) } } - case ST_DIGITSLASHWSCOLONCOLON, ST_DIGITSLASHWSCOLONCOLONAMPM: // starts digit then slash 02/ more digits/slashes then whitespace double colons + if err == nil { + return t.Add(add), nil + } + return time.Time{}, err + + case ST_DIGITSLASHWSCOLONCOLON, ST_DIGITSLASHWSCOLONCOLONAM, ST_DIGITSLASHWSCOLONCOLONPM: // starts digit then slash 02/ more digits/slashes then whitespace double colons // 2014/07/10 06:55:38.156283 // 03/19/2012 10:11:59 // 3/1/2012 10:11:59 // 03/1/2012 10:11:59 // 3/01/2012 10:11:59 - if state == ST_DIGITSLASHWSCOLONCOLONAMPM { + // 3/01/2012 10:11:59 PM + + var t time.Time + var err error + var add time.Duration + + if state == ST_DIGITSLASHWSCOLONCOLONAM { datestr = strings.Replace(datestr, " AM", "", -1) + } else if state == ST_DIGITSLASHWSCOLONCOLONPM { datestr = strings.Replace(datestr, " PM", "", -1) + add = time.Duration(12 * time.Hour) } + if firstSlash == 4 { - if len(datestr) == len("2014/07/10 06:55:38.156283") { - if t, err := time.Parse("2006/01/02 15:04:05.000000", datestr); err == nil { - return t, nil - } else { - return time.Time{}, err - } - } else if len(datestr) == len("2006/01/02 15:04:05") { - if t, err := time.Parse("2006/01/02 15:04:05", datestr); err == nil { - return t, nil - } else { - return time.Time{}, err - } - } else if len(datestr) == len("2006/01/2 15:04:05") { - if t, err := time.Parse("2006/01/2 15:04:05", datestr); err == nil { - return t, nil - } else { - if t, err := time.Parse("2006/1/02 15:04:05", datestr); err == nil { - return t, nil - } else { - return time.Time{}, err - } - } - } else { - if t, err := time.Parse("2006/1/2 15:04:05", datestr); err == nil { - return t, nil - } else { - return time.Time{}, err + switch len(datestr) { + case len("2014/07/10 06:55:38.156283"): + 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 { - if len(datestr) == len("07/10/2014 06:55:38.156283") { - if t, err := time.Parse("01/02/2006 15:04:05.000000", datestr); err == nil { - return t, nil - } else { - return time.Time{}, err - } - } else if len(datestr) == len("01/02/2006 15:04:05") { - if t, err := time.Parse("01/02/2006 15:04:05", datestr); err == nil { - return t, nil - } else { - return time.Time{}, err - } - } else if len(datestr) == len("01/2/2006 15:04:05") { - if t, err := time.Parse("01/2/2006 15:04:05", datestr); err == nil { - return t, nil - } else { - if t, err := time.Parse("1/02/2006 15:04:05", datestr); err == nil { - return t, nil - } else { - return time.Time{}, err - } - } - } else { - if t, err := time.Parse("1/2/2006 15:04:05", datestr); err == nil { - return t, nil - } else { - return time.Time{}, err + 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.Add(add), nil + } + return time.Time{}, err + case ST_WEEKDAYABBREVCOMMA: // Starts alpha then comma // Mon, 02 Jan 2006 15:04:05 MST t, err := time.Parse("Mon, 02 Jan 2006 15:04:05 MST", datestr) diff --git a/parseany_test.go b/parseany_test.go index f17c8e4..9b0d180 100644 --- a/parseany_test.go +++ b/parseany_test.go @@ -172,7 +172,19 @@ func TestParse(t *testing.T) { //u.Debug(ts.In(time.UTC).Unix(), ts.In(time.UTC)) assert.T(t, "2014-04-02 03:00:51 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC))) - ts, err = ParseAny("8/8/1965 12:00:00 AM") + ts, err = ParseAny("8/8/1965 01:00:01 PM") + //u.Debug(ts.In(time.UTC).Unix(), ts.In(time.UTC), " error ", err) + assert.T(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") + //u.Debug(ts.In(time.UTC).Unix(), ts.In(time.UTC), " error ", err) + assert.T(t, "1965-08-08 12:00:01 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC))) + + ts, err = ParseAny("8/8/1965 01:00 PM") + //u.Debug(ts.In(time.UTC).Unix(), ts.In(time.UTC), " error ", err) + assert.T(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") //u.Debug(ts.In(time.UTC).Unix(), ts.In(time.UTC), " error ", err) assert.T(t, "1965-08-08 12:00:00 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC))) From 83d88934e42e2e6bbc221d1c4a5cba895f2bd7f0 Mon Sep 17 00:00:00 2001 From: junichif Date: Mon, 13 Feb 2017 18:39:03 -0800 Subject: [PATCH 2/2] split am/pm into own statements --- parseany.go | 124 ++++++++++++++++++++++++++++++++++------------- parseany_test.go | 12 +++-- 2 files changed, 97 insertions(+), 39 deletions(-) diff --git a/parseany.go b/parseany.go index 27e89b9..b76001f 100644 --- a/parseany.go +++ b/parseany.go @@ -3,7 +3,6 @@ package dateparse import ( "fmt" "strconv" - "strings" "time" "unicode" "unicode/utf8" @@ -25,11 +24,9 @@ const ( ST_DIGITSLASH ST_DIGITSLASHWS ST_DIGITSLASHWSCOLON - ST_DIGITSLASHWSCOLONAM - ST_DIGITSLASHWSCOLONPM + ST_DIGITSLASHWSCOLONAMPM ST_DIGITSLASHWSCOLONCOLON - ST_DIGITSLASHWSCOLONCOLONAM - ST_DIGITSLASHWSCOLONCOLONPM + ST_DIGITSLASHWSCOLONCOLONAMPM ST_DIGITALPHA ST_ALPHA ST_ALPHAWS @@ -250,10 +247,8 @@ iterRunes: switch r { case ':': state = ST_DIGITSLASHWSCOLONCOLON - case 'A': - state = ST_DIGITSLASHWSCOLONAM - case 'P': - state = ST_DIGITSLASHWSCOLONPM + case 'A', 'P': + state = ST_DIGITSLASHWSCOLONAMPM } case ST_DIGITSLASHWSCOLONCOLON: // starts digit then slash 02/ more digits/slashes then whitespace // 2014/07/10 06:55:38.156283 @@ -263,10 +258,8 @@ iterRunes: // 4/8/2014 22:05 // 3/1/2012 10:11:59 AM switch r { - case 'A': - state = ST_DIGITSLASHWSCOLONCOLONAM - case 'P': - state = ST_DIGITSLASHWSCOLONCOLONPM + case 'A', 'P': + state = ST_DIGITSLASHWSCOLONCOLONAMPM } case ST_DIGITALPHA: // 12 Feb 2006, 19:17 @@ -614,23 +607,14 @@ iterRunes: return time.Time{}, fmt.Errorf("Unrecognized dateformat: %v", datestr) } - case ST_DIGITSLASHWSCOLON, ST_DIGITSLASHWSCOLONAM, ST_DIGITSLASHWSCOLONPM: // starts digit then slash 02/ more digits/slashes then whitespace + case ST_DIGITSLASHWSCOLON: // starts digit then slash 02/ more digits/slashes then whitespace // 4/8/2014 22:05 // 04/08/2014 22:05 // 2014/4/8 22:05 // 2014/04/08 22:05 - // 2014/04/08 08:05 PM var t time.Time var err error - var add time.Duration - - if state == ST_DIGITSLASHWSCOLONAM { - datestr = strings.Replace(datestr, " AM", "", -1) - } else if state == ST_DIGITSLASHWSCOLONPM { - datestr = strings.Replace(datestr, " PM", "", -1) - add = time.Duration(12 * time.Hour) - } if firstSlash == 4 { switch len(datestr) { @@ -656,28 +640,56 @@ iterRunes: } } if err == nil { - return t.Add(add), nil + return t, nil } return time.Time{}, err - case ST_DIGITSLASHWSCOLONCOLON, ST_DIGITSLASHWSCOLONCOLONAM, ST_DIGITSLASHWSCOLONCOLONPM: // starts digit then slash 02/ more digits/slashes then whitespace double colons + case ST_DIGITSLASHWSCOLONAMPM: // starts digit then slash 02/ more digits/slashes then whitespace + // 4/8/2014 22:05 PM + // 04/08/2014 22:05 PM + // 2014/4/8 22:05 PM + // 2014/04/08 22:05 PM + + var t time.Time + var err error + + if firstSlash == 4 { + switch len(datestr) { + case len("2006/01/02 15:04 PM"): + t, err = time.Parse("2006/01/02 03:04 PM", datestr) + 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 time.Time{}, err + + case ST_DIGITSLASHWSCOLONCOLON: // starts digit then slash 02/ more digits/slashes then whitespace double colons // 2014/07/10 06:55:38.156283 // 03/19/2012 10:11:59 // 3/1/2012 10:11:59 // 03/1/2012 10:11:59 // 3/01/2012 10:11:59 - // 3/01/2012 10:11:59 PM var t time.Time var err error - var add time.Duration - - if state == ST_DIGITSLASHWSCOLONCOLONAM { - datestr = strings.Replace(datestr, " AM", "", -1) - } else if state == ST_DIGITSLASHWSCOLONCOLONPM { - datestr = strings.Replace(datestr, " PM", "", -1) - add = time.Duration(12 * time.Hour) - } if firstSlash == 4 { switch len(datestr) { @@ -707,7 +719,49 @@ iterRunes: } } if err == nil { - return t.Add(add), nil + return t, nil + } + return time.Time{}, err + + case ST_DIGITSLASHWSCOLONCOLONAMPM: // starts digit then slash 02/ more digits/slashes then whitespace double colons + // 2014/07/10 06:55:38.156283 PM + // 03/19/2012 10:11:59 PM + // 3/1/2012 10:11:59 PM + // 03/1/2012 10:11:59 PM + // 3/01/2012 10:11:59 PM + + var t time.Time + var err error + + if firstSlash == 4 { + switch len(datestr) { + case len("2014/07/10 06:55:38.156283 PM"): + t, err = time.Parse("2006/01/02 03:04:05.000000 PM", datestr) + 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 time.Time{}, err diff --git a/parseany_test.go b/parseany_test.go index 9b0d180..9cada33 100644 --- a/parseany_test.go +++ b/parseany_test.go @@ -167,10 +167,10 @@ func TestParse(t *testing.T) { //u.Debug(ts.In(time.UTC).Unix(), ts.In(time.UTC)) assert.T(t, "2014-04-08 22:05:00 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC))) - ts, err = ParseAny("04/2/2014 03:00:51") + ts, err = ParseAny("04/2/2014 4:00:51") assert.Tf(t, err == nil, "%v", err) //u.Debug(ts.In(time.UTC).Unix(), ts.In(time.UTC)) - assert.T(t, "2014-04-02 03:00:51 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC))) + assert.T(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") //u.Debug(ts.In(time.UTC).Unix(), ts.In(time.UTC), " error ", err) @@ -178,15 +178,19 @@ func TestParse(t *testing.T) { ts, err = ParseAny("8/8/1965 12:00:01 AM") //u.Debug(ts.In(time.UTC).Unix(), ts.In(time.UTC), " error ", err) - assert.T(t, "1965-08-08 12:00:01 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC))) + assert.T(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") + // u.Debug(ts.In(time.UTC).Unix(), ts.In(time.UTC), " error ", err) + assert.T(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") //u.Debug(ts.In(time.UTC).Unix(), ts.In(time.UTC), " error ", err) assert.T(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") //u.Debug(ts.In(time.UTC).Unix(), ts.In(time.UTC), " error ", err) - assert.T(t, "1965-08-08 12:00:00 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC))) + assert.T(t, "1965-08-08 00:00:00 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC))) ts, err = ParseAny("4/02/2014 03:00:51") assert.Tf(t, err == nil, "%v", err)