From 5f0a0dbd11aa8b664c729f121383747f8410de48 Mon Sep 17 00:00:00 2001 From: gouguoyin <245629560@qq.com> Date: Thu, 27 Oct 2022 00:07:47 +0800 Subject: [PATCH] Optimized parse method, make it smarter and general --- parser.go | 122 +++++++++++++++++++++++++++++++++++------------------- 1 file changed, 79 insertions(+), 43 deletions(-) diff --git a/parser.go b/parser.go index f368445b..1d824e28 100755 --- a/parser.go +++ b/parser.go @@ -1,57 +1,93 @@ package carbon import ( - "strconv" - "strings" "time" ) -// Parse parses a standard string as a Carbon instance. +// Parse parses a standard time string as a Carbon instance. // 将标准格式时间字符串解析成 Carbon 实例 func (c Carbon) Parse(value string, timezone ...string) Carbon { - layout := DateTimeLayout - if _, err := strconv.ParseInt(value, 10, 64); err == nil { - switch { - case len(value) == 8: - layout = ShortDateLayout - case len(value) == 14: - layout = ShortDateTimeLayout - } - } else { - switch { - case len(value) == 10 && strings.Count(value, "-") == 2: - layout = DateLayout - case len(value) == 18 && strings.Index(value, ".") == 14: - layout = ShortDateTimeMilliLayout - case len(value) == 21 && strings.Index(value, ".") == 14: - layout = ShortDateTimeMicroLayout - case len(value) == 24 && strings.Index(value, ".") == 14: - layout = ShortDateTimeNanoLayout - case len(value) == 25 && strings.Index(value, "T") == 10: - layout = RFC3339Layout - case len(value) == 29 && strings.Index(value, "T") == 10 && strings.Index(value, ".") == 19: - layout = RFC3339MilliLayout - case len(value) == 32 && strings.Index(value, "T") == 10 && strings.Index(value, ".") == 19: - layout = RFC3339MicroLayout - case len(value) == 35 && strings.Index(value, "T") == 10 && strings.Index(value, ".") == 19: - layout = RFC3339NanoLayout - } + timeLayouts := []string{ + DayDateTimeLayout, + DateTimeLayout, + DateTimeMilliLayout, + DateTimeMicroLayout, + DateTimeNanoLayout, + ShortDateTimeLayout, + ShortDateTimeMilliLayout, + ShortDateTimeMicroLayout, + ShortDateTimeNanoLayout, + DateLayout, + DateMilliLayout, + DateMicroLayout, + DateNanoLayout, + ShortDateLayout, + ShortDateMilliLayout, + ShortDateMicroLayout, + ShortDateNanoLayout, + TimeLayout, + TimeMilliLayout, + TimeMicroLayout, + TimeNanoLayout, + ShortTimeLayout, + ShortTimeMilliLayout, + ShortTimeMicroLayout, + ShortTimeNanoLayout, + ANSICLayout, + UnixDateLayout, + RubyDateLayout, + RFC822Layout, + RFC822ZLayout, + RFC850Layout, + RFC1123Layout, + RFC1123ZLayout, + KitchenLayout, + CookieLayout, + RFC3339Layout, + RFC3339MilliLayout, + RFC3339MicroLayout, + RFC3339NanoLayout, + ISO8601Layout, + ISO8601MilliLayout, + ISO8601MicroLayout, + ISO8601NanoLayout, + RFC1036Layout, + RFC7231Layout, + "2006", "2006-1", "2006-1-2", "2006-1-2 15", "2006-1-2 15:4", "2006-1-2 15:4:5", "2006-1-2 15:4:5.999999999", + "2006.1", "2006.1.2", "2006.1.2 15", "2006.1.2 15:4", "2006.1.2 15:4:5", "2006.1.2 15:4:5.999999999", + "2006/1", "2006/1/2", "2006/1/2 15", "2006/1/2 15:4", "2006/1/2 15:4:5", "2006/1/2 15:4:5.999999999", + "1/2/2006", "1/2/2006 15", "1/2/2006 15:4", "1/2/2006 15:4:5", "1/2/2006 15:4:5.999999999", + "15:4:5 Jan 2, 2006 MST", "2006-1-2 15:4:5.999999999 -0700 MST", "Monday, 2-Jan-2006 15:4:5 MST", + "2006-1-2T15:4:5Z07", "2006-1-2T15:4:5Z0700", "2006-1-2T15:4:5Z07:00", "2006-1-2T15:4:5-07:00", "2006-1-2T15:4:5.999999999Z07", "2006-1-2T15:4:5.999999999Z0700", "2006-1-2T15:4:5.999999999-07:00", "2006-1-2T15:4:5.999999999Z07:00", } - carbon := c.ParseByLayout(value, layout, timezone...) - if carbon.Error != nil { - carbon.Error = invalidValueError(value) + if len(timezone) > 0 { + c.loc, c.Error = getLocationByTimezone(timezone[len(timezone)-1]) } - return carbon + if c.Error != nil { + return c + } + if value == "" || value == "0" || value == "0000-00-00 00:00:00" || value == "0000-00-00" || value == "00:00:00" { + return c + } + for _, layout := range timeLayouts { + tt, err := time.ParseInLocation(layout, value, c.loc) + if err == nil { + c.time = tt + return c + } + } + c.Error = invalidValueError(value) + return c } -// Parse parses a standard string as a Carbon instance. +// Parse parses a standard time string as a Carbon instance. // 将标准时间字符串解析成 Carbon 实例 func Parse(value string, timezone ...string) Carbon { return NewCarbon().Parse(value, timezone...) } -// ParseByFormat parses a string as a Carbon instance by format. -// 通过格式模板将字符串解析成 carbon 实例 +// ParseByFormat parses a time string as a Carbon instance by format. +// 通过格式模板将时间字符串解析成 carbon 实例 func (c Carbon) ParseByFormat(value, format string, timezone ...string) Carbon { carbon := c.ParseByLayout(value, format2layout(format), timezone...) if carbon.Error != nil { @@ -60,14 +96,14 @@ func (c Carbon) ParseByFormat(value, format string, timezone ...string) Carbon { return carbon } -// ParseByFormat parses a string as a Carbon instance by format. -// 通过格式模板将字符串解析成 carbon 实例 +// ParseByFormat parses a time string as a Carbon instance by format. +// 通过格式模板将时间字符串解析成 carbon 实例 func ParseByFormat(value, format string, timezone ...string) Carbon { return NewCarbon().ParseByFormat(value, format, timezone...) } -// ParseByLayout parses a string as a Carbon instance by layout. -// 通过布局模板将字符串解析成 carbon 实例 +// ParseByLayout parses a time string as a Carbon instance by layout. +// 通过布局模板将时间字符串解析成 carbon 实例 func (c Carbon) ParseByLayout(value, layout string, timezone ...string) Carbon { if len(timezone) > 0 { c.loc, c.Error = getLocationByTimezone(timezone[len(timezone)-1]) @@ -87,8 +123,8 @@ func (c Carbon) ParseByLayout(value, layout string, timezone ...string) Carbon { return c } -// ParseByLayout parses a string as a Carbon instance by layout. -// 通过布局模板将字符串解析成 Carbon 实例 +// ParseByLayout parses a time string as a Carbon instance by layout. +// 通过布局模板将时间字符串解析成 Carbon 实例 func ParseByLayout(value, layout string, timezone ...string) Carbon { return NewCarbon().ParseByLayout(value, layout, timezone...) }