added comma format

This commit is contained in:
Brian Leishman 2023-08-07 14:58:57 -04:00
parent 6b43995a97
commit 9e8b9fec92
3 changed files with 25 additions and 22 deletions

View File

@ -7,7 +7,6 @@ import (
) )
/* /*
go test -bench Parse go test -bench Parse
BenchmarkShotgunParse 50000 37588 ns/op 13258 B/op 167 allocs/op BenchmarkShotgunParse 50000 37588 ns/op 13258 B/op 167 allocs/op
@ -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 BenchmarkShotgunParse-8 50000 33940 ns/op 13136 B/op 169 allocs/op
BenchmarkParseAny-8 200000 10146 ns/op 912 B/op 29 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 BenchmarkParseDateString-8 10000 123077 ns/op 208 B/op 13 allocs/op
*/ */
func BenchmarkShotgunParse(b *testing.B) { func BenchmarkShotgunParse(b *testing.B) {
b.ReportAllocs() b.ReportAllocs()
@ -70,7 +68,7 @@ var (
"2014-04-26", "2014-04-26",
} }
ErrDateFormat = fmt.Errorf("Invalid Date Format") ErrDateFormat = fmt.Errorf("invalid Date Format")
timeFormats = []string{ timeFormats = []string{
// ISO 8601ish formats // ISO 8601ish formats

View File

@ -133,11 +133,11 @@ const (
var ( var (
// ErrAmbiguousMMDD for date formats such as 04/02/2014 the mm/dd vs dd/mm are // 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. // 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 { 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. // ParseAny parse an unknown date format, detect the layout.
@ -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 // Set Location to time.Local. Same as ParseIn Location but lazily uses
// the global time.Local variable for Location argument. // the global time.Local variable for Location argument.
// //
// denverLoc, _ := time.LoadLocation("America/Denver") // denverLoc, _ := time.LoadLocation("America/Denver")
// time.Local = denverLoc // time.Local = denverLoc
// //
// t, err := dateparse.ParseLocal("3/1/2014") // t, err := dateparse.ParseLocal("3/1/2014")
// //
// Equivalent to: // 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) { func ParseLocal(datestr string, opts ...ParserOption) (time.Time, error) {
p, err := parseTime(datestr, time.Local, opts...) p, err := parseTime(datestr, time.Local, opts...)
if err != nil { if err != nil {
@ -204,9 +203,8 @@ func MustParse(datestr string, opts ...ParserOption) time.Time {
// ParseFormat parse's an unknown date-time string and returns a layout // 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. // string that can parse this (and exact same format) other date-time strings.
// //
// layout, err := dateparse.ParseFormat("2013-02-01 00:00:00") // layout, err := dateparse.ParseFormat("2013-02-01 00:00:00")
// // layout = "2006-01-02 15:04:05" // // layout = "2006-01-02 15:04:05"
//
func ParseFormat(datestr string, opts ...ParserOption) (string, error) { func ParseFormat(datestr string, opts ...ParserOption) (string, error) {
p, err := parseTime(datestr, nil, opts...) p, err := parseTime(datestr, nil, opts...)
if err != nil { if err != nil {
@ -243,14 +241,14 @@ func parseTime(datestr string, loc *time.Location, opts ...ParserOption) (p *par
if p != nil && p.ambiguousMD { if p != nil && p.ambiguousMD {
// if it errors out with the following error, swap before we // 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 // 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") { if err != nil && strings.Contains(err.Error(), "month out of range") {
// create the option to reverse the preference // create the option to reverse the preference
preferMonthFirst := PreferMonthFirst(!p.preferMonthFirst) preferMonthFirst := PreferMonthFirst(!p.preferMonthFirst)
// turn off the retry to avoid endless recursion // turn off the retry to avoid endless recursion
retryAmbiguousDateWithSwap := RetryAmbiguousDateWithSwap(false) retryAmbiguousDateWithSwap := RetryAmbiguousDateWithSwap(false)
modifiedOpts := append(opts, preferMonthFirst, retryAmbiguousDateWithSwap) modifiedOpts := append(opts, preferMonthFirst, retryAmbiguousDateWithSwap)
p, err = parseTime(datestr, time.Local, modifiedOpts...) _, err = parseTime(datestr, time.Local, modifiedOpts...)
} }
} }
@ -578,6 +576,7 @@ iterRunes:
case dateDigitSlash: case dateDigitSlash:
// 03/19/2012 10:11:59 // 03/19/2012 10:11:59
// 04/2/2014 03:00:37 // 04/2/2014 03:00:37
// 04/2/2014, 03:00:37
// 3/1/2012 10:11:59 // 3/1/2012 10:11:59
// 4/8/2014 22:05 // 4/8/2014 22:05
// 3/1/2014 // 3/1/2014
@ -610,6 +609,14 @@ iterRunes:
p.setYear() p.setYear()
} }
break iterRunes break iterRunes
case ',':
p.stateTime = timeStart
if p.yearlen == 0 {
p.yearlen = i - p.yeari
i++
p.setYear()
}
break iterRunes
} }
case dateDigitColon: case dateDigitColon:
@ -711,7 +718,6 @@ iterRunes:
// 2013年07月18日 星期四 10:27 上午 // 2013年07月18日 星期四 10:27 上午
if r == ' ' { if r == ' ' {
p.stateDate = dateDigitChineseYearWs p.stateDate = dateDigitChineseYearWs
break
} }
case dateDigitDot: case dateDigitDot:
// This is the 2nd period // This is the 2nd period
@ -1449,7 +1455,6 @@ iterRunes:
p.extra = i - 1 p.extra = i - 1
p.stateTime = timeWsOffset p.stateTime = timeWsOffset
p.trimExtra() p.trimExtra()
break
default: default:
switch { switch {
case unicode.IsDigit(r): case unicode.IsDigit(r):
@ -1596,7 +1601,6 @@ iterRunes:
// 00:00:00.000 +0300 +0300 // 00:00:00.000 +0300 +0300
p.extra = i - 1 p.extra = i - 1
p.trimExtra() p.trimExtra()
break
default: default:
if unicode.IsLetter(r) { if unicode.IsLetter(r) {
// 00:07:31.945167 +0000 UTC // 00:07:31.945167 +0000 UTC
@ -1611,7 +1615,6 @@ iterRunes:
if r == '=' && datestr[i-1] == 'm' { if r == '=' && datestr[i-1] == 'm' {
p.extra = i - 2 p.extra = i - 2
p.trimExtra() p.trimExtra()
break
} }
case timePeriodWsOffsetColon: case timePeriodWsOffsetColon:
@ -1982,7 +1985,6 @@ type parser struct {
msi int msi int
mslen int mslen int
offseti int offseti int
offsetlen int
tzi int tzi int
tzlen int tzlen int
t *time.Time t *time.Time

View File

@ -10,8 +10,7 @@ import (
func TestOne(t *testing.T) { func TestOne(t *testing.T) {
time.Local = time.UTC 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))) assert.Equal(t, "2020-07-19 16:00:00 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
} }
@ -179,7 +178,9 @@ var testInputs = []dateTest{
{in: "8/8/71", out: "1971-08-08 00:00:00 +0000 UTC"}, {in: "8/8/71", out: "1971-08-08 00:00:00 +0000 UTC"},
// mm/dd/yy hh:mm:ss // 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: "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: "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: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 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"}, {in: "04/02/2014 04:08", out: "2014-04-02 04:08:00 +0000 UTC"},
@ -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 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: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 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, 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 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 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"}, {in: "04/02/2014 04:08:09.123 AM", out: "2014-04-02 04:08:09.123 +0000 UTC"},