Skip to content

Commit

Permalink
Add support for dd-mm-yyyy (digit month) formats
Browse files Browse the repository at this point in the history
Some European dates are formatted as dd-mm-yyyy where
day month and year are all digits.

Fixes araddon#139

Signed-off-by: Daniel Ferstay <[email protected]>
  • Loading branch information
Daniel Ferstay committed Nov 10, 2021
1 parent 6b43995 commit 65e246a
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 2 deletions.
72 changes: 71 additions & 1 deletion parseany.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ const (
dateAlphaPeriodWsDigit
dateWeekdayComma
dateWeekdayAbbrevComma
dateDigitDashDigit
dateDigitDashDigitDash
)
const (
// Time state
Expand Down Expand Up @@ -485,6 +487,9 @@ iterRunes:
if unicode.IsLetter(r) {
p.stateDate = dateDigitDashAlpha
p.moi = i
} else if unicode.IsDigit(r) {
p.stateDate = dateDigitDashDigit
p.moi = i
} else {
return nil, unknownErr(datestr)
}
Expand All @@ -499,7 +504,15 @@ iterRunes:
p.yeari = i + 1
p.stateDate = dateDigitDashAlphaDash
}

case dateDigitDashDigit:
// 29-06-2026
switch r {
case '-':
p.molen = i - p.moi
p.set(p.moi, "01")
p.yeari = i + 1
p.stateDate = dateDigitDashDigitDash
}
case dateDigitDashAlphaDash:
// 13-Feb-03 ambiguous
// 28-Feb-03 ambiguous
Expand Down Expand Up @@ -532,6 +545,36 @@ iterRunes:
p.stateTime = timeStart
break iterRunes
}
case dateDigitDashDigitDash:
// 29-06-2026
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 dateDigitYearSlash:
// 2014/07/10 06:55:38.156283
Expand Down Expand Up @@ -1844,6 +1887,33 @@ iterRunes:
p.setDay()
}

return p, nil
case dateDigitDashDigitDash:
// 13-02-03 ambiguous
// 28-02-03 ambiguous
// 29-06-2016
length := len(datestr) - (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()
}

return p, nil

case dateDigitDot:
Expand Down
7 changes: 6 additions & 1 deletion parseany_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,10 +239,15 @@ var testInputs = []dateTest{
// yyyy-mm-dd-07:00
{in: "2020-07-20+08:00", out: "2020-07-19 16:00:00 +0000 UTC"},
{in: "2020-07-20+0800", out: "2020-07-19 16:00:00 +0000 UTC"},
// dd-mmm-yy
// dd-mmm-yy (alpha month)
{in: "28-Feb-02", out: "2002-02-28 00:00:00 +0000 UTC"},
{in: "15-Jan-18", out: "2018-01-15 00:00:00 +0000 UTC"},
{in: "15-Jan-2017", out: "2017-01-15 00:00:00 +0000 UTC"},
// dd-mmm-yy (digit month)
{in: "28-02-02", out: "2002-02-28 00:00:00 +0000 UTC"}, https: //github.com/araddon/dateparse/issues/139
{in: "15-01-18", out: "2018-01-15 00:00:00 +0000 UTC"},
{in: "15-01-2017", out: "2017-01-15 00:00:00 +0000 UTC"},

// yyyy-mm
{in: "2014-04", out: "2014-04-01 00:00:00 +0000 UTC"},
// yyyy-mm-dd hh:mm:ss AM
Expand Down

0 comments on commit 65e246a

Please sign in to comment.