mirror of
https://github.com/araddon/dateparse.git
synced 2024-11-10 11:51:54 +08:00
new format closes #69
This commit is contained in:
parent
089f77b1d9
commit
700250988b
479
parseany.go
479
parseany.go
@ -38,11 +38,14 @@ type timeState uint8
|
|||||||
const (
|
const (
|
||||||
dateStart dateState = iota
|
dateStart dateState = iota
|
||||||
dateDigit
|
dateDigit
|
||||||
|
dateYearDash
|
||||||
|
dateYearDashAlphaDash
|
||||||
|
dateYearDashDash
|
||||||
|
dateYearDashDashWs
|
||||||
|
dateYearDashDashT
|
||||||
dateDigitDash
|
dateDigitDash
|
||||||
dateDigitDashDash
|
dateDigitDashAlpha
|
||||||
dateDigitDashDashWs
|
dateDigitDashAlphaDash
|
||||||
dateDigitDashDashT
|
|
||||||
dateDigitDashDashAlpha
|
|
||||||
dateDigitDot
|
dateDigitDot
|
||||||
dateDigitDotDot
|
dateDigitDotDot
|
||||||
dateDigitSlash
|
dateDigitSlash
|
||||||
@ -202,167 +205,6 @@ func ParseStrict(datestr string) (time.Time, error) {
|
|||||||
return p.parse()
|
return p.parse()
|
||||||
}
|
}
|
||||||
|
|
||||||
type parser struct {
|
|
||||||
loc *time.Location
|
|
||||||
preferMonthFirst bool
|
|
||||||
ambiguousMD bool
|
|
||||||
stateDate dateState
|
|
||||||
stateTime timeState
|
|
||||||
format []byte
|
|
||||||
datestr string
|
|
||||||
skip int
|
|
||||||
extra int
|
|
||||||
part1Len int
|
|
||||||
yeari int
|
|
||||||
yearlen int
|
|
||||||
moi int
|
|
||||||
molen int
|
|
||||||
dayi int
|
|
||||||
daylen int
|
|
||||||
houri int
|
|
||||||
hourlen int
|
|
||||||
mini int
|
|
||||||
minlen int
|
|
||||||
seci int
|
|
||||||
seclen int
|
|
||||||
msi int
|
|
||||||
mslen int
|
|
||||||
offseti int
|
|
||||||
offsetlen int
|
|
||||||
tzi int
|
|
||||||
tzlen int
|
|
||||||
t *time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
func newParser(dateStr string, loc *time.Location) *parser {
|
|
||||||
p := parser{
|
|
||||||
stateDate: dateStart,
|
|
||||||
stateTime: timeIgnore,
|
|
||||||
datestr: dateStr,
|
|
||||||
loc: loc,
|
|
||||||
preferMonthFirst: true,
|
|
||||||
}
|
|
||||||
p.format = []byte(dateStr)
|
|
||||||
return &p
|
|
||||||
}
|
|
||||||
func (p *parser) set(start int, val string) {
|
|
||||||
if start < 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if len(p.format) < start+len(val) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for i, r := range val {
|
|
||||||
p.format[start+i] = byte(r)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
func (p *parser) setMonth() {
|
|
||||||
if p.molen == 2 {
|
|
||||||
p.set(p.moi, "01")
|
|
||||||
} else if p.molen == 1 {
|
|
||||||
p.set(p.moi, "1")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *parser) setDay() {
|
|
||||||
if p.daylen == 2 {
|
|
||||||
p.set(p.dayi, "02")
|
|
||||||
} else if p.daylen == 1 {
|
|
||||||
p.set(p.dayi, "2")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
func (p *parser) setYear() {
|
|
||||||
if p.yearlen == 2 {
|
|
||||||
p.set(p.yeari, "06")
|
|
||||||
} else if p.yearlen == 4 {
|
|
||||||
p.set(p.yeari, "2006")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
func (p *parser) coalesceDate(end int) {
|
|
||||||
if p.yeari > 0 {
|
|
||||||
if p.yearlen == 0 {
|
|
||||||
p.yearlen = end - p.yeari
|
|
||||||
}
|
|
||||||
p.setYear()
|
|
||||||
}
|
|
||||||
if p.moi > 0 && p.molen == 0 {
|
|
||||||
p.molen = end - p.moi
|
|
||||||
p.setMonth()
|
|
||||||
}
|
|
||||||
if p.dayi > 0 && p.daylen == 0 {
|
|
||||||
p.daylen = end - p.dayi
|
|
||||||
p.setDay()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
func (p *parser) ts() string {
|
|
||||||
return fmt.Sprintf("h:(%d:%d) m:(%d:%d) s:(%d:%d)", p.houri, p.hourlen, p.mini, p.minlen, p.seci, p.seclen)
|
|
||||||
}
|
|
||||||
func (p *parser) ds() string {
|
|
||||||
return fmt.Sprintf("%s d:(%d:%d) m:(%d:%d) y:(%d:%d)", p.datestr, p.dayi, p.daylen, p.moi, p.molen, p.yeari, p.yearlen)
|
|
||||||
}
|
|
||||||
func (p *parser) coalesceTime(end int) {
|
|
||||||
// 03:04:05
|
|
||||||
// 15:04:05
|
|
||||||
// 3:04:05
|
|
||||||
// 3:4:5
|
|
||||||
// 15:04:05.00
|
|
||||||
if p.houri > 0 {
|
|
||||||
if p.hourlen == 2 {
|
|
||||||
p.set(p.houri, "15")
|
|
||||||
} else if p.hourlen == 1 {
|
|
||||||
p.set(p.houri, "3")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if p.mini > 0 {
|
|
||||||
if p.minlen == 0 {
|
|
||||||
p.minlen = end - p.mini
|
|
||||||
}
|
|
||||||
if p.minlen == 2 {
|
|
||||||
p.set(p.mini, "04")
|
|
||||||
} else {
|
|
||||||
p.set(p.mini, "4")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if p.seci > 0 {
|
|
||||||
if p.seclen == 0 {
|
|
||||||
p.seclen = end - p.seci
|
|
||||||
}
|
|
||||||
if p.seclen == 2 {
|
|
||||||
p.set(p.seci, "05")
|
|
||||||
} else {
|
|
||||||
p.set(p.seci, "5")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if p.msi > 0 {
|
|
||||||
for i := 0; i < p.mslen; i++ {
|
|
||||||
p.format[p.msi+i] = '0'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *parser) trimExtra() {
|
|
||||||
if p.extra > 0 && len(p.format) > p.extra {
|
|
||||||
p.format = p.format[0:p.extra]
|
|
||||||
p.datestr = p.datestr[0:p.extra]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *parser) parse() (time.Time, error) {
|
|
||||||
if p.t != nil {
|
|
||||||
return *p.t, nil
|
|
||||||
}
|
|
||||||
if p.skip > 0 && len(p.format) > p.skip {
|
|
||||||
p.format = p.format[p.skip:]
|
|
||||||
p.datestr = p.datestr[p.skip:]
|
|
||||||
}
|
|
||||||
//gou.Debugf("parse %q AS %s", p.datestr, string(p.format))
|
|
||||||
if p.loc == nil {
|
|
||||||
return time.Parse(string(p.format), p.datestr)
|
|
||||||
}
|
|
||||||
return time.ParseInLocation(string(p.format), p.datestr, p.loc)
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseTime(datestr string, loc *time.Location) (*parser, error) {
|
func parseTime(datestr string, loc *time.Location) (*parser, error) {
|
||||||
|
|
||||||
p := newParser(datestr, loc)
|
p := newParser(datestr, loc)
|
||||||
@ -395,15 +237,17 @@ iterRunes:
|
|||||||
switch r {
|
switch r {
|
||||||
case '-', '\u2212':
|
case '-', '\u2212':
|
||||||
// 2006-01-02
|
// 2006-01-02
|
||||||
// 2006-01-02T15:04:05Z07:00
|
|
||||||
// 13-Feb-03
|
|
||||||
// 2013-Feb-03
|
// 2013-Feb-03
|
||||||
p.stateDate = dateDigitDash
|
// 13-Feb-03
|
||||||
p.yeari = 0
|
// 29-Jun-2016
|
||||||
p.yearlen = i
|
|
||||||
p.moi = i + 1
|
|
||||||
if i == 4 {
|
if i == 4 {
|
||||||
|
p.stateDate = dateYearDash
|
||||||
|
p.yeari = 0
|
||||||
|
p.yearlen = i
|
||||||
|
p.moi = i + 1
|
||||||
p.set(0, "2006")
|
p.set(0, "2006")
|
||||||
|
} else {
|
||||||
|
p.stateDate = dateDigitDash
|
||||||
}
|
}
|
||||||
case '/':
|
case '/':
|
||||||
// 03/31/2005
|
// 03/31/2005
|
||||||
@ -458,83 +302,110 @@ iterRunes:
|
|||||||
case ',':
|
case ',':
|
||||||
return nil, unknownErr(datestr)
|
return nil, unknownErr(datestr)
|
||||||
default:
|
default:
|
||||||
//if unicode.IsDigit(r) {
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
p.part1Len = i
|
p.part1Len = i
|
||||||
|
|
||||||
case dateDigitDash:
|
case dateYearDash:
|
||||||
// 2006-01
|
// dateYearDashDashT
|
||||||
// 2006-01-02
|
|
||||||
// dateDigitDashDashT
|
|
||||||
// 2006-01-02T15:04:05Z07:00
|
// 2006-01-02T15:04:05Z07:00
|
||||||
// 2017-06-25T17:46:57.45706582-07:00
|
// dateYearDashDashWs
|
||||||
// 2006-01-02T15:04:05.999999999Z07:00
|
|
||||||
// 2006-01-02T15:04:05+0000
|
|
||||||
// dateDigitDashDashWs
|
|
||||||
// 2012-08-03 18:31:59.257000000
|
|
||||||
// 2014-04-26 17:24:37.3186369
|
|
||||||
// 2017-01-27 00:07:31.945167
|
|
||||||
// 2016-03-14 00:00:00.000
|
|
||||||
// 2014-05-11 08:20:13,787
|
|
||||||
// 2017-07-19 03:21:51+00:00
|
|
||||||
// 2013-04-01 22:43:22
|
// 2013-04-01 22:43:22
|
||||||
// 2014-04-26 05:24:37 PM
|
// dateYearDashAlphaDash
|
||||||
// dateDigitDashDashAlpha
|
// 2013-Feb-03
|
||||||
// 2013-Feb-03
|
|
||||||
// 13-Feb-03
|
|
||||||
switch r {
|
switch r {
|
||||||
case '-':
|
case '-':
|
||||||
p.molen = i - p.moi
|
p.molen = i - p.moi
|
||||||
p.dayi = i + 1
|
p.dayi = i + 1
|
||||||
p.stateDate = dateDigitDashDash
|
p.stateDate = dateYearDashDash
|
||||||
p.setMonth()
|
p.setMonth()
|
||||||
default:
|
default:
|
||||||
if unicode.IsDigit(r) {
|
if unicode.IsLetter(r) {
|
||||||
//continue
|
p.stateDate = dateYearDashAlphaDash
|
||||||
} else if unicode.IsLetter(r) {
|
|
||||||
p.stateDate = dateDigitDashDashAlpha
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case dateDigitDashDash:
|
|
||||||
// 2006-01-02
|
case dateYearDashDash:
|
||||||
// dateDigitDashDashT
|
// dateYearDashDashT
|
||||||
// 2006-01-02T15:04:05Z07:00
|
// 2006-01-02T15:04:05Z07:00
|
||||||
// 2017-06-25T17:46:57.45706582-07:00
|
// dateYearDashDashWs
|
||||||
// 2006-01-02T15:04:05.999999999Z07:00
|
|
||||||
// 2006-01-02T15:04:05+0000
|
|
||||||
// dateDigitDashDashWs
|
|
||||||
// 2012-08-03 18:31:59.257000000
|
|
||||||
// 2014-04-26 17:24:37.3186369
|
|
||||||
// 2017-01-27 00:07:31.945167
|
|
||||||
// 2016-03-14 00:00:00.000
|
|
||||||
// 2014-05-11 08:20:13,787
|
|
||||||
// 2017-07-19 03:21:51+00:00
|
|
||||||
// 2013-04-01 22:43:22
|
// 2013-04-01 22:43:22
|
||||||
// 2014-04-26 05:24:37 PM
|
|
||||||
switch r {
|
switch r {
|
||||||
case ' ':
|
case ' ':
|
||||||
p.daylen = i - p.dayi
|
p.daylen = i - p.dayi
|
||||||
p.stateDate = dateDigitDashDashWs
|
p.stateDate = dateYearDashDashWs
|
||||||
p.stateTime = timeStart
|
p.stateTime = timeStart
|
||||||
p.setDay()
|
p.setDay()
|
||||||
break iterRunes
|
break iterRunes
|
||||||
case 'T':
|
case 'T':
|
||||||
p.daylen = i - p.dayi
|
p.daylen = i - p.dayi
|
||||||
p.stateDate = dateDigitDashDashT
|
p.stateDate = dateYearDashDashT
|
||||||
p.stateTime = timeStart
|
p.stateTime = timeStart
|
||||||
p.setDay()
|
p.setDay()
|
||||||
break iterRunes
|
break iterRunes
|
||||||
}
|
}
|
||||||
case dateDigitDashDashAlpha:
|
case dateYearDashAlphaDash:
|
||||||
// 2013-Feb-03
|
// 2013-Feb-03
|
||||||
// 13-Feb-03
|
|
||||||
switch r {
|
switch r {
|
||||||
case '-':
|
case '-':
|
||||||
p.molen = i - p.moi
|
p.molen = i - p.moi
|
||||||
p.set(p.moi, "Jan")
|
p.set(p.moi, "Jan")
|
||||||
p.dayi = i + 1
|
p.dayi = i + 1
|
||||||
}
|
}
|
||||||
|
case dateDigitDash:
|
||||||
|
// 13-Feb-03
|
||||||
|
// 29-Jun-2016
|
||||||
|
if unicode.IsLetter(r) {
|
||||||
|
p.stateDate = dateDigitDashAlpha
|
||||||
|
p.moi = i
|
||||||
|
} else {
|
||||||
|
return nil, unknownErr(datestr)
|
||||||
|
}
|
||||||
|
case dateDigitDashAlpha:
|
||||||
|
// 13-Feb-03
|
||||||
|
// 28-Feb-03
|
||||||
|
// 29-Jun-2016
|
||||||
|
switch r {
|
||||||
|
case '-':
|
||||||
|
p.molen = i - p.moi
|
||||||
|
p.set(p.moi, "Jan")
|
||||||
|
p.yeari = i + 1
|
||||||
|
p.stateDate = dateDigitDashAlphaDash
|
||||||
|
}
|
||||||
|
|
||||||
|
case dateDigitDashAlphaDash:
|
||||||
|
// 13-Feb-03 ambiguous
|
||||||
|
// 28-Feb-03 ambiguous
|
||||||
|
// 29-Jun-2016
|
||||||
|
switch r {
|
||||||
|
case ' ':
|
||||||
|
// we need to find if this was 4 digits, aka year
|
||||||
|
// or 2 digits which makes it ambiguous year/day
|
||||||
|
length := i - (p.moi + p.molen + 1)
|
||||||
|
if length == 4 {
|
||||||
|
p.yearlen = 4
|
||||||
|
p.set(p.yeari, "2006")
|
||||||
|
// We now also know that part1 was the day
|
||||||
|
p.dayi = 0
|
||||||
|
p.daylen = p.part1Len
|
||||||
|
p.setDay()
|
||||||
|
} else if length == 2 {
|
||||||
|
// We have no idea if this is
|
||||||
|
// yy-mon-dd OR dd-mon-yy
|
||||||
|
//
|
||||||
|
// We are going to ASSUME (bad, bad) that it is dd-mon-yy which is a horible assumption
|
||||||
|
p.ambiguousMD = true
|
||||||
|
p.yearlen = 2
|
||||||
|
p.set(p.yeari, "06")
|
||||||
|
// We now also know that part1 was the day
|
||||||
|
p.dayi = 0
|
||||||
|
p.daylen = p.part1Len
|
||||||
|
p.setDay()
|
||||||
|
}
|
||||||
|
p.stateTime = timeStart
|
||||||
|
break iterRunes
|
||||||
|
}
|
||||||
|
|
||||||
case dateDigitSlash:
|
case dateDigitSlash:
|
||||||
// 2014/07/10 06:55:38.156283
|
// 2014/07/10 06:55:38.156283
|
||||||
// 03/19/2012 10:11:59
|
// 03/19/2012 10:11:59
|
||||||
@ -1462,30 +1333,35 @@ iterRunes:
|
|||||||
return p, nil
|
return p, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
case dateDigitDash:
|
case dateYearDash:
|
||||||
// 2006-01
|
// 2006-01
|
||||||
return p, nil
|
return p, nil
|
||||||
|
|
||||||
case dateDigitDashDash:
|
case dateYearDashDash:
|
||||||
// 2006-01-02
|
// 2006-01-02
|
||||||
// 2006-1-02
|
// 2006-1-02
|
||||||
// 2006-1-2
|
// 2006-1-2
|
||||||
// 2006-01-2
|
// 2006-01-2
|
||||||
return p, nil
|
return p, nil
|
||||||
|
|
||||||
case dateDigitDashDashAlpha:
|
case dateYearDashAlphaDash:
|
||||||
// 2013-Feb-03
|
// 2013-Feb-03
|
||||||
// 2013-Feb-3
|
// 2013-Feb-3
|
||||||
p.daylen = i - p.dayi
|
p.daylen = i - p.dayi
|
||||||
p.setDay()
|
p.setDay()
|
||||||
return p, nil
|
return p, nil
|
||||||
|
|
||||||
case dateDigitDashDashWs: // starts digit then dash 02- then whitespace 1 << 2 << 5 + 3
|
case dateYearDashDashWs:
|
||||||
// 2013-04-01 22:43:22
|
// 2013-04-01
|
||||||
// 2013-04-01 22:43
|
|
||||||
return p, nil
|
return p, nil
|
||||||
|
|
||||||
case dateDigitDashDashT:
|
case dateYearDashDashT:
|
||||||
|
return p, nil
|
||||||
|
|
||||||
|
case dateDigitDashAlphaDash:
|
||||||
|
// 13-Feb-03 ambiguous
|
||||||
|
// 28-Feb-03 ambiguous
|
||||||
|
// 29-Jun-2016
|
||||||
return p, nil
|
return p, nil
|
||||||
|
|
||||||
case dateDigitDot:
|
case dateDigitDot:
|
||||||
@ -1509,9 +1385,7 @@ iterRunes:
|
|||||||
// 2 Jan 18
|
// 2 Jan 18
|
||||||
// 2 Jan 2018 23:59
|
// 2 Jan 2018 23:59
|
||||||
// 02 Jan 2018 23:59
|
// 02 Jan 2018 23:59
|
||||||
// 02 Jan 2018 23:59:45
|
|
||||||
// 12 Feb 2006, 19:17
|
// 12 Feb 2006, 19:17
|
||||||
// 12 Feb 2006, 19:17:22
|
|
||||||
return p, nil
|
return p, nil
|
||||||
|
|
||||||
case dateDigitWsMolong:
|
case dateDigitWsMolong:
|
||||||
@ -1572,3 +1446,164 @@ iterRunes:
|
|||||||
|
|
||||||
return nil, unknownErr(datestr)
|
return nil, unknownErr(datestr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type parser struct {
|
||||||
|
loc *time.Location
|
||||||
|
preferMonthFirst bool
|
||||||
|
ambiguousMD bool
|
||||||
|
stateDate dateState
|
||||||
|
stateTime timeState
|
||||||
|
format []byte
|
||||||
|
datestr string
|
||||||
|
skip int
|
||||||
|
extra int
|
||||||
|
part1Len int
|
||||||
|
yeari int
|
||||||
|
yearlen int
|
||||||
|
moi int
|
||||||
|
molen int
|
||||||
|
dayi int
|
||||||
|
daylen int
|
||||||
|
houri int
|
||||||
|
hourlen int
|
||||||
|
mini int
|
||||||
|
minlen int
|
||||||
|
seci int
|
||||||
|
seclen int
|
||||||
|
msi int
|
||||||
|
mslen int
|
||||||
|
offseti int
|
||||||
|
offsetlen int
|
||||||
|
tzi int
|
||||||
|
tzlen int
|
||||||
|
t *time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
func newParser(dateStr string, loc *time.Location) *parser {
|
||||||
|
p := parser{
|
||||||
|
stateDate: dateStart,
|
||||||
|
stateTime: timeIgnore,
|
||||||
|
datestr: dateStr,
|
||||||
|
loc: loc,
|
||||||
|
preferMonthFirst: true,
|
||||||
|
}
|
||||||
|
p.format = []byte(dateStr)
|
||||||
|
return &p
|
||||||
|
}
|
||||||
|
func (p *parser) set(start int, val string) {
|
||||||
|
if start < 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len(p.format) < start+len(val) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for i, r := range val {
|
||||||
|
p.format[start+i] = byte(r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (p *parser) setMonth() {
|
||||||
|
if p.molen == 2 {
|
||||||
|
p.set(p.moi, "01")
|
||||||
|
} else if p.molen == 1 {
|
||||||
|
p.set(p.moi, "1")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *parser) setDay() {
|
||||||
|
if p.daylen == 2 {
|
||||||
|
p.set(p.dayi, "02")
|
||||||
|
} else if p.daylen == 1 {
|
||||||
|
p.set(p.dayi, "2")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (p *parser) setYear() {
|
||||||
|
if p.yearlen == 2 {
|
||||||
|
p.set(p.yeari, "06")
|
||||||
|
} else if p.yearlen == 4 {
|
||||||
|
p.set(p.yeari, "2006")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (p *parser) coalesceDate(end int) {
|
||||||
|
if p.yeari > 0 {
|
||||||
|
if p.yearlen == 0 {
|
||||||
|
p.yearlen = end - p.yeari
|
||||||
|
}
|
||||||
|
p.setYear()
|
||||||
|
}
|
||||||
|
if p.moi > 0 && p.molen == 0 {
|
||||||
|
p.molen = end - p.moi
|
||||||
|
p.setMonth()
|
||||||
|
}
|
||||||
|
if p.dayi > 0 && p.daylen == 0 {
|
||||||
|
p.daylen = end - p.dayi
|
||||||
|
p.setDay()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (p *parser) ts() string {
|
||||||
|
return fmt.Sprintf("h:(%d:%d) m:(%d:%d) s:(%d:%d)", p.houri, p.hourlen, p.mini, p.minlen, p.seci, p.seclen)
|
||||||
|
}
|
||||||
|
func (p *parser) ds() string {
|
||||||
|
return fmt.Sprintf("%s d:(%d:%d) m:(%d:%d) y:(%d:%d)", p.datestr, p.dayi, p.daylen, p.moi, p.molen, p.yeari, p.yearlen)
|
||||||
|
}
|
||||||
|
func (p *parser) coalesceTime(end int) {
|
||||||
|
// 03:04:05
|
||||||
|
// 15:04:05
|
||||||
|
// 3:04:05
|
||||||
|
// 3:4:5
|
||||||
|
// 15:04:05.00
|
||||||
|
if p.houri > 0 {
|
||||||
|
if p.hourlen == 2 {
|
||||||
|
p.set(p.houri, "15")
|
||||||
|
} else if p.hourlen == 1 {
|
||||||
|
p.set(p.houri, "3")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if p.mini > 0 {
|
||||||
|
if p.minlen == 0 {
|
||||||
|
p.minlen = end - p.mini
|
||||||
|
}
|
||||||
|
if p.minlen == 2 {
|
||||||
|
p.set(p.mini, "04")
|
||||||
|
} else {
|
||||||
|
p.set(p.mini, "4")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if p.seci > 0 {
|
||||||
|
if p.seclen == 0 {
|
||||||
|
p.seclen = end - p.seci
|
||||||
|
}
|
||||||
|
if p.seclen == 2 {
|
||||||
|
p.set(p.seci, "05")
|
||||||
|
} else {
|
||||||
|
p.set(p.seci, "5")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.msi > 0 {
|
||||||
|
for i := 0; i < p.mslen; i++ {
|
||||||
|
p.format[p.msi+i] = '0'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *parser) trimExtra() {
|
||||||
|
if p.extra > 0 && len(p.format) > p.extra {
|
||||||
|
p.format = p.format[0:p.extra]
|
||||||
|
p.datestr = p.datestr[0:p.extra]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *parser) parse() (time.Time, error) {
|
||||||
|
if p.t != nil {
|
||||||
|
return *p.t, nil
|
||||||
|
}
|
||||||
|
if p.skip > 0 && len(p.format) > p.skip {
|
||||||
|
p.format = p.format[p.skip:]
|
||||||
|
p.datestr = p.datestr[p.skip:]
|
||||||
|
}
|
||||||
|
//gou.Debugf("parse %q AS %s", p.datestr, string(p.format))
|
||||||
|
if p.loc == nil {
|
||||||
|
return time.Parse(string(p.format), p.datestr)
|
||||||
|
}
|
||||||
|
return time.ParseInLocation(string(p.format), p.datestr, p.loc)
|
||||||
|
}
|
||||||
|
@ -11,8 +11,9 @@ import (
|
|||||||
func TestOne(t *testing.T) {
|
func TestOne(t *testing.T) {
|
||||||
time.Local = time.UTC
|
time.Local = time.UTC
|
||||||
var ts time.Time
|
var ts time.Time
|
||||||
ts = MustParse("sept. 28, 2017")
|
ts = MustParse("11-Jun-11 18:09:59")
|
||||||
assert.Equal(t, "2017-09-28 00:00:00 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
|
// "2016-06-29 18:09:59 +0000 UTC"
|
||||||
|
assert.Equal(t, "2011-06-11 18:09:59 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
|
||||||
}
|
}
|
||||||
|
|
||||||
type dateTest struct {
|
type dateTest struct {
|
||||||
@ -100,21 +101,25 @@ var testInputs = []dateTest{
|
|||||||
{in: "Wednesday, 2 Feb 2018 09:01:00 -0300", out: "2018-02-02 12:01:00 +0000 UTC"},
|
{in: "Wednesday, 2 Feb 2018 09:01:00 -0300", out: "2018-02-02 12:01:00 +0000 UTC"},
|
||||||
{in: "Wednesday, 2 Feb 2018 9:01:00 -0300", out: "2018-02-02 12:01:00 +0000 UTC"},
|
{in: "Wednesday, 2 Feb 2018 9:01:00 -0300", out: "2018-02-02 12:01:00 +0000 UTC"},
|
||||||
{in: "Wednesday, 2 Feb 2018 09:1:00 -0300", out: "2018-02-02 12:01:00 +0000 UTC"},
|
{in: "Wednesday, 2 Feb 2018 09:1:00 -0300", out: "2018-02-02 12:01:00 +0000 UTC"},
|
||||||
// 12 Feb 2006, 19:17:08
|
// dd mon yyyy 12 Feb 2006, 19:17:08
|
||||||
{in: "07 Feb 2004, 09:07", out: "2004-02-07 09:07:00 +0000 UTC"},
|
{in: "07 Feb 2004, 09:07", out: "2004-02-07 09:07:00 +0000 UTC"},
|
||||||
{in: "07 Feb 2004, 09:07:07", out: "2004-02-07 09:07:07 +0000 UTC"},
|
{in: "07 Feb 2004, 09:07:07", out: "2004-02-07 09:07:07 +0000 UTC"},
|
||||||
{in: "7 Feb 2004, 09:07:07", out: "2004-02-07 09:07:07 +0000 UTC"},
|
{in: "7 Feb 2004, 09:07:07", out: "2004-02-07 09:07:07 +0000 UTC"},
|
||||||
{in: "07 Feb 2004, 9:7:7", out: "2004-02-07 09:07:07 +0000 UTC"},
|
{in: "07 Feb 2004, 9:7:7", out: "2004-02-07 09:07:07 +0000 UTC"},
|
||||||
// DD Mon yyyy hh:mm:ss
|
// dd Mon yyyy hh:mm:ss
|
||||||
{in: "07 Feb 2004 09:07:08", out: "2004-02-07 09:07:08 +0000 UTC"},
|
{in: "07 Feb 2004 09:07:08", out: "2004-02-07 09:07:08 +0000 UTC"},
|
||||||
{in: "07 Feb 2004 09:07", out: "2004-02-07 09:07:00 +0000 UTC"},
|
{in: "07 Feb 2004 09:07", out: "2004-02-07 09:07:00 +0000 UTC"},
|
||||||
{in: "7 Feb 2004 9:7:8", out: "2004-02-07 09:07:08 +0000 UTC"},
|
{in: "7 Feb 2004 9:7:8", out: "2004-02-07 09:07:08 +0000 UTC"},
|
||||||
{in: "07 Feb 2004 09:07:08.123", out: "2004-02-07 09:07:08.123 +0000 UTC"},
|
{in: "07 Feb 2004 09:07:08.123", out: "2004-02-07 09:07:08.123 +0000 UTC"},
|
||||||
// 12 Feb 2006, 19:17:08 GMT
|
// dd-mon-yyyy 12 Feb 2006, 19:17:08 GMT
|
||||||
{in: "07 Feb 2004, 09:07:07 GMT", out: "2004-02-07 09:07:07 +0000 UTC"},
|
{in: "07 Feb 2004, 09:07:07 GMT", out: "2004-02-07 09:07:07 +0000 UTC"},
|
||||||
// 12 Feb 2006, 19:17:08 +0100
|
// dd-mon-yyyy 12 Feb 2006, 19:17:08 +0100
|
||||||
{in: "07 Feb 2004, 09:07:07 +0100", out: "2004-02-07 08:07:07 +0000 UTC"},
|
{in: "07 Feb 2004, 09:07:07 +0100", out: "2004-02-07 08:07:07 +0000 UTC"},
|
||||||
// 2013-Feb-03
|
// dd-mon-yyyy 12-Feb-2006 19:17:08
|
||||||
|
{in: "07-Feb-2004 09:07:07 +0100", out: "2004-02-07 08:07:07 +0000 UTC"},
|
||||||
|
// dd-mon-yy 12-Feb-2006 19:17:08
|
||||||
|
{in: "07-Feb-04 09:07:07 +0100", out: "2004-02-07 08:07:07 +0000 UTC"},
|
||||||
|
// yyyy-mon-dd 2013-Feb-03
|
||||||
{in: "2013-Feb-03", out: "2013-02-03 00:00:00 +0000 UTC"},
|
{in: "2013-Feb-03", out: "2013-02-03 00:00:00 +0000 UTC"},
|
||||||
// 03 February 2013
|
// 03 February 2013
|
||||||
{in: "03 February 2013", out: "2013-02-03 00:00:00 +0000 UTC"},
|
{in: "03 February 2013", out: "2013-02-03 00:00:00 +0000 UTC"},
|
||||||
@ -426,6 +431,9 @@ var testParseErrors = []dateTest{
|
|||||||
{in: "xyzq-baad"},
|
{in: "xyzq-baad"},
|
||||||
{in: "oct.-7-1970", err: true},
|
{in: "oct.-7-1970", err: true},
|
||||||
{in: "septe. 7, 1970", err: true},
|
{in: "septe. 7, 1970", err: true},
|
||||||
|
{in: "29-06-2016", err: true},
|
||||||
|
// this is just testing the empty space up front
|
||||||
|
{in: " 2018-01-02 17:08:09 -07:00", err: true},
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestParseErrors(t *testing.T) {
|
func TestParseErrors(t *testing.T) {
|
||||||
@ -475,6 +483,8 @@ func TestParseLayout(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var testParseStrict = []dateTest{
|
var testParseStrict = []dateTest{
|
||||||
|
// dd-mon-yy 13-Feb-03
|
||||||
|
{in: "03-03-14"},
|
||||||
// mm.dd.yyyy
|
// mm.dd.yyyy
|
||||||
{in: "3.3.2014"},
|
{in: "3.3.2014"},
|
||||||
// mm.dd.yy
|
// mm.dd.yy
|
||||||
|
Loading…
Reference in New Issue
Block a user