From 65e246add044a60c9fe66e86a7a8b52288ba9eeb Mon Sep 17 00:00:00 2001 From: Daniel Ferstay Date: Tue, 26 Oct 2021 15:26:22 -0700 Subject: [PATCH] Add support for dd-mm-yyyy (digit month) formats Some European dates are formatted as dd-mm-yyyy where day month and year are all digits. Fixes #139 Signed-off-by: Daniel Ferstay --- parseany.go | 72 +++++++++++++++++++++++++++++++++++++++++++++++- parseany_test.go | 7 ++++- 2 files changed, 77 insertions(+), 2 deletions(-) diff --git a/parseany.go b/parseany.go index b9668b2..a389430 100644 --- a/parseany.go +++ b/parseany.go @@ -93,6 +93,8 @@ const ( dateAlphaPeriodWsDigit dateWeekdayComma dateWeekdayAbbrevComma + dateDigitDashDigit + dateDigitDashDigitDash ) const ( // Time state @@ -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) } @@ -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 @@ -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 @@ -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: diff --git a/parseany_test.go b/parseany_test.go index 7fea1e6..1249d68 100644 --- a/parseany_test.go +++ b/parseany_test.go @@ -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