Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support %F, %T, and more in strptime #944

Merged
merged 3 commits into from
Feb 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 26 additions & 7 deletions internal/pkg/pbnjay-strptime/strptime.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ func MustParse(value, format string) time.Time {

// Check verifies that format is a fully-supported strptime format string for this implementation.
func Check(format string) error {
format = expandShorthands(format)

parts := strings.Split(format, "%")
for _, ps := range parts {
// since we split on '%', this is the format code
Expand All @@ -112,6 +114,8 @@ func Check(format string) error {
}

func strptime_tz(value, format string, ignoreUnsupported bool, useTZ bool, location *time.Location) (time.Time, error) {
format = expandShorthands(format)

parseStr := ""
parseFmt := ""
vi := 0
Expand Down Expand Up @@ -212,6 +216,21 @@ func strptime_tz(value, format string, ignoreUnsupported bool, useTZ bool, locat
}
}

// expandShorthands handles some shorthands that the C library uses, which we can easily
// replicate -- e.g. "%T" is "%Y-%m-%d".
func expandShorthands(format string) string {
// TODO: mem cache
format = strings.ReplaceAll(format, "%T", "%H:%M:%S")
format = strings.ReplaceAll(format, "%D", "%m/%d/%y")
format = strings.ReplaceAll(format, "%F", "%Y-%m-%d")
format = strings.ReplaceAll(format, "%R", "%H:%M")
format = strings.ReplaceAll(format, "%r", "%I:%M:%S %p")
format = strings.ReplaceAll(format, "%T", "%H:%M:%S")
// We've no %e in this package
// format = strings.ReplaceAll(format, "%v", "%e-%b-%Y")
return format
}

var (
// ErrFormatMismatch means that intervening text in the strptime format string did not
// match within the parsed string.
Expand All @@ -220,19 +239,19 @@ var (
ErrFormatUnsupported = errors.New("date format contains unsupported percent-encodings")

formatMap = map[int]string{
'd': "02",
'b': "Jan",
'B': "January",
'j': "__2",
'm': "01",
'y': "06",
'Y': "2006",
'd': "02",
'f': "999999",
'H': "15",
'I': "03",
'p': "PM",
'j': "__2",
'm': "01",
'M': "04",
'p': "PM",
'S': "05",
'f': "999999",
'y': "06",
'Y': "2006",
'z': "-0700",
'Z': "MST",
}
Expand Down
1 change: 1 addition & 0 deletions test/cases/dsl-gmt-date-time-functions/0019/cmd
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
mlr --icsv --opprint put -f ${CASEDIR}/mlr test/input/gmt2sec
Empty file.
29 changes: 29 additions & 0 deletions test/cases/dsl-gmt-date-time-functions/0019/expout
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
gmt sec
1970-01-01T00:00:00Z 0
1970-01-01T00:00:00.Z (error)
1970-01-01T00:00:01Z 1
1970-01-01T00:00:01.0Z 1
1970-01-01T00:00:10Z 10
1970-01-01T00:00:10.00Z 10
1970-01-01T00:01:40Z 100
1970-01-01T00:01:40.1Z 100.1
1970-01-01T00:16:40Z 1000
1970-01-01T00:16:40.12Z 1000.12
1970-01-01T02:46:40Z 10000
1970-01-01T02:46:40.123Z 10000.123
1970-01-02T03:46:40Z 100000
1970-01-02T03:46:40.1234Z 100000.1234
1970-01-12T13:46:40Z 1000000
1970-01-12T13:46:40.12345Z 1000000.12345
1970-04-26T17:46:40Z 10000000
1970-04-26T17:46:40.123456Z 10000000.123456
1973-03-03T09:46:40Z 100000000
1973-03-03T09:46:40.1234567Z 100000000.1234567
2001-09-09T01:46:40Z 1000000000
2001-09-09T01:46:40.12345678Z 1000000000.1234567
2015-05-19T11:49:40Z 1432036180
2015-05-19T11:49:40.123456789Z 1432036180.1234567
2017-07-14T02:40:00Z 1500000000
2017-07-14T02:40:00.999Z 1500000000.999
2033-05-18T03:33:20Z 2000000000
2033-05-18T03:33:20.999999Z 2000000000.999999
1 change: 1 addition & 0 deletions test/cases/dsl-gmt-date-time-functions/0019/mlr
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
$sec = strptime($gmt, "%FT%TZ")