From 12e457bc96b4028caba017af281b70d1db47889b Mon Sep 17 00:00:00 2001 From: John Kerl Date: Mon, 7 Feb 2022 09:10:27 -0500 Subject: [PATCH] strptime %j format for 3-digit day in year (#930) * strptime %j format for 3-digit day in year * doc mods --- docs/src/manpage.md | 6 +++--- docs/src/manpage.txt | 6 +++--- docs/src/reference-dsl-builtin-functions.md | 4 ++-- internal/pkg/pbnjay-strptime/strptime.go | 11 +++++++---- man/manpage.txt | 6 +++--- man/mlr.1 | 8 ++++---- .../dsl-local-date-time-functions/strptime-j/cmd | 1 + .../dsl-local-date-time-functions/strptime-j/experr | 0 .../dsl-local-date-time-functions/strptime-j/expout | 2 ++ .../dsl-local-date-time-functions/strptime-j/mlr | 4 ++++ todo.txt | 3 ++- 11 files changed, 31 insertions(+), 20 deletions(-) create mode 100644 test/cases/dsl-local-date-time-functions/strptime-j/cmd create mode 100644 test/cases/dsl-local-date-time-functions/strptime-j/experr create mode 100644 test/cases/dsl-local-date-time-functions/strptime-j/expout create mode 100644 test/cases/dsl-local-date-time-functions/strptime-j/mlr diff --git a/docs/src/manpage.md b/docs/src/manpage.md index 354307825..3252352a4 100644 --- a/docs/src/manpage.md +++ b/docs/src/manpage.md @@ -2293,7 +2293,7 @@ FUNCTIONS FOR FILTER/PUT (class=typing #args=1) True if argument is not an array. is_not_empty - (class=typing #args=1) False if field is present in input with empty value, true otherwise + (class=typing #args=1) True if field is present in input with non-empty value, false otherwise is_not_map (class=typing #args=1) True if argument is not a map. @@ -2540,7 +2540,7 @@ FUNCTIONS FOR FILTER/PUT ssub("abc.def", ".", "X") gives "abcXdef" strftime - (class=time #args=2) Formats seconds since the epoch as timestamp. Format strings are mostly as in the C library (see "man strftime" on your system), with the Miller-specific addition of "%1S" through "%9S" which format the seconds with 1 through 9 decimal places, respectively. ("%S" uses no decimal places.) See also strftime_local. See also "DSL datetime/timezone functions" at https://miller.readthedocs.io for more information on the differences from the C library. + (class=time #args=2) Formats seconds since the epoch as timestamp. Format strings are as at https://pkg.go.dev/github.com/lestrrat-go/strftime, with the Miller-specific addition of "%1S" through "%9S" which format the seconds with 1 through 9 decimal places, respectively. ("%S" uses no decimal places.) See also "DSL datetime/timezone functions" at https://miller.readthedocs.io for more information on the differences from the C library ("man strftime" on your system). See also strftime_local. Examples: strftime(1440768801.7,"%Y-%m-%dT%H:%M:%SZ") = "2015-08-28T13:33:21Z" strftime(1440768801.7,"%Y-%m-%dT%H:%M:%3SZ") = "2015-08-28T13:33:21.700Z" @@ -3162,5 +3162,5 @@ SEE ALSO - 2022-02-06 MILLER(1) + 2022-02-07 MILLER(1) diff --git a/docs/src/manpage.txt b/docs/src/manpage.txt index 603bcd290..f952d0f09 100644 --- a/docs/src/manpage.txt +++ b/docs/src/manpage.txt @@ -2272,7 +2272,7 @@ FUNCTIONS FOR FILTER/PUT (class=typing #args=1) True if argument is not an array. is_not_empty - (class=typing #args=1) False if field is present in input with empty value, true otherwise + (class=typing #args=1) True if field is present in input with non-empty value, false otherwise is_not_map (class=typing #args=1) True if argument is not a map. @@ -2519,7 +2519,7 @@ FUNCTIONS FOR FILTER/PUT ssub("abc.def", ".", "X") gives "abcXdef" strftime - (class=time #args=2) Formats seconds since the epoch as timestamp. Format strings are mostly as in the C library (see "man strftime" on your system), with the Miller-specific addition of "%1S" through "%9S" which format the seconds with 1 through 9 decimal places, respectively. ("%S" uses no decimal places.) See also strftime_local. See also "DSL datetime/timezone functions" at https://miller.readthedocs.io for more information on the differences from the C library. + (class=time #args=2) Formats seconds since the epoch as timestamp. Format strings are as at https://pkg.go.dev/github.com/lestrrat-go/strftime, with the Miller-specific addition of "%1S" through "%9S" which format the seconds with 1 through 9 decimal places, respectively. ("%S" uses no decimal places.) See also "DSL datetime/timezone functions" at https://miller.readthedocs.io for more information on the differences from the C library ("man strftime" on your system). See also strftime_local. Examples: strftime(1440768801.7,"%Y-%m-%dT%H:%M:%SZ") = "2015-08-28T13:33:21Z" strftime(1440768801.7,"%Y-%m-%dT%H:%M:%3SZ") = "2015-08-28T13:33:21.700Z" @@ -3141,4 +3141,4 @@ SEE ALSO - 2022-02-06 MILLER(1) + 2022-02-07 MILLER(1) diff --git a/docs/src/reference-dsl-builtin-functions.md b/docs/src/reference-dsl-builtin-functions.md index c6038e044..2d19bca9f 100644 --- a/docs/src/reference-dsl-builtin-functions.md +++ b/docs/src/reference-dsl-builtin-functions.md @@ -1228,7 +1228,7 @@ sec2localtime(1234567890.123456, 6, "Asia/Istanbul") = "2009-02-14 01:31:30.1234 ### strftime
-strftime  (class=time #args=2) Formats seconds since the epoch as timestamp. Format strings are mostly as in the C library (see "man strftime" on your system), with the Miller-specific addition of "%1S" through "%9S" which format the seconds with 1 through 9 decimal places, respectively. ("%S" uses no decimal places.) See also strftime_local. See also "DSL datetime/timezone functions" at https://miller.readthedocs.io for more information on the differences from the C library.
+strftime  (class=time #args=2) Formats seconds since the epoch as timestamp. Format strings are as at https://pkg.go.dev/github.com/lestrrat-go/strftime, with the Miller-specific addition of "%1S" through "%9S" which format the seconds with 1 through 9 decimal places, respectively. ("%S" uses no decimal places.) See also "DSL datetime/timezone functions" at https://miller.readthedocs.io for more information on the differences from the C library ("man strftime" on your system). See also strftime_local.
 Examples:
 strftime(1440768801.7,"%Y-%m-%dT%H:%M:%SZ")  = "2015-08-28T13:33:21Z"
 strftime(1440768801.7,"%Y-%m-%dT%H:%M:%3SZ") = "2015-08-28T13:33:21.700Z"
@@ -1475,7 +1475,7 @@ is_not_array  (class=typing #args=1) True if argument is not an array.
 
 ### is_not_empty
 
-is_not_empty  (class=typing #args=1) False if field is present in input with empty value, true otherwise
+is_not_empty  (class=typing #args=1) True if field is present in input with non-empty value, false otherwise
 
diff --git a/internal/pkg/pbnjay-strptime/strptime.go b/internal/pkg/pbnjay-strptime/strptime.go index fdbdfc857..32e827be9 100644 --- a/internal/pkg/pbnjay-strptime/strptime.go +++ b/internal/pkg/pbnjay-strptime/strptime.go @@ -54,6 +54,8 @@ import ( "time" ) +const _ignoreUnsupported = false + // Parse accepts a percent-encoded strptime format string, converts it for use with // time.Parse, and returns the resulting time.Time value. If non-date-related format // text does not match within the string value, then ErrFormatMismatch will be returned. @@ -62,25 +64,25 @@ import ( // If a unsupported format specifier is provided, it will be ignored and matching // text will be skipped. To receive errors for unsupported formats, use ParseStrict or call Check. func Parse(value, format string) (time.Time, error) { - return strptime_tz(value, format, true, false, nil) + return strptime_tz(value, format, _ignoreUnsupported, false, nil) } // ParseLocal is like Parse except it consults the $TZ environment variable. // This is for Miller. func ParseLocal(value, format string) (time.Time, error) { - return strptime_tz(value, format, true, true, nil) + return strptime_tz(value, format, _ignoreUnsupported, true, nil) } // ParseLocation is like Parse except it uses the specified location (timezone). // This is for Miller. func ParseLocation(value, format string, location *time.Location) (time.Time, error) { - return strptime_tz(value, format, true, true, location) + return strptime_tz(value, format, _ignoreUnsupported, true, location) } // ParseStrict returns ErrFormatUnsupported for unsupported formats strings, but is otherwise // identical to Parse. func ParseStrict(value, format string) (time.Time, error) { - return strptime_tz(value, format, false, false, nil) + return strptime_tz(value, format, _ignoreUnsupported, false, nil) } // MustParse is a wrapper for Parse which panics on any error. @@ -221,6 +223,7 @@ var ( 'd': "02", 'b': "Jan", 'B': "January", + 'j': "__2", 'm': "01", 'y': "06", 'Y': "2006", diff --git a/man/manpage.txt b/man/manpage.txt index 603bcd290..f952d0f09 100644 --- a/man/manpage.txt +++ b/man/manpage.txt @@ -2272,7 +2272,7 @@ FUNCTIONS FOR FILTER/PUT (class=typing #args=1) True if argument is not an array. is_not_empty - (class=typing #args=1) False if field is present in input with empty value, true otherwise + (class=typing #args=1) True if field is present in input with non-empty value, false otherwise is_not_map (class=typing #args=1) True if argument is not a map. @@ -2519,7 +2519,7 @@ FUNCTIONS FOR FILTER/PUT ssub("abc.def", ".", "X") gives "abcXdef" strftime - (class=time #args=2) Formats seconds since the epoch as timestamp. Format strings are mostly as in the C library (see "man strftime" on your system), with the Miller-specific addition of "%1S" through "%9S" which format the seconds with 1 through 9 decimal places, respectively. ("%S" uses no decimal places.) See also strftime_local. See also "DSL datetime/timezone functions" at https://miller.readthedocs.io for more information on the differences from the C library. + (class=time #args=2) Formats seconds since the epoch as timestamp. Format strings are as at https://pkg.go.dev/github.com/lestrrat-go/strftime, with the Miller-specific addition of "%1S" through "%9S" which format the seconds with 1 through 9 decimal places, respectively. ("%S" uses no decimal places.) See also "DSL datetime/timezone functions" at https://miller.readthedocs.io for more information on the differences from the C library ("man strftime" on your system). See also strftime_local. Examples: strftime(1440768801.7,"%Y-%m-%dT%H:%M:%SZ") = "2015-08-28T13:33:21Z" strftime(1440768801.7,"%Y-%m-%dT%H:%M:%3SZ") = "2015-08-28T13:33:21.700Z" @@ -3141,4 +3141,4 @@ SEE ALSO - 2022-02-06 MILLER(1) + 2022-02-07 MILLER(1) diff --git a/man/mlr.1 b/man/mlr.1 index 1dc18c120..9fb1cf4d4 100644 --- a/man/mlr.1 +++ b/man/mlr.1 @@ -2,12 +2,12 @@ .\" Title: mlr .\" Author: [see the "AUTHOR" section] .\" Generator: ./mkman.rb -.\" Date: 2022-02-06 +.\" Date: 2022-02-07 .\" Manual: \ \& .\" Source: \ \& .\" Language: English .\" -.TH "MILLER" "1" "2022-02-06" "\ \&" "\ \&" +.TH "MILLER" "1" "2022-02-07" "\ \&" "\ \&" .\" ----------------------------------------------------------------- .\" * Portability definitions .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -3289,7 +3289,7 @@ gsub("prefix4529:suffix8567", "(....ix)([0-9]+)", "[\e1 : \e2]") gives "[prefix .RS 0 .\} .nf - (class=typing #args=1) False if field is present in input with empty value, true otherwise + (class=typing #args=1) True if field is present in input with non-empty value, false otherwise .fi .if n \{\ .RE @@ -3914,7 +3914,7 @@ ssub("abc.def", ".", "X") gives "abcXdef" .RS 0 .\} .nf - (class=time #args=2) Formats seconds since the epoch as timestamp. Format strings are mostly as in the C library (see "man strftime" on your system), with the Miller-specific addition of "%1S" through "%9S" which format the seconds with 1 through 9 decimal places, respectively. ("%S" uses no decimal places.) See also strftime_local. See also "DSL datetime/timezone functions" at https://miller.readthedocs.io for more information on the differences from the C library. + (class=time #args=2) Formats seconds since the epoch as timestamp. Format strings are as at https://pkg.go.dev/github.com/lestrrat-go/strftime, with the Miller-specific addition of "%1S" through "%9S" which format the seconds with 1 through 9 decimal places, respectively. ("%S" uses no decimal places.) See also "DSL datetime/timezone functions" at https://miller.readthedocs.io for more information on the differences from the C library ("man strftime" on your system). See also strftime_local. Examples: strftime(1440768801.7,"%Y-%m-%dT%H:%M:%SZ") = "2015-08-28T13:33:21Z" strftime(1440768801.7,"%Y-%m-%dT%H:%M:%3SZ") = "2015-08-28T13:33:21.700Z" diff --git a/test/cases/dsl-local-date-time-functions/strptime-j/cmd b/test/cases/dsl-local-date-time-functions/strptime-j/cmd new file mode 100644 index 000000000..e281b3385 --- /dev/null +++ b/test/cases/dsl-local-date-time-functions/strptime-j/cmd @@ -0,0 +1 @@ +mlr --tz UTC -n put -f ${CASEDIR}/mlr diff --git a/test/cases/dsl-local-date-time-functions/strptime-j/experr b/test/cases/dsl-local-date-time-functions/strptime-j/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/dsl-local-date-time-functions/strptime-j/expout b/test/cases/dsl-local-date-time-functions/strptime-j/expout new file mode 100644 index 000000000..7d7dd945c --- /dev/null +++ b/test/cases/dsl-local-date-time-functions/strptime-j/expout @@ -0,0 +1,2 @@ +2021-01-01 +2021-12-29 diff --git a/test/cases/dsl-local-date-time-functions/strptime-j/mlr b/test/cases/dsl-local-date-time-functions/strptime-j/mlr new file mode 100644 index 000000000..51f00ed40 --- /dev/null +++ b/test/cases/dsl-local-date-time-functions/strptime-j/mlr @@ -0,0 +1,4 @@ +end { + print strftime(strptime("001 2021", "%j %Y"),"%Y-%m-%d"); + print strftime(strptime("363 2021", "%j %Y"),"%Y-%m-%d"); +} diff --git a/todo.txt b/todo.txt index 612d33e7f..c71644ee8 100644 --- a/todo.txt +++ b/todo.txt @@ -9,6 +9,8 @@ RELEASES ? rank o fmt/unfmt/regex doc o FAQ/examples reorg + m strptime/strftime tabulate options + m unicode string literals k IANA-TSV w/ \{X} k still need csv --lazy-quotes k default colors; bold/underline/reverse @@ -16,7 +18,6 @@ RELEASES k format/unformat k split verb k slwin & shift-lead - m unicode string literals k 0o.. octal literals in the DSL k codeql/codespell/goreleaseer binaries/zips k :rb