Skip to content

Commit

Permalink
Optimized parse method, make it smarter and general
Browse files Browse the repository at this point in the history
  • Loading branch information
gouguoyin committed Oct 26, 2022
1 parent 60b5d96 commit 5f0a0db
Showing 1 changed file with 79 additions and 43 deletions.
122 changes: 79 additions & 43 deletions parser.go
Original file line number Diff line number Diff line change
@@ -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 {
Expand All @@ -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])
Expand All @@ -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...)
}

0 comments on commit 5f0a0db

Please sign in to comment.