Skip to content

Commit

Permalink
Reimplement date parser (#611)
Browse files Browse the repository at this point in the history
  • Loading branch information
rkscv authored Sep 26, 2024
1 parent 6c7d1df commit 02193f3
Show file tree
Hide file tree
Showing 4 changed files with 394 additions and 908 deletions.
94 changes: 24 additions & 70 deletions date.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,80 +25,34 @@ type dateObject struct {
msec int64
}

type dateLayoutDesc struct {
layout string
dateOnly bool
}

var (
dateLayoutsNumeric = []dateLayoutDesc{
{layout: "2006-01-02T15:04:05Z0700"},
{layout: "2006-01-02T15:04:05"},
{layout: "2006-01-02", dateOnly: true},
{layout: "2006-01-02 15:04:05"},

{layout: "2006", dateOnly: true},
{layout: "2006-01", dateOnly: true},

{layout: "2006T15:04"},
{layout: "2006-01T15:04"},
{layout: "2006-01-02T15:04"},

{layout: "2006T15:04:05"},
{layout: "2006-01T15:04:05"},

{layout: "2006T15:04Z0700"},
{layout: "2006-01T15:04Z0700"},
{layout: "2006-01-02T15:04Z0700"},

{layout: "2006T15:04:05Z0700"},
{layout: "2006-01T15:04:05Z0700"},
func dateParse(date string) (t time.Time, ok bool) {
d, ok := parseDateISOString(date)
if !ok {
d, ok = parseDateOtherString(date)
}

dateLayoutsAlpha = []dateLayoutDesc{
{layout: time.RFC1123},
{layout: time.RFC1123Z},
{layout: dateTimeLayout},
{layout: time.UnixDate},
{layout: time.ANSIC},
{layout: time.RubyDate},
{layout: "Mon, _2 Jan 2006 15:04:05 GMT-0700 (MST)"},
{layout: "Mon, _2 Jan 2006 15:04:05 -0700 (MST)"},
{layout: "Jan _2, 2006", dateOnly: true},
}
)

func dateParse(date string) (time.Time, bool) {
var t time.Time
var err error
var layouts []dateLayoutDesc
if len(date) > 0 {
first := date[0]
if first <= '9' && (first >= '0' || first == '-' || first == '+') {
layouts = dateLayoutsNumeric
} else {
layouts = dateLayoutsAlpha
}
} else {
return time.Time{}, false
if !ok {
return
}
for _, desc := range layouts {
var defLoc *time.Location
if desc.dateOnly {
defLoc = time.UTC
} else {
defLoc = time.Local
}
t, err = parseDate(desc.layout, date, defLoc)
if err == nil {
break
}
if d.month > 12 ||
d.day > 31 ||
d.hour > 24 ||
d.min > 59 ||
d.sec > 59 ||
// special case 24:00:00.000
(d.hour == 24 && (d.min != 0 || d.sec != 0 || d.msec != 0)) {
ok = false
return
}
if err != nil {
return time.Time{}, false
var loc *time.Location
if d.isLocal {
loc = time.Local
} else {
loc = time.FixedZone("", d.timeZoneOffset*60)
}
unix := timeToMsec(t)
return t, unix >= -maxTime && unix <= maxTime
t = time.Date(d.year, time.Month(d.month), d.day, d.hour, d.min, d.sec, d.msec*1e6, loc)
unixMilli := t.UnixMilli()
ok = unixMilli >= -maxTime && unixMilli <= maxTime
return
}

func (r *Runtime) newDateObject(t time.Time, isSet bool, proto *Object) *Object {
Expand Down
Loading

0 comments on commit 02193f3

Please sign in to comment.