mirror of
https://github.com/araddon/dateparse.git
synced 2025-01-19 19:26:09 +08:00
Support PMDT and AMT time zones
Also disallow PM and AM from being specified twice in the string. Fixes https://github.com/araddon/dateparse/issues/149
This commit is contained in:
parent
3ebc8bc635
commit
c62ed15d73
28
parseany.go
28
parseany.go
@ -114,7 +114,6 @@ const (
|
|||||||
timeOffset
|
timeOffset
|
||||||
timeOffsetColon
|
timeOffsetColon
|
||||||
timeOffsetColonAlpha
|
timeOffsetColonAlpha
|
||||||
timeAlpha
|
|
||||||
timePeriod
|
timePeriod
|
||||||
timePeriodAMPM
|
timePeriodAMPM
|
||||||
timeZ
|
timeZ
|
||||||
@ -1350,17 +1349,22 @@ iterRunes:
|
|||||||
} else {
|
} else {
|
||||||
// Could be AM/PM
|
// Could be AM/PM
|
||||||
isLower := r == 'a' || r == 'p'
|
isLower := r == 'a' || r == 'p'
|
||||||
|
isTwoLetterWord := ((i+2) == len(p.datestr) || p.nextIs(i+1, ' '))
|
||||||
switch {
|
switch {
|
||||||
case isLower && p.nextIs(i, 'm'):
|
case isLower && p.nextIs(i, 'm') && isTwoLetterWord && !p.parsedAMPM:
|
||||||
p.coalesceTime(i)
|
p.coalesceTime(i)
|
||||||
p.set(i, "pm")
|
p.set(i, "pm")
|
||||||
|
p.parsedAMPM = true
|
||||||
// skip 'm'
|
// skip 'm'
|
||||||
i++
|
i++
|
||||||
case !isLower && p.nextIs(i, 'M'):
|
case !isLower && p.nextIs(i, 'M') && isTwoLetterWord && !p.parsedAMPM:
|
||||||
p.coalesceTime(i)
|
p.coalesceTime(i)
|
||||||
p.set(i, "PM")
|
p.set(i, "PM")
|
||||||
|
p.parsedAMPM = true
|
||||||
// skip 'M'
|
// skip 'M'
|
||||||
i++
|
i++
|
||||||
|
default:
|
||||||
|
return p, unexpectedTail(p.datestr[i:])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case ' ':
|
case ' ':
|
||||||
@ -1526,8 +1530,11 @@ iterRunes:
|
|||||||
// timeWsAlpha
|
// timeWsAlpha
|
||||||
// 00:12:00 PST
|
// 00:12:00 PST
|
||||||
// 15:44:11 UTC+0100 2015
|
// 15:44:11 UTC+0100 2015
|
||||||
if r == 'm' || r == 'M' {
|
isTwoLetterWord := ((i+1) == len(p.datestr) || p.nextIs(i, ' '))
|
||||||
//return parse("2006-01-02 03:04:05 PM", p.datestr, loc)
|
if (r == 'm' || r == 'M') && isTwoLetterWord {
|
||||||
|
if p.parsedAMPM {
|
||||||
|
return p, unexpectedTail(p.datestr[i:])
|
||||||
|
}
|
||||||
// This isn't a time zone after all...
|
// This isn't a time zone after all...
|
||||||
p.tzi = 0
|
p.tzi = 0
|
||||||
p.stateTime = timeWsAMPM
|
p.stateTime = timeWsAMPM
|
||||||
@ -1536,6 +1543,7 @@ iterRunes:
|
|||||||
} else {
|
} else {
|
||||||
p.set(i-1, "PM")
|
p.set(i-1, "PM")
|
||||||
}
|
}
|
||||||
|
p.parsedAMPM = true
|
||||||
if p.hourlen == 2 {
|
if p.hourlen == 2 {
|
||||||
p.set(p.houri, "03")
|
p.set(p.houri, "03")
|
||||||
} else if p.hourlen == 1 {
|
} else if p.hourlen == 1 {
|
||||||
@ -1668,21 +1676,26 @@ iterRunes:
|
|||||||
case 'a', 'A', 'p', 'P':
|
case 'a', 'A', 'p', 'P':
|
||||||
// Could be AM/PM
|
// Could be AM/PM
|
||||||
isLower := r == 'a' || r == 'p'
|
isLower := r == 'a' || r == 'p'
|
||||||
|
isTwoLetterWord := ((i+2) == len(p.datestr) || p.nextIs(i+1, ' '))
|
||||||
switch {
|
switch {
|
||||||
case isLower && p.nextIs(i, 'm'):
|
case isLower && p.nextIs(i, 'm') && isTwoLetterWord && !p.parsedAMPM:
|
||||||
p.mslen = i - p.msi
|
p.mslen = i - p.msi
|
||||||
p.coalesceTime(i)
|
p.coalesceTime(i)
|
||||||
p.set(i, "pm")
|
p.set(i, "pm")
|
||||||
|
p.parsedAMPM = true
|
||||||
// skip 'm'
|
// skip 'm'
|
||||||
i++
|
i++
|
||||||
p.stateTime = timePeriodAMPM
|
p.stateTime = timePeriodAMPM
|
||||||
case !isLower && p.nextIs(i, 'M'):
|
case !isLower && p.nextIs(i, 'M') && isTwoLetterWord && !p.parsedAMPM:
|
||||||
p.mslen = i - p.msi
|
p.mslen = i - p.msi
|
||||||
p.coalesceTime(i)
|
p.coalesceTime(i)
|
||||||
p.set(i, "PM")
|
p.set(i, "PM")
|
||||||
|
p.parsedAMPM = true
|
||||||
// skip 'M'
|
// skip 'M'
|
||||||
i++
|
i++
|
||||||
p.stateTime = timePeriodAMPM
|
p.stateTime = timePeriodAMPM
|
||||||
|
default:
|
||||||
|
return p, unexpectedTail(p.datestr[i:])
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
if !unicode.IsDigit(r) {
|
if !unicode.IsDigit(r) {
|
||||||
@ -2053,6 +2066,7 @@ type parser struct {
|
|||||||
formatSetLen int
|
formatSetLen int
|
||||||
datestr string
|
datestr string
|
||||||
fullMonth string
|
fullMonth string
|
||||||
|
parsedAMPM bool
|
||||||
skip int
|
skip int
|
||||||
extra int
|
extra int
|
||||||
part1Len int
|
part1Len int
|
||||||
|
@ -373,6 +373,19 @@ var testInputs = []dateTest{
|
|||||||
{in: "1 October 2022 23:59", out: "2022-10-01 23:59:00 +0000 UTC"},
|
{in: "1 October 2022 23:59", out: "2022-10-01 23:59:00 +0000 UTC"},
|
||||||
{in: "1 November 2022 23:59", out: "2022-11-01 23:59:00 +0000 UTC"},
|
{in: "1 November 2022 23:59", out: "2022-11-01 23:59:00 +0000 UTC"},
|
||||||
{in: "1 December 2022 23:59", out: "2022-12-01 23:59:00 +0000 UTC"},
|
{in: "1 December 2022 23:59", out: "2022-12-01 23:59:00 +0000 UTC"},
|
||||||
|
// https://github.com/araddon/dateparse/issues/149
|
||||||
|
{in: "2018-09-30 21:09:13 PMDT", out: "2018-09-30 21:09:13 +0000 UTC", zname: "PMDT"},
|
||||||
|
{in: "2018-09-30 08:09:13 PM PMDT", out: "2018-09-30 20:09:13 +0000 UTC", zname: "PMDT"},
|
||||||
|
{in: "2018-09-30 08:09:13pm PMDT", out: "2018-09-30 20:09:13 +0000 UTC", zname: "PMDT"},
|
||||||
|
{in: "2018-09-30 21:09:13.123 PMDT", out: "2018-09-30 21:09:13.123 +0000 UTC", zname: "PMDT"},
|
||||||
|
{in: "2018-09-30 08:09:13.123 PM PMDT", out: "2018-09-30 20:09:13.123 +0000 UTC", zname: "PMDT"},
|
||||||
|
{in: "2018-09-30 08:09:13.123pm PMDT", out: "2018-09-30 20:09:13.123 +0000 UTC", zname: "PMDT"},
|
||||||
|
{in: "2018-09-30 21:09:13 AMT", out: "2018-09-30 21:09:13 +0000 UTC", zname: "AMT"},
|
||||||
|
{in: "2018-09-30 08:09:13 AM AMT", out: "2018-09-30 08:09:13 +0000 UTC", zname: "AMT"},
|
||||||
|
{in: "2018-09-30 08:09:13am AMT", out: "2018-09-30 08:09:13 +0000 UTC", zname: "AMT"},
|
||||||
|
{in: "2018-09-30 21:09:13.123 AMT", out: "2018-09-30 21:09:13.123 +0000 UTC", zname: "AMT"},
|
||||||
|
{in: "2018-09-30 08:09:13.123 am AMT", out: "2018-09-30 08:09:13.123 +0000 UTC", zname: "AMT"},
|
||||||
|
{in: "2018-09-30 08:09:13.123am AMT", out: "2018-09-30 08:09:13.123 +0000 UTC", zname: "AMT"},
|
||||||
// yyyy-mm-dd hh:mm:ss,000
|
// yyyy-mm-dd hh:mm:ss,000
|
||||||
{in: "2014-05-11 08:20:13,787", out: "2014-05-11 08:20:13.787 +0000 UTC"},
|
{in: "2014-05-11 08:20:13,787", out: "2014-05-11 08:20:13.787 +0000 UTC"},
|
||||||
// yyyy-mm-dd hh:mm:ss +0000
|
// yyyy-mm-dd hh:mm:ss +0000
|
||||||
@ -713,6 +726,23 @@ var testParseErrors = []dateTest{
|
|||||||
{in: "Wayne, Bruce", err: true},
|
{in: "Wayne, Bruce", err: true},
|
||||||
{in: "Miami, Florida", err: true},
|
{in: "Miami, Florida", err: true},
|
||||||
{in: "Doe, John", err: true},
|
{in: "Doe, John", err: true},
|
||||||
|
// https://github.com/araddon/dateparse/issues/149
|
||||||
|
{in: "2018-09-30 21:09:13PMDT", err: true},
|
||||||
|
{in: "2018-09-30 08:09:13pm PM", err: true},
|
||||||
|
{in: "2018-09-30 08:09:13 PM PM", err: true},
|
||||||
|
{in: "2018-09-30 08:09:13 PMDT PM", err: true},
|
||||||
|
{in: "2018-09-30 21:09:13.123PMDT", err: true},
|
||||||
|
{in: "2018-09-30 08:09:13.123PM pm", err: true},
|
||||||
|
{in: "2018-09-30 08:09:13.123 pm PM", err: true},
|
||||||
|
{in: "2018-09-30 08:09:13.123 PMDT pm", err: true},
|
||||||
|
{in: "2018-09-30 21:09:13AMT", err: true},
|
||||||
|
{in: "2018-09-30 08:09:13am AM", err: true},
|
||||||
|
{in: "2018-09-30 08:09:13 AM AM", err: true},
|
||||||
|
{in: "2018-09-30 08:09:13 AMT AM", err: true},
|
||||||
|
{in: "2018-09-30 21:09:13.123AMT", err: true},
|
||||||
|
{in: "2018-09-30 08:09:13.123AM am", err: true},
|
||||||
|
{in: "2018-09-30 08:09:13.123 am AM", err: true},
|
||||||
|
{in: "2018-09-30 08:09:13.123 AMDT am", err: true},
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestParseErrors(t *testing.T) {
|
func TestParseErrors(t *testing.T) {
|
||||||
|
Loading…
Reference in New Issue
Block a user