mirror of
https://github.com/araddon/dateparse.git
synced 2025-04-11 19:30:33 +08:00
Merge 01b692d1ce4d329cac9290001673b0446acf599d into 6b43995a97dee4b2c7fc0bdff8e124da9f31a57e
This commit is contained in:
commit
8cb3a74e38
29
.github/workflows/lint.yaml
vendored
Normal file
29
.github/workflows/lint.yaml
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
name: golangci-lint
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- v*
|
||||
branches:
|
||||
- master
|
||||
- main
|
||||
pull_request:
|
||||
jobs:
|
||||
golangci:
|
||||
name: lint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Cache-Go
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: |
|
||||
~/go/pkg/mod # Module download cache
|
||||
~/.cache/go-build # Build cache (Linux)
|
||||
~/Library/Caches/go-build # Build cache (Mac)
|
||||
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||
- name: golangci-lint
|
||||
uses: golangci/golangci-lint-action@v3
|
||||
with:
|
||||
version: latest
|
39
.github/workflows/releaser.yml
vendored
Normal file
39
.github/workflows/releaser.yml
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
name: releaser
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*.*.*'
|
||||
|
||||
jobs:
|
||||
goreleaser:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: 1.19
|
||||
- name: Cache-Go
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: |
|
||||
~/go/pkg/mod # Module download cache
|
||||
~/.cache/go-build # Build cache (Linux)
|
||||
~/Library/Caches/go-build # Build cache (Mac)
|
||||
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||
- name: Test
|
||||
run: go test ./...
|
||||
- name: Run GoReleaser
|
||||
uses: goreleaser/goreleaser-action@v2
|
||||
with:
|
||||
distribution: goreleaser
|
||||
version: latest
|
||||
args: release --rm-dist
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
28
.github/workflows/test.yaml
vendored
Normal file
28
.github/workflows/test.yaml
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
on: [push, pull_request]
|
||||
name: Test
|
||||
jobs:
|
||||
test:
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.19.x]
|
||||
os: [ubuntu-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: ${{ matrix.go-version }}
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
- name: Cache-Go
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: |
|
||||
~/go/pkg/mod # Module download cache
|
||||
~/.cache/go-build # Build cache (Linux)
|
||||
~/Library/Caches/go-build # Build cache (Mac)
|
||||
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||
- name: Test
|
||||
run: go test ./...
|
38
.goreleaser.yml
Normal file
38
.goreleaser.yml
Normal file
@ -0,0 +1,38 @@
|
||||
project_name: dateparse
|
||||
builds:
|
||||
-
|
||||
id: "dateparse"
|
||||
binary: "dateparse"
|
||||
dir: dateparse
|
||||
-
|
||||
id: "example"
|
||||
binary: "example"
|
||||
dir: example
|
||||
archives:
|
||||
-
|
||||
format_overrides:
|
||||
- goos: windows
|
||||
format: zip
|
||||
checksum:
|
||||
name_template: 'checksums.txt'
|
||||
snapshot:
|
||||
name_template: "{{ .Tag }}-next"
|
||||
changelog:
|
||||
sort: asc
|
||||
filters:
|
||||
exclude:
|
||||
- '^docs:'
|
||||
- '^test:'
|
||||
nfpms:
|
||||
-
|
||||
vendor: dateparse
|
||||
homepage: https://github.com/araddon/dateparse
|
||||
maintainer: n/a <someone@eample.com>
|
||||
description: NA
|
||||
formats:
|
||||
- apk
|
||||
- deb
|
||||
- rpm
|
||||
release: 1
|
||||
section: default
|
||||
priority: extra
|
@ -7,7 +7,6 @@ import (
|
||||
)
|
||||
|
||||
/*
|
||||
|
||||
go test -bench Parse
|
||||
|
||||
BenchmarkShotgunParse 50000 37588 ns/op 13258 B/op 167 allocs/op
|
||||
@ -21,14 +20,13 @@ BenchmarkParseAny-4 200000 8627 ns/op 144 B/op 3 allo
|
||||
BenchmarkShotgunParse-8 50000 33940 ns/op 13136 B/op 169 allocs/op
|
||||
BenchmarkParseAny-8 200000 10146 ns/op 912 B/op 29 allocs/op
|
||||
BenchmarkParseDateString-8 10000 123077 ns/op 208 B/op 13 allocs/op
|
||||
|
||||
*/
|
||||
func BenchmarkShotgunParse(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
for i := 0; i < b.N; i++ {
|
||||
for _, dateStr := range testDates {
|
||||
// This is the non dateparse traditional approach
|
||||
parseShotgunStyle(dateStr)
|
||||
_, _ = parseShotgunStyle(dateStr)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -37,7 +35,7 @@ func BenchmarkParseAny(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
for i := 0; i < b.N; i++ {
|
||||
for _, dateStr := range testDates {
|
||||
ParseAny(dateStr)
|
||||
_, _ = ParseAny(dateStr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
11
go.mod
11
go.mod
@ -1,9 +1,16 @@
|
||||
module github.com/araddon/dateparse
|
||||
|
||||
go 1.12
|
||||
go 1.19
|
||||
|
||||
require (
|
||||
github.com/mattn/go-runewidth v0.0.10 // indirect
|
||||
github.com/scylladb/termtables v0.0.0-20191203121021-c4c0b6d42ff4
|
||||
github.com/stretchr/testify v1.7.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.0 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.10 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/rivo/uniseg v0.1.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect
|
||||
)
|
||||
|
1
go.sum
1
go.sum
@ -8,7 +8,6 @@ github.com/rivo/uniseg v0.1.0 h1:+2KBaVoUmb9XzDsrx/Ct0W/EYOSFf/nWTauy++DprtY=
|
||||
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/scylladb/termtables v0.0.0-20191203121021-c4c0b6d42ff4 h1:8qmTC5ByIXO3GP/IzBkxcZ/99VITvnIETDhdFz/om7A=
|
||||
github.com/scylladb/termtables v0.0.0-20191203121021-c4c0b6d42ff4/go.mod h1:C1a7PQSMz9NShzorzCiG2fk9+xuCgLkPeCvMHYR2OWg=
|
||||
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
|
100
parseany.go
100
parseany.go
@ -133,11 +133,12 @@ const (
|
||||
var (
|
||||
// ErrAmbiguousMMDD for date formats such as 04/02/2014 the mm/dd vs dd/mm are
|
||||
// ambiguous, so it is an error for strict parse rules.
|
||||
ErrAmbiguousMMDD = fmt.Errorf("This date has ambiguous mm/dd vs dd/mm type format")
|
||||
ErrAmbiguousMMDD = fmt.Errorf("this date has ambiguous mm/dd vs dd/mm type format")
|
||||
ErrCouldntFindFormat = fmt.Errorf("could not find format for")
|
||||
)
|
||||
|
||||
func unknownErr(datestr string) error {
|
||||
return fmt.Errorf("Could not find format for %q", datestr)
|
||||
return fmt.Errorf("%w %q", ErrCouldntFindFormat, datestr)
|
||||
}
|
||||
|
||||
// ParseAny parse an unknown date format, detect the layout.
|
||||
@ -170,15 +171,14 @@ func ParseIn(datestr string, loc *time.Location, opts ...ParserOption) (time.Tim
|
||||
// Set Location to time.Local. Same as ParseIn Location but lazily uses
|
||||
// the global time.Local variable for Location argument.
|
||||
//
|
||||
// denverLoc, _ := time.LoadLocation("America/Denver")
|
||||
// time.Local = denverLoc
|
||||
// denverLoc, _ := time.LoadLocation("America/Denver")
|
||||
// time.Local = denverLoc
|
||||
//
|
||||
// t, err := dateparse.ParseLocal("3/1/2014")
|
||||
// t, err := dateparse.ParseLocal("3/1/2014")
|
||||
//
|
||||
// Equivalent to:
|
||||
//
|
||||
// t, err := dateparse.ParseIn("3/1/2014", denverLoc)
|
||||
//
|
||||
// t, err := dateparse.ParseIn("3/1/2014", denverLoc)
|
||||
func ParseLocal(datestr string, opts ...ParserOption) (time.Time, error) {
|
||||
p, err := parseTime(datestr, time.Local, opts...)
|
||||
if err != nil {
|
||||
@ -204,9 +204,8 @@ func MustParse(datestr string, opts ...ParserOption) time.Time {
|
||||
// ParseFormat parse's an unknown date-time string and returns a layout
|
||||
// string that can parse this (and exact same format) other date-time strings.
|
||||
//
|
||||
// layout, err := dateparse.ParseFormat("2013-02-01 00:00:00")
|
||||
// // layout = "2006-01-02 15:04:05"
|
||||
//
|
||||
// layout, err := dateparse.ParseFormat("2013-02-01 00:00:00")
|
||||
// // layout = "2006-01-02 15:04:05"
|
||||
func ParseFormat(datestr string, opts ...ParserOption) (string, error) {
|
||||
p, err := parseTime(datestr, nil, opts...)
|
||||
if err != nil {
|
||||
@ -234,7 +233,10 @@ func ParseStrict(datestr string, opts ...ParserOption) (time.Time, error) {
|
||||
|
||||
func parseTime(datestr string, loc *time.Location, opts ...ParserOption) (p *parser, err error) {
|
||||
|
||||
p = newParser(datestr, loc, opts...)
|
||||
p, err = newParser(datestr, loc, opts...)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if p.retryAmbiguousDateWithSwap {
|
||||
// month out of range signifies that a day/month swap is the correct solution to an ambiguous date
|
||||
// this is because it means that a day is being interpreted as a month and overflowing the valid value for that
|
||||
@ -250,7 +252,7 @@ func parseTime(datestr string, loc *time.Location, opts ...ParserOption) (p *par
|
||||
// turn off the retry to avoid endless recursion
|
||||
retryAmbiguousDateWithSwap := RetryAmbiguousDateWithSwap(false)
|
||||
modifiedOpts := append(opts, preferMonthFirst, retryAmbiguousDateWithSwap)
|
||||
p, err = parseTime(datestr, time.Local, modifiedOpts...)
|
||||
p, _ = parseTime(datestr, time.Local, modifiedOpts...)
|
||||
}
|
||||
}
|
||||
|
||||
@ -268,7 +270,7 @@ iterRunes:
|
||||
//r := rune(datestr[i])
|
||||
r, bytesConsumed := utf8.DecodeRuneInString(datestr[i:])
|
||||
if bytesConsumed > 1 {
|
||||
i += (bytesConsumed - 1)
|
||||
i += bytesConsumed - 1
|
||||
}
|
||||
|
||||
// gou.Debugf("i=%d r=%s state=%d %s", i, string(r), p.stateDate, datestr)
|
||||
@ -467,8 +469,6 @@ iterRunes:
|
||||
switch r {
|
||||
case ':':
|
||||
p.set(p.offseti, "-07:00")
|
||||
// case ' ':
|
||||
// return nil, unknownErr(datestr)
|
||||
}
|
||||
|
||||
case dateYearDashAlphaDash:
|
||||
@ -538,7 +538,9 @@ iterRunes:
|
||||
// I honestly don't know if this format ever shows up as yyyy/
|
||||
|
||||
switch r {
|
||||
case ' ', ':':
|
||||
case ' ':
|
||||
fallthrough
|
||||
case ':':
|
||||
p.stateTime = timeStart
|
||||
if p.daylen == 0 {
|
||||
p.daylen = i - p.dayi
|
||||
@ -566,7 +568,9 @@ iterRunes:
|
||||
}
|
||||
// We aren't breaking because we are going to re-use this case
|
||||
// to find where the date starts, and possible time begins
|
||||
case ' ', ':':
|
||||
case ' ':
|
||||
fallthrough
|
||||
case ':':
|
||||
p.stateTime = timeStart
|
||||
if p.yearlen == 0 {
|
||||
p.yearlen = i - p.yeari
|
||||
@ -925,7 +929,9 @@ iterRunes:
|
||||
switch r {
|
||||
case '\'':
|
||||
p.yeari = i + 1
|
||||
case ' ', ',':
|
||||
case ' ':
|
||||
fallthrough
|
||||
case ',':
|
||||
// x
|
||||
// May 8, 2009 5:57:51 PM
|
||||
// x
|
||||
@ -941,7 +947,9 @@ iterRunes:
|
||||
// April 8, 2009
|
||||
// April 8 2009
|
||||
switch r {
|
||||
case ' ', ',':
|
||||
case ' ':
|
||||
fallthrough
|
||||
case ',':
|
||||
// x
|
||||
// June 8, 2009
|
||||
// x
|
||||
@ -1066,7 +1074,9 @@ iterRunes:
|
||||
p.dayi = i
|
||||
}
|
||||
switch r {
|
||||
case ' ', '-':
|
||||
case ' ':
|
||||
fallthrough
|
||||
case '-':
|
||||
if p.moi == 0 {
|
||||
p.moi = i + 1
|
||||
p.daylen = i - p.dayi
|
||||
@ -1087,8 +1097,15 @@ iterRunes:
|
||||
// Thu, 4 Jan 2018 17:53:36 +0000
|
||||
// Tue, 11 Jul 2017 16:28:13 +0200 (CEST)
|
||||
// Mon, 02-Jan-06 15:04:05 MST
|
||||
var offset int
|
||||
switch r {
|
||||
case ' ', '-':
|
||||
case ' ':
|
||||
for i+1 < len(datestr) && datestr[i+1] == ' ' {
|
||||
i++
|
||||
offset++
|
||||
}
|
||||
fallthrough
|
||||
case '-':
|
||||
if p.dayi == 0 {
|
||||
p.dayi = i + 1
|
||||
} else if p.moi == 0 {
|
||||
@ -1096,11 +1113,11 @@ iterRunes:
|
||||
p.setDay()
|
||||
p.moi = i + 1
|
||||
} else if p.yeari == 0 {
|
||||
p.molen = i - p.moi
|
||||
p.molen = i - p.moi - offset
|
||||
p.set(p.moi, "Jan")
|
||||
p.yeari = i + 1
|
||||
} else {
|
||||
p.yearlen = i - p.yeari
|
||||
p.yearlen = i - p.yeari - offset
|
||||
p.setYear()
|
||||
p.stateTime = timeStart
|
||||
break iterRunes
|
||||
@ -1328,7 +1345,12 @@ iterRunes:
|
||||
// 15:44:11 UTC+0100 2015
|
||||
switch r {
|
||||
case '+', '-':
|
||||
p.tzlen = i - p.tzi
|
||||
if datestr[p.tzi:i] == "GMT" {
|
||||
p.tzi = 0
|
||||
p.tzlen = 0
|
||||
} else {
|
||||
p.tzlen = i - p.tzi
|
||||
}
|
||||
if p.tzlen == 4 {
|
||||
p.set(p.tzi, " MST")
|
||||
} else if p.tzlen == 3 {
|
||||
@ -1439,7 +1461,6 @@ iterRunes:
|
||||
if datestr[i-1] == 'm' {
|
||||
p.extra = i - 2
|
||||
p.trimExtra()
|
||||
break
|
||||
}
|
||||
case '+', '-', '(':
|
||||
// This really doesn't seem valid, but for some reason when round-tripping a go date
|
||||
@ -1449,7 +1470,6 @@ iterRunes:
|
||||
p.extra = i - 1
|
||||
p.stateTime = timeWsOffset
|
||||
p.trimExtra()
|
||||
break
|
||||
default:
|
||||
switch {
|
||||
case unicode.IsDigit(r):
|
||||
@ -1596,7 +1616,6 @@ iterRunes:
|
||||
// 00:00:00.000 +0300 +0300
|
||||
p.extra = i - 1
|
||||
p.trimExtra()
|
||||
break
|
||||
default:
|
||||
if unicode.IsLetter(r) {
|
||||
// 00:07:31.945167 +0000 UTC
|
||||
@ -1665,10 +1684,13 @@ iterRunes:
|
||||
p.trimExtra()
|
||||
case timeWsAlphaZoneOffset:
|
||||
// 06:20:00 UTC-05
|
||||
if i-p.offseti < 4 {
|
||||
switch i - p.offseti {
|
||||
case 2, 3, 4:
|
||||
p.set(p.offseti, "-07")
|
||||
} else {
|
||||
case 5:
|
||||
p.set(p.offseti, "-0700")
|
||||
case 6:
|
||||
p.set(p.offseti, "-07:00")
|
||||
}
|
||||
|
||||
case timePeriod:
|
||||
@ -1982,7 +2004,6 @@ type parser struct {
|
||||
msi int
|
||||
mslen int
|
||||
offseti int
|
||||
offsetlen int
|
||||
tzi int
|
||||
tzlen int
|
||||
t *time.Time
|
||||
@ -2008,7 +2029,7 @@ func RetryAmbiguousDateWithSwap(retryAmbiguousDateWithSwap bool) ParserOption {
|
||||
}
|
||||
}
|
||||
|
||||
func newParser(dateStr string, loc *time.Location, opts ...ParserOption) *parser {
|
||||
func newParser(dateStr string, loc *time.Location, opts ...ParserOption) (*parser, error) {
|
||||
p := &parser{
|
||||
stateDate: dateStart,
|
||||
stateTime: timeIgnore,
|
||||
@ -2021,9 +2042,11 @@ func newParser(dateStr string, loc *time.Location, opts ...ParserOption) *parser
|
||||
|
||||
// allow the options to mutate the parser fields from their defaults
|
||||
for _, option := range opts {
|
||||
option(p)
|
||||
if err := option(p); err != nil {
|
||||
return nil, fmt.Errorf("option error: %w", err)
|
||||
}
|
||||
}
|
||||
return p
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func (p *parser) nextIs(i int, b byte) bool {
|
||||
@ -2141,17 +2164,6 @@ func (p *parser) trimExtra() {
|
||||
}
|
||||
}
|
||||
|
||||
// func (p *parser) remove(i, length int) {
|
||||
// if len(p.format) > i+length {
|
||||
// //append(a[:i], a[j:]...)
|
||||
// p.format = append(p.format[0:i], p.format[i+length:]...)
|
||||
// }
|
||||
// if len(p.datestr) > i+length {
|
||||
// //append(a[:i], a[j:]...)
|
||||
// p.datestr = fmt.Sprintf("%s%s", p.datestr[0:i], p.datestr[i+length:])
|
||||
// }
|
||||
// }
|
||||
|
||||
func (p *parser) parse() (time.Time, error) {
|
||||
if p.t != nil {
|
||||
return *p.t, nil
|
||||
|
100
parseany_test.go
100
parseany_test.go
@ -10,8 +10,7 @@ import (
|
||||
|
||||
func TestOne(t *testing.T) {
|
||||
time.Local = time.UTC
|
||||
var ts time.Time
|
||||
ts = MustParse("2020-07-20+08:00")
|
||||
var ts = MustParse("2020-07-20+08:00")
|
||||
assert.Equal(t, "2020-07-19 16:00:00 +0000 UTC", fmt.Sprintf("%v", ts.In(time.UTC)))
|
||||
}
|
||||
|
||||
@ -417,6 +416,10 @@ var testInputs = []dateTest{
|
||||
{in: "1384216367111", out: "2013-11-12 00:32:47.111 +0000 UTC"},
|
||||
{in: "1384216367111222", out: "2013-11-12 00:32:47.111222 +0000 UTC"},
|
||||
{in: "1384216367111222333", out: "2013-11-12 00:32:47.111222333 +0000 UTC"},
|
||||
|
||||
{in: "Wed, 8 Feb 2023 19:00:46 +1100 (AEDT)", out: "2023-02-08 08:00:46 +0000 UTC"},
|
||||
{in: "FRI, 16 AUG 2013 9:39:51 +1000", out: "2013-08-15 23:39:51 +0000 UTC"},
|
||||
{in: "Mon, 1 Dec 2008 14:48:22 GMT-07:00", out: "2008-12-01 21:48:22 +0000 UTC"},
|
||||
}
|
||||
|
||||
func TestParse(t *testing.T) {
|
||||
@ -425,52 +428,70 @@ func TestParse(t *testing.T) {
|
||||
time.Local = time.UTC
|
||||
|
||||
zeroTime := time.Time{}.Unix()
|
||||
ts, err := ParseAny("INVALID")
|
||||
assert.Equal(t, zeroTime, ts.Unix())
|
||||
assert.NotEqual(t, nil, err)
|
||||
t.Run("Invalid", func(t *testing.T) {
|
||||
ts, err := ParseAny("INVALID")
|
||||
assert.Equal(t, zeroTime, ts.Unix())
|
||||
assert.NotEqual(t, nil, err)
|
||||
|
||||
assert.Equal(t, true, testDidPanic("NOT GONNA HAPPEN"))
|
||||
// https://github.com/golang/go/issues/5294
|
||||
_, err = ParseAny(time.RFC3339)
|
||||
assert.NotEqual(t, nil, err)
|
||||
assert.Equal(t, true, testDidPanic("NOT GONNA HAPPEN"))
|
||||
// https://github.com/golang/go/issues/5294
|
||||
_, err = ParseAny(time.RFC3339)
|
||||
assert.NotEqual(t, nil, err)
|
||||
})
|
||||
|
||||
for _, th := range testInputs {
|
||||
if len(th.loc) > 0 {
|
||||
loc, err := time.LoadLocation(th.loc)
|
||||
if err != nil {
|
||||
t.Fatalf("Expected to load location %q but got %v", th.loc, err)
|
||||
t.Run(th.in, func(t *testing.T) {
|
||||
var ts time.Time
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
t.Fatalf("error: %s", r)
|
||||
}
|
||||
}()
|
||||
if len(th.loc) > 0 {
|
||||
loc, err := time.LoadLocation(th.loc)
|
||||
if err != nil {
|
||||
t.Fatalf("Expected to load location %q but got %v", th.loc, err)
|
||||
}
|
||||
ts, err = ParseIn(th.in, loc)
|
||||
if err != nil {
|
||||
t.Fatalf("expected to parse %q but got %v", th.in, err)
|
||||
}
|
||||
got := fmt.Sprintf("%v", ts.In(time.UTC))
|
||||
assert.Equal(t, th.out, got, "Expected %q but got %q from %q", th.out, got, th.in)
|
||||
if th.out != got {
|
||||
t.Fatalf("whoops, got %s, expected %s", got, th.out)
|
||||
}
|
||||
} else {
|
||||
ts = MustParse(th.in)
|
||||
got := fmt.Sprintf("%v", ts.In(time.UTC))
|
||||
assert.Equal(t, th.out, got, "Expected %q but got %q from %q", th.out, got, th.in)
|
||||
if th.out != got {
|
||||
t.Fatalf("whoops, got %s, expected %s", got, th.out)
|
||||
}
|
||||
}
|
||||
ts, err = ParseIn(th.in, loc)
|
||||
if err != nil {
|
||||
t.Fatalf("expected to parse %q but got %v", th.in, err)
|
||||
}
|
||||
got := fmt.Sprintf("%v", ts.In(time.UTC))
|
||||
assert.Equal(t, th.out, got, "Expected %q but got %q from %q", th.out, got, th.in)
|
||||
if th.out != got {
|
||||
panic("whoops")
|
||||
}
|
||||
} else {
|
||||
ts = MustParse(th.in)
|
||||
got := fmt.Sprintf("%v", ts.In(time.UTC))
|
||||
assert.Equal(t, th.out, got, "Expected %q but got %q from %q", th.out, got, th.in)
|
||||
if th.out != got {
|
||||
panic("whoops")
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// some errors
|
||||
|
||||
assert.Equal(t, true, testDidPanic(`{"ts":"now"}`))
|
||||
t.Run("", func(t *testing.T) {
|
||||
assert.Equal(t, true, testDidPanic(`{"ts":"now"}`))
|
||||
})
|
||||
|
||||
_, err = ParseAny("138421636711122233311111") // too many digits
|
||||
assert.NotEqual(t, nil, err)
|
||||
t.Run("too many digits", func(t *testing.T) {
|
||||
_, err := ParseAny("138421636711122233311111") // too many digits
|
||||
assert.NotEqual(t, nil, err)
|
||||
})
|
||||
|
||||
_, err = ParseAny("-1314")
|
||||
assert.NotEqual(t, nil, err)
|
||||
t.Run("negative number", func(t *testing.T) {
|
||||
_, err := ParseAny("-1314")
|
||||
assert.NotEqual(t, nil, err)
|
||||
})
|
||||
|
||||
_, err = ParseAny("2014-13-13 08:20:13,787") // month 13 doesn't exist so error
|
||||
assert.NotEqual(t, nil, err)
|
||||
t.Run("month doesn't exist", func(t *testing.T) {
|
||||
_, err := ParseAny("2014-13-13 08:20:13,787") // month 13 doesn't exist so error
|
||||
assert.NotEqual(t, nil, err)
|
||||
})
|
||||
}
|
||||
|
||||
func testDidPanic(datestr string) (paniced bool) {
|
||||
@ -488,7 +509,10 @@ func TestPStruct(t *testing.T) {
|
||||
denverLoc, err := time.LoadLocation("America/Denver")
|
||||
assert.Equal(t, nil, err)
|
||||
|
||||
p := newParser("08.21.71", denverLoc)
|
||||
p, err := newParser("08.21.71", denverLoc)
|
||||
if err != nil {
|
||||
t.Fatalf("Parser build error: %s", err)
|
||||
}
|
||||
|
||||
p.setMonth()
|
||||
assert.Equal(t, 0, p.moi)
|
||||
|
Loading…
x
Reference in New Issue
Block a user