Skip to content

Commit fc278d3

Browse files
Incorporate support for dd-mm-yyyy (digit month)
Incorporate PR araddon#140 from https://github.com/dferstay to fix araddon#139 This also fixes araddon#155 (duplicate of issue 139) PR is adapted to avoid duplicate code and validate format.
1 parent 18938f1 commit fc278d3

2 files changed

Lines changed: 88 additions & 39 deletions

File tree

parseany.go

Lines changed: 77 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -59,26 +59,28 @@ const (
5959
dateYearDash
6060
dateYearDashAlphaDash
6161
dateYearDashDash
62-
dateYearDashDashWs // 5
62+
dateYearDashDashWs // 6
6363
dateYearDashDashT
6464
dateYearDashDashOffset
6565
dateDigitDash
6666
dateDigitDashAlpha
67-
dateDigitDashAlphaDash // 10
67+
dateDigitDashAlphaDash // 11
68+
dateDigitDashDigit
69+
dateDigitDashDigitDash
6870
dateDigitDot
6971
dateDigitDotDot
7072
dateDigitSlash
7173
dateDigitYearSlash
72-
dateDigitSlashAlpha // 15
74+
dateDigitSlashAlpha // 18
7375
dateDigitColon
7476
dateDigitChineseYear
7577
dateDigitChineseYearWs
7678
dateDigitWs
77-
dateDigitWsMoYear // 20
79+
dateDigitWsMoYear // 23
7880
dateAlpha
7981
dateAlphaWs
8082
dateAlphaWsDigit
81-
dateAlphaWsDigitMore // 24
83+
dateAlphaWsDigitMore // 27
8284
dateAlphaWsDigitMoreWs
8385
dateAlphaWsDigitMoreWsYear
8486
dateAlphaWsMonth
@@ -88,7 +90,7 @@ const (
8890
dateAlphaWsMore
8991
dateAlphaWsAtTime
9092
dateAlphaWsAlpha
91-
dateAlphaWsAlphaYearmaybe // 34
93+
dateAlphaWsAlphaYearmaybe // 37
9294
dateAlphaPeriodWsDigit
9395
dateAlphaSlash
9496
dateAlphaSlashDigit
@@ -545,6 +547,9 @@ iterRunes:
545547
if unicode.IsLetter(r) {
546548
p.stateDate = dateDigitDashAlpha
547549
p.moi = i
550+
} else if unicode.IsDigit(r) {
551+
p.stateDate = dateDigitDashDigit
552+
p.moi = i
548553
} else {
549554
return p, unknownErr(datestr)
550555
}
@@ -560,10 +565,29 @@ iterRunes:
560565
p.stateDate = dateDigitDashAlphaDash
561566
}
562567

563-
case dateDigitDashAlphaDash:
564-
// 13-Feb-03 ambiguous
565-
// 28-Feb-03 ambiguous
566-
// 29-Jun-2016 dd-month(alpha)-yyyy
568+
case dateDigitDashDigit:
569+
// 29-06-2026
570+
switch r {
571+
case '-':
572+
// X
573+
// 29-06-2026
574+
p.molen = i - p.moi
575+
if p.molen == 2 {
576+
p.set(p.moi, "01")
577+
p.yeari = i + 1
578+
p.stateDate = dateDigitDashDigitDash
579+
} else {
580+
return p, unknownErr(datestr)
581+
}
582+
}
583+
584+
case dateDigitDashAlphaDash, dateDigitDashDigitDash:
585+
// dateDigitDashAlphaDash:
586+
// 13-Feb-03 ambiguous
587+
// 28-Feb-03 ambiguous
588+
// 29-Jun-2016 dd-month(alpha)-yyyy
589+
// dateDigitDashDigitDash:
590+
// 29-06-2026
567591
switch r {
568592
case ' ':
569593
// we need to find if this was 4 digits, aka year
@@ -581,8 +605,11 @@ iterRunes:
581605
} else if length == 2 {
582606
// We have no idea if this is
583607
// yy-mon-dd OR dd-mon-yy
608+
// (or for dateDigitDashDigitDash, yy-mm-dd OR dd-mm-yy)
584609
//
585-
// We are going to ASSUME (bad, bad) that it is dd-mon-yy which is a horible assumption
610+
// We are going to ASSUME (bad, bad) that it is dd-mon-yy (dd-mm-yy),
611+
// which is a horrible assumption, but seems to be the convention for
612+
// dates that are formatted in this way.
586613
p.ambiguousMD = true
587614
p.yearlen = 2
588615
p.set(p.yeari, "06")
@@ -592,6 +619,8 @@ iterRunes:
592619
if !p.setDay() {
593620
return p, unknownErr(datestr)
594621
}
622+
} else {
623+
return p, unknownErr(datestr)
595624
}
596625
p.stateTime = timeStart
597626
break iterRunes
@@ -2055,32 +2084,43 @@ iterRunes:
20552084
case dateYearDashDashT:
20562085
return p, nil
20572086

2058-
case dateDigitDashAlphaDash:
2059-
// 13-Feb-03 ambiguous
2060-
// 28-Feb-03 ambiguous
2061-
// 29-Jun-2016
2062-
length := len(p.datestr) - (p.moi + p.molen + 1)
2063-
if length == 4 {
2064-
p.yearlen = 4
2065-
p.set(p.yeari, "2006")
2066-
// We now also know that part1 was the day
2067-
p.dayi = 0
2068-
p.daylen = p.part1Len
2069-
if !p.setDay() {
2070-
return p, unknownErr(datestr)
2071-
}
2072-
} else if length == 2 {
2073-
// We have no idea if this is
2074-
// yy-mon-dd OR dd-mon-yy
2075-
//
2076-
// We are going to ASSUME (bad, bad) that it is dd-mon-yy which is a horible assumption
2077-
p.ambiguousMD = true
2078-
p.yearlen = 2
2079-
p.set(p.yeari, "06")
2080-
// We now also know that part1 was the day
2081-
p.dayi = 0
2082-
p.daylen = p.part1Len
2083-
if !p.setDay() {
2087+
case dateDigitDashAlphaDash, dateDigitDashDigitDash:
2088+
// This has already been done if we parsed the time already
2089+
if p.stateTime == timeIgnore {
2090+
// dateDigitDashAlphaDash:
2091+
// 13-Feb-03 ambiguous
2092+
// 28-Feb-03 ambiguous
2093+
// 29-Jun-2016
2094+
// dateDigitDashDigitDash:
2095+
// 29-06-2026
2096+
length := len(p.datestr) - (p.moi + p.molen + 1)
2097+
if length == 4 {
2098+
p.yearlen = 4
2099+
p.set(p.yeari, "2006")
2100+
// We now also know that part1 was the day
2101+
p.dayi = 0
2102+
p.daylen = p.part1Len
2103+
if !p.setDay() {
2104+
return p, unknownErr(datestr)
2105+
}
2106+
} else if length == 2 {
2107+
// We have no idea if this is
2108+
// yy-mon-dd OR dd-mon-yy
2109+
// (or for dateDigitDashDigitDash, yy-mm-dd OR dd-mm-yy)
2110+
//
2111+
// We are going to ASSUME (bad, bad) that it is dd-mon-yy (dd-mm-yy),
2112+
// which is a horrible assumption, but seems to be the convention for
2113+
// dates that are formatted in this way.
2114+
p.ambiguousMD = true
2115+
p.yearlen = 2
2116+
p.set(p.yeari, "06")
2117+
// We now also know that part1 was the day
2118+
p.dayi = 0
2119+
p.daylen = p.part1Len
2120+
if !p.setDay() {
2121+
return p, unknownErr(datestr)
2122+
}
2123+
} else {
20842124
return p, unknownErr(datestr)
20852125
}
20862126
}

parseany_test.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -324,10 +324,20 @@ var testInputs = []dateTest{
324324
// yyyy-mm-dd-07:00
325325
{in: "2020-07-20+08:00", out: "2020-07-19 16:00:00 +0000 UTC"},
326326
{in: "2020-07-20+0800", out: "2020-07-19 16:00:00 +0000 UTC"},
327-
// dd-mmm-yy
327+
// dd-mmm-yy (alpha month)
328328
{in: "28-Feb-02", out: "2002-02-28 00:00:00 +0000 UTC"},
329329
{in: "15-Jan-18", out: "2018-01-15 00:00:00 +0000 UTC"},
330330
{in: "15-Jan-2017", out: "2017-01-15 00:00:00 +0000 UTC"},
331+
{in: "28-Feb-02 15:16:17", out: "2002-02-28 15:16:17 +0000 UTC"},
332+
{in: "15-Jan-18 15:16:17", out: "2018-01-15 15:16:17 +0000 UTC"},
333+
{in: "15-Jan-2017 15:16:17", out: "2017-01-15 15:16:17 +0000 UTC"},
334+
// dd-mm-yy (digit month - potentially ambiguous) - https://github.com/araddon/dateparse/issues/139
335+
{in: "28-02-02", out: "2002-02-28 00:00:00 +0000 UTC"},
336+
{in: "15-01-18", out: "2018-01-15 00:00:00 +0000 UTC"},
337+
{in: "15-01-2017", out: "2017-01-15 00:00:00 +0000 UTC"},
338+
{in: "28-02-02 15:16:17", out: "2002-02-28 15:16:17 +0000 UTC"},
339+
{in: "15-01-18 15:16:17", out: "2018-01-15 15:16:17 +0000 UTC"},
340+
{in: "15-01-2017 15:16:17", out: "2017-01-15 15:16:17 +0000 UTC"},
331341
// yyyy-mm
332342
{in: "2014-04", out: "2014-04-01 00:00:00 +0000 UTC"},
333343
// yyyy-mm-dd hh:mm:ss AM
@@ -733,7 +743,6 @@ var testParseErrors = []dateTest{
733743
{in: "oct.-7-1970", err: true},
734744
{in: "septe. 7, 1970", err: true},
735745
{in: "SeptemberRR 7th, 1970", err: true},
736-
{in: "29-06-2016", err: true},
737746
// this is just testing the empty space up front
738747
{in: " 2018-01-02 17:08:09 -07:00", err: true},
739748
// a semantic version number should not be interpreted as a date

0 commit comments

Comments
 (0)