Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions bench_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
)

/*

go test -bench Parse

BenchmarkShotgunParse 50000 37588 ns/op 13258 B/op 167 allocs/op
Expand All @@ -21,7 +20,6 @@ BenchmarkParseAny-4 200000 8627 ns/op 144 B/op 3 allo
BenchmarkShotgunParse-8 50000 33940 ns/op 13136 B/op 169 allocs/op
BenchmarkParseAny-8 200000 10146 ns/op 912 B/op 29 allocs/op
BenchmarkParseDateString-8 10000 123077 ns/op 208 B/op 13 allocs/op

*/
func BenchmarkShotgunParse(b *testing.B) {
b.ReportAllocs()
Expand Down Expand Up @@ -70,7 +68,7 @@ var (
"2014-04-26",
}

ErrDateFormat = fmt.Errorf("Invalid Date Format")
ErrDateFormat = fmt.Errorf("invalid Date Format")

timeFormats = []string{
// ISO 8601ish formats
Expand Down
36 changes: 19 additions & 17 deletions parseany.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,11 +133,11 @@ const (
var (
// ErrAmbiguousMMDD for date formats such as 04/02/2014 the mm/dd vs dd/mm are
// ambiguous, so it is an error for strict parse rules.
ErrAmbiguousMMDD = fmt.Errorf("This date has ambiguous mm/dd vs dd/mm type format")
ErrAmbiguousMMDD = fmt.Errorf("this date has ambiguous mm/dd vs dd/mm type format")
)

func unknownErr(datestr string) error {
return fmt.Errorf("Could not find format for %q", datestr)
return fmt.Errorf("could not find format for %q", datestr)
}

// ParseAny parse an unknown date format, detect the layout.
Expand Down Expand Up @@ -170,15 +170,14 @@ func ParseIn(datestr string, loc *time.Location, opts ...ParserOption) (time.Tim
// Set Location to time.Local. Same as ParseIn Location but lazily uses
// the global time.Local variable for Location argument.
//
// denverLoc, _ := time.LoadLocation("America/Denver")
// time.Local = denverLoc
// denverLoc, _ := time.LoadLocation("America/Denver")
// time.Local = denverLoc
//
// t, err := dateparse.ParseLocal("3/1/2014")
// t, err := dateparse.ParseLocal("3/1/2014")
//
// Equivalent to:
//
// t, err := dateparse.ParseIn("3/1/2014", denverLoc)
//
// t, err := dateparse.ParseIn("3/1/2014", denverLoc)
func ParseLocal(datestr string, opts ...ParserOption) (time.Time, error) {
p, err := parseTime(datestr, time.Local, opts...)
if err != nil {
Expand All @@ -204,9 +203,8 @@ func MustParse(datestr string, opts ...ParserOption) time.Time {
// ParseFormat parse's an unknown date-time string and returns a layout
// string that can parse this (and exact same format) other date-time strings.
//
// layout, err := dateparse.ParseFormat("2013-02-01 00:00:00")
// // layout = "2006-01-02 15:04:05"
//
// layout, err := dateparse.ParseFormat("2013-02-01 00:00:00")
// // layout = "2006-01-02 15:04:05"
func ParseFormat(datestr string, opts ...ParserOption) (string, error) {
p, err := parseTime(datestr, nil, opts...)
if err != nil {
Expand Down Expand Up @@ -243,14 +241,14 @@ func parseTime(datestr string, loc *time.Location, opts ...ParserOption) (p *par
if p != nil && p.ambiguousMD {
// if it errors out with the following error, swap before we
// get out of this function to reduce scope it needs to be applied on
_, err := p.parse()
_, err = p.parse()
if err != nil && strings.Contains(err.Error(), "month out of range") {
// create the option to reverse the preference
preferMonthFirst := PreferMonthFirst(!p.preferMonthFirst)
// turn off the retry to avoid endless recursion
retryAmbiguousDateWithSwap := RetryAmbiguousDateWithSwap(false)
modifiedOpts := append(opts, preferMonthFirst, retryAmbiguousDateWithSwap)
p, err = parseTime(datestr, time.Local, modifiedOpts...)
_, err = parseTime(datestr, time.Local, modifiedOpts...)
}
}

Expand Down Expand Up @@ -578,6 +576,7 @@ iterRunes:
case dateDigitSlash:
// 03/19/2012 10:11:59
// 04/2/2014 03:00:37
// 04/2/2014, 03:00:37
// 3/1/2012 10:11:59
// 4/8/2014 22:05
// 3/1/2014
Expand Down Expand Up @@ -610,6 +609,14 @@ iterRunes:
p.setYear()
}
break iterRunes
case ',':
p.stateTime = timeStart
if p.yearlen == 0 {
p.yearlen = i - p.yeari
i++
p.setYear()
}
break iterRunes
}

case dateDigitColon:
Expand Down Expand Up @@ -711,7 +718,6 @@ iterRunes:
// 2013年07月18日 星期四 10:27 上午
if r == ' ' {
p.stateDate = dateDigitChineseYearWs
break
}
case dateDigitDot:
// This is the 2nd period
Expand Down Expand Up @@ -1449,7 +1455,6 @@ iterRunes:
p.extra = i - 1
p.stateTime = timeWsOffset
p.trimExtra()
break
default:
switch {
case unicode.IsDigit(r):
Expand Down Expand Up @@ -1596,7 +1601,6 @@ iterRunes:
// 00:00:00.000 +0300 +0300
p.extra = i - 1
p.trimExtra()
break
default:
if unicode.IsLetter(r) {
// 00:07:31.945167 +0000 UTC
Expand All @@ -1611,7 +1615,6 @@ iterRunes:
if r == '=' && datestr[i-1] == 'm' {
p.extra = i - 2
p.trimExtra()
break
}

case timePeriodWsOffsetColon:
Expand Down Expand Up @@ -1982,7 +1985,6 @@ type parser struct {
msi int
mslen int
offseti int
offsetlen int
tzi int
tzlen int
t *time.Time
Expand Down
7 changes: 5 additions & 2 deletions parseany_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ import (

func TestOne(t *testing.T) {
time.Local = time.UTC
var ts time.Time
ts = MustParse("2020-07-20+08:00")
ts := MustParse("2020-07-20+08:00")
assert.Equal(t, "2020-07-19 16:00:00 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
}

Expand Down Expand Up @@ -179,7 +178,9 @@ var testInputs = []dateTest{
{in: "8/8/71", out: "1971-08-08 00:00:00 +0000 UTC"},
// mm/dd/yy hh:mm:ss
{in: "04/02/2014 04:08:09", out: "2014-04-02 04:08:09 +0000 UTC"},
{in: "04/02/2014, 04:08:09", out: "2014-04-02 04:08:09 +0000 UTC"},
{in: "4/2/2014 04:08:09", out: "2014-04-02 04:08:09 +0000 UTC"},
{in: "4/2/2014, 04:08:09", out: "2014-04-02 04:08:09 +0000 UTC"},
{in: "04/02/2014 4:08:09", out: "2014-04-02 04:08:09 +0000 UTC"},
{in: "04/02/2014 4:8:9", out: "2014-04-02 04:08:09 +0000 UTC"},
{in: "04/02/2014 04:08", out: "2014-04-02 04:08:00 +0000 UTC"},
Expand All @@ -201,7 +202,9 @@ var testInputs = []dateTest{
{in: "04/02/2014 04:08:09 AM", out: "2014-04-02 04:08:09 +0000 UTC"},
{in: "04/02/2014 04:08:09 PM", out: "2014-04-02 16:08:09 +0000 UTC"},
{in: "04/02/2014 04:08 AM", out: "2014-04-02 04:08:00 +0000 UTC"},
{in: "04/02/2014, 04:08 AM", out: "2014-04-02 04:08:00 +0000 UTC"},
{in: "04/02/2014 04:08 PM", out: "2014-04-02 16:08:00 +0000 UTC"},
{in: "04/02/2014, 04:08 PM", out: "2014-04-02 16:08:00 +0000 UTC"},
{in: "04/02/2014 4:8 AM", out: "2014-04-02 04:08:00 +0000 UTC"},
{in: "04/02/2014 4:8 PM", out: "2014-04-02 16:08:00 +0000 UTC"},
{in: "04/02/2014 04:08:09.123 AM", out: "2014-04-02 04:08:09.123 +0000 UTC"},
Expand Down