Skip to content

Commit 2c0ba64

Browse files
Merge pull request #6 from itlightning/enhance-dateparse-example
Enhance dateparse example with flags related to ambiguous formats
2 parents eeb01af + 3df9b08 commit 2c0ba64

10 files changed

Lines changed: 146 additions & 77 deletions

File tree

.github/workflows/lint.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ jobs:
1111
name: lint
1212
runs-on: ubuntu-latest
1313
steps:
14-
- uses: actions/checkout@v2
14+
- uses: actions/checkout@v4
1515
- name: Cache-Go
16-
uses: actions/cache@v1
16+
uses: actions/cache@v4
1717
with:
1818
path: |
1919
~/go/pkg/mod # Module download cache
@@ -23,6 +23,6 @@ jobs:
2323
restore-keys: |
2424
${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
2525
- name: golangci-lint
26-
uses: golangci/golangci-lint-action@v3
26+
uses: golangci/golangci-lint-action@v7
2727
with:
2828
version: latest

.github/workflows/releaser.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,15 @@ jobs:
1010
runs-on: ubuntu-latest
1111
steps:
1212
- name: Set up Go
13-
uses: actions/setup-go@v2
13+
uses: actions/setup-go@v5
1414
with:
1515
go-version: 1.20.x
1616
- name: Checkout
17-
uses: actions/checkout@v2
17+
uses: actions/checkout@v4
1818
with:
1919
fetch-depth: 0
2020
- name: Cache-Go
21-
uses: actions/cache@v1
21+
uses: actions/cache@v4
2222
with:
2323
path: |
2424
~/go/pkg/mod # Module download cache
@@ -30,7 +30,7 @@ jobs:
3030
- name: Test
3131
run: go test ./...
3232
- name: Run GoReleaser
33-
uses: goreleaser/goreleaser-action@v5
33+
uses: goreleaser/goreleaser-action@v6
3434
with:
3535
distribution: goreleaser
3636
version: latest

.github/workflows/test.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@ jobs:
99
runs-on: ${{ matrix.os }}
1010
steps:
1111
- name: Install Go
12-
uses: actions/setup-go@v2
12+
uses: actions/setup-go@v5
1313
with:
1414
go-version: ${{ matrix.go-version }}
1515
- name: Checkout code
16-
uses: actions/checkout@v2
16+
uses: actions/checkout@v4
1717
- name: Cache-Go
18-
uses: actions/cache@v1
18+
uses: actions/cache@v4
1919
with:
2020
path: |
2121
~/go/pkg/mod # Module download cache

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
*.pprof
22
*.test
33
dist
4-
vendor
4+
vendor
5+
dateparse/dateparse

README.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Go Date Parser
66

77
Parse date/time strings without knowing the format in advance. Supports 100+ formats. Validates comprehensively to avoid false positives. Very fast (~single-pass state-machine based approach). See [bench_test.go](https://github.com/itlightning/dateparse/blob/main/bench_test.go) for performance comparison. See the critical note below about timezones.
88

9-
⚡ Maintained by [IT Lightning](https://itlightning.com/), a cloud-first logging platform that's uniquely powerful, super-easy (schemaless, point-and-shoot ingestion), and affordable. It automatically extracts and classifies structured data out of your unstructured log messages. Enjoy visual pattern-analysis and robust SQL-like search. It's unique architecture means you can log more and pay less. Check it out and give us feedback! ⚡
9+
⚡ Maintained by [SparkLogs](https://sparklogs.com/), a cloud-first logging platform that's uniquely powerful, super-easy (schemaless, point-and-shoot ingestion), and affordable. It automatically extracts and classifies structured data out of your unstructured log messages. Enjoy visual pattern-analysis and robust SQL-like search. It's unique architecture means you can log more and pay less. Check it out and give us feedback! SparkLogs is developed by [IT Lightning](https://itlightning.com/).
1010

1111
🐛💡 Find a bug or have an idea with this package? [Issues](https://github.com/itlightning/dateparse/issues) and pull requests are welcome.
1212

@@ -75,6 +75,14 @@ cli tool for testing dateformats
7575

7676
[Date Parse CLI](https://github.com/itlightning/dateparse/tree/main/dateparse)
7777

78+
Running the tests
79+
----------------------------------
80+
81+
Make sure for your Linux distribution you've installed the relevant package that includes older timezone name links (e.g., `US/Pacific`). For example, on Ubuntu:
82+
83+
```bash
84+
sudo apt install tzdata-legacy
85+
```
7886

7987
Extended example
8088
-------------------

dateparse/README.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,4 +169,44 @@ Your Using time.Local set to location=America/New_York EDT
169169
| ParseAny | time.Local = time.UTC | 2017-03-03 00:00:00 +0000 UTC | 2017-03-03 00:00:00 +0000 UTC day=5 |
170170
+-------------+---------------------------+----------------------------------------------------+----------------------------------------------------+
171171

172+
# Automatically retry date formats that are ambiguous mm/dd vs dd/mm
173+
$ ./dateparse --retry-ambiguous "28.09.2024"
174+
175+
Your Current time.Local zone is MDT
176+
177+
Layout String: dateparse.ParseFormat() => 02.01.2006
178+
179+
+-------------+-----------------------+----------------------------------------------------+----------------------------------------------------+
180+
| method | Zone Source | Parsed | Parsed: t.In(time.UTC) |
181+
+-------------+-----------------------+----------------------------------------------------+----------------------------------------------------+
182+
| ParseIn | time.Local = nil | 2024-09-28 00:00:00 +0000 UTC | 2024-09-28 00:00:00 +0000 UTC |
183+
| ParseIn | time.Local = time.UTC | 2024-09-28 00:00:00 +0000 UTC | 2024-09-28 00:00:00 +0000 UTC |
184+
| ParseLocal | time.Local = nil | 2024-09-28 00:00:00 +0000 UTC | 2024-09-28 00:00:00 +0000 UTC |
185+
| ParseLocal | time.Local = time.UTC | 2024-09-28 00:00:00 +0000 UTC | 2024-09-28 00:00:00 +0000 UTC |
186+
| ParseStrict | time.Local = nil | this date has ambiguous mm/dd vs dd/mm type format | this date has ambiguous mm/dd vs dd/mm type format |
187+
| ParseStrict | time.Local = time.UTC | this date has ambiguous mm/dd vs dd/mm type format | this date has ambiguous mm/dd vs dd/mm type format |
188+
| ParseAny | time.Local = nil | 2024-09-28 00:00:00 +0000 UTC | 2024-09-28 00:00:00 +0000 UTC day=6 |
189+
| ParseAny | time.Local = time.UTC | 2024-09-28 00:00:00 +0000 UTC | 2024-09-28 00:00:00 +0000 UTC day=6 |
190+
+-------------+-----------------------+----------------------------------------------------+----------------------------------------------------+
191+
192+
# Force dates to be interpreted as day-first instead of month-first
193+
$ ./dateparse --prefer-day-first "28.09.2024"
194+
195+
Your Current time.Local zone is MDT
196+
197+
Layout String: dateparse.ParseFormat() => 02.01.2006
198+
199+
+-------------+-----------------------+----------------------------------------------------+----------------------------------------------------+
200+
| method | Zone Source | Parsed | Parsed: t.In(time.UTC) |
201+
+-------------+-----------------------+----------------------------------------------------+----------------------------------------------------+
202+
| ParseAny | time.Local = nil | 2024-09-28 00:00:00 +0000 UTC | 2024-09-28 00:00:00 +0000 UTC day=6 |
203+
| ParseAny | time.Local = time.UTC | 2024-09-28 00:00:00 +0000 UTC | 2024-09-28 00:00:00 +0000 UTC day=6 |
204+
| ParseIn | time.Local = nil | 2024-09-28 00:00:00 +0000 UTC | 2024-09-28 00:00:00 +0000 UTC |
205+
| ParseIn | time.Local = time.UTC | 2024-09-28 00:00:00 +0000 UTC | 2024-09-28 00:00:00 +0000 UTC |
206+
| ParseLocal | time.Local = nil | 2024-09-28 00:00:00 +0000 UTC | 2024-09-28 00:00:00 +0000 UTC |
207+
| ParseLocal | time.Local = time.UTC | 2024-09-28 00:00:00 +0000 UTC | 2024-09-28 00:00:00 +0000 UTC |
208+
| ParseStrict | time.Local = nil | this date has ambiguous mm/dd vs dd/mm type format | this date has ambiguous mm/dd vs dd/mm type format |
209+
| ParseStrict | time.Local = time.UTC | this date has ambiguous mm/dd vs dd/mm type format | this date has ambiguous mm/dd vs dd/mm type format |
210+
+-------------+-----------------------+----------------------------------------------------+----------------------------------------------------+
211+
172212
```

dateparse/main.go

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,27 @@ import (
1111
)
1212

1313
var (
14-
timezone = ""
15-
datestr = ""
14+
timezone = ""
15+
datestr = ""
16+
retryAmbiguousDateWithSwap = false
17+
preferDayFirst = false
18+
parserOptions = []dateparse.ParserOption{}
1619
)
1720

21+
func buildParserOptions() {
22+
parserOptions = []dateparse.ParserOption{}
23+
if retryAmbiguousDateWithSwap {
24+
parserOptions = append(parserOptions, dateparse.RetryAmbiguousDateWithSwap(true))
25+
}
26+
if preferDayFirst {
27+
parserOptions = append(parserOptions, dateparse.PreferMonthFirst(false))
28+
}
29+
}
30+
1831
func main() {
1932
flag.StringVar(&timezone, "timezone", "", "Timezone aka `America/Los_Angeles` formatted time-zone")
33+
flag.BoolVar(&retryAmbiguousDateWithSwap, "retry-ambiguous", false, "Retry ambiguous date/time formats (day-first vs month-first)")
34+
flag.BoolVar(&preferDayFirst, "prefer-day-first", false, "Prefer day-first date format")
2035
flag.Parse()
2136

2237
if len(flag.Args()) == 0 {
@@ -25,13 +40,17 @@ func main() {
2540
./dateparse "2009-08-12T22:15:09.99Z"
2641
2742
./dateparse --timezone="America/Denver" "2017-07-19 03:21:51+00:00"
43+
./dateparse --prefer-day-first "28.09.2024"
44+
./dateparse --retry-ambiguous "28.09.2024"
2845
`)
2946
return
3047
}
3148

49+
buildParserOptions()
50+
3251
datestr = flag.Args()[0]
3352

34-
layout, err := dateparse.ParseFormat(datestr)
53+
layout, err := dateparse.ParseFormat(datestr, parserOptions...)
3554
if err != nil {
3655
fatal(err)
3756
}
@@ -82,7 +101,7 @@ type parser func(datestr string, loc *time.Location, utc bool) string
82101

83102
func parseLocal(datestr string, loc *time.Location, utc bool) string {
84103
time.Local = loc
85-
t, err := dateparse.ParseLocal(datestr)
104+
t, err := dateparse.ParseLocal(datestr, parserOptions...)
86105
if err != nil {
87106
return err.Error()
88107
}
@@ -93,7 +112,7 @@ func parseLocal(datestr string, loc *time.Location, utc bool) string {
93112
}
94113

95114
func parseIn(datestr string, loc *time.Location, utc bool) string {
96-
t, err := dateparse.ParseIn(datestr, loc)
115+
t, err := dateparse.ParseIn(datestr, loc, parserOptions...)
97116
if err != nil {
98117
return err.Error()
99118
}
@@ -104,7 +123,7 @@ func parseIn(datestr string, loc *time.Location, utc bool) string {
104123
}
105124

106125
func parseAny(datestr string, loc *time.Location, utc bool) string {
107-
t, err := dateparse.ParseAny(datestr)
126+
t, err := dateparse.ParseAny(datestr, parserOptions...)
108127
if err != nil {
109128
return err.Error()
110129
}
@@ -115,7 +134,7 @@ func parseAny(datestr string, loc *time.Location, utc bool) string {
115134
}
116135

117136
func parseStrict(datestr string, loc *time.Location, utc bool) string {
118-
t, err := dateparse.ParseStrict(datestr)
137+
t, err := dateparse.ParseStrict(datestr, parserOptions...)
119138
if err != nil {
120139
return err.Error()
121140
}

go.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@ go 1.20
44

55
require (
66
github.com/scylladb/termtables v0.0.0-20191203121021-c4c0b6d42ff4
7-
github.com/stretchr/testify v1.8.4
7+
github.com/stretchr/testify v1.10.0
88
)
99

1010
require (
1111
github.com/davecgh/go-spew v1.1.1 // indirect
12-
github.com/mattn/go-runewidth v0.0.15 // indirect
12+
github.com/mattn/go-runewidth v0.0.16 // indirect
1313
github.com/pmezard/go-difflib v1.0.0 // indirect
1414
github.com/rivo/uniseg v0.4.7 // indirect
1515
gopkg.in/yaml.v3 v3.0.1 // indirect

go.sum

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,17 @@
1-
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
2-
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
31
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
42
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
5-
github.com/mattn/go-runewidth v0.0.10 h1:CoZ3S2P7pvtP45xOtBw+/mDL2z0RKI576gSkzRRpdGg=
6-
github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
7-
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
8-
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
3+
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
4+
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
95
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
106
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
11-
github.com/rivo/uniseg v0.1.0 h1:+2KBaVoUmb9XzDsrx/Ct0W/EYOSFf/nWTauy++DprtY=
12-
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
137
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
148
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
159
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
1610
github.com/scylladb/termtables v0.0.0-20191203121021-c4c0b6d42ff4 h1:8qmTC5ByIXO3GP/IzBkxcZ/99VITvnIETDhdFz/om7A=
1711
github.com/scylladb/termtables v0.0.0-20191203121021-c4c0b6d42ff4/go.mod h1:C1a7PQSMz9NShzorzCiG2fk9+xuCgLkPeCvMHYR2OWg=
18-
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
19-
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
20-
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
21-
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
22-
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
12+
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
13+
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
2314
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
2415
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
25-
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
26-
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
2716
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
2817
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

0 commit comments

Comments
 (0)