diff --git a/parseany.go b/parseany.go index 58c296e..b76001f 100644 --- a/parseany.go +++ b/parseany.go @@ -3,7 +3,6 @@ package dateparse import ( "fmt" "strconv" - "strings" "time" "unicode" "unicode/utf8" @@ -25,6 +24,7 @@ const ( ST_DIGITSLASH ST_DIGITSLASHWS ST_DIGITSLASHWSCOLON + ST_DIGITSLASHWSCOLONAMPM ST_DIGITSLASHWSCOLONCOLON ST_DIGITSLASHWSCOLONCOLONAMPM ST_DIGITALPHA @@ -247,6 +247,8 @@ iterRunes: switch r { case ':': state = ST_DIGITSLASHWSCOLONCOLON + 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 @@ -610,126 +612,159 @@ iterRunes: // 04/08/2014 22:05 // 2014/4/8 22:05 // 2014/04/08 22:05 + + var t time.Time + var err error + 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, nil + } + return time.Time{}, err + + 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 - if state == ST_DIGITSLASHWSCOLONCOLONAMPM { - datestr = strings.Replace(datestr, " AM", "", -1) - datestr = strings.Replace(datestr, " PM", "", -1) - } + + var t time.Time + var err error + 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, 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 + 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..9cada33 100644 --- a/parseany_test.go +++ b/parseany_test.go @@ -167,14 +167,30 @@ 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 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 12:00:00 +0000 UTC" == fmt.Sprintf("%v", ts.In(time.UTC))) + 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 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 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)