Add DSL functions for integer nanoseconds since the epoch (#1326)

* DSL functions for 64-bit nano-epoch timestamps

* strfntime

* nsec2gmt; move sec/nsec pairs adjacent to one another

* update on-line help

* artifacts from `make dev`

* unit-test files
This commit is contained in:
John Kerl 2023-06-24 17:05:15 -04:00 committed by GitHub
parent 4c0731d395
commit d72ef826fb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
112 changed files with 1805 additions and 173 deletions

View file

@ -211,21 +211,23 @@ MILLER(1) MILLER(1)
capitalize cbrt ceil clean_whitespace collapse_whitespace concat cos cosh capitalize cbrt ceil clean_whitespace collapse_whitespace concat cos cosh
depth dhms2fsec dhms2sec erf erfc every exec exp expm1 flatten float floor depth dhms2fsec dhms2sec erf erfc every exec exp expm1 flatten float floor
fmtifnum fmtnum fold format fsec2dhms fsec2hms get_keys get_values fmtifnum fmtnum fold format fsec2dhms fsec2hms get_keys get_values
gmt2localtime gmt2sec gssub gsub haskey hexfmt hms2fsec hms2sec hostname index gmt2localtime gmt2nsec gmt2sec gssub gsub haskey hexfmt hms2fsec hms2sec
int invqnorm is_absent is_array is_bool is_boolean is_empty is_empty_map hostname index int invqnorm is_absent is_array is_bool is_boolean is_empty
is_error is_float is_int is_map is_nan is_nonempty_map is_not_array is_empty_map is_error is_float is_int is_map is_nan is_nonempty_map
is_not_empty is_not_map is_not_null is_null is_numeric is_present is_string is_not_array is_not_empty is_not_map is_not_null is_null is_numeric is_present
joink joinkv joinv json_parse json_stringify latin1_to_utf8 leafcount leftpad is_string joink joinkv joinv json_parse json_stringify latin1_to_utf8
length localtime2gmt localtime2sec log log10 log1p logifit lstrip madd mapdiff leafcount leftpad length localtime2gmt localtime2nsec localtime2sec log log10
mapexcept mapselect mapsum max md5 mexp min mmul msub os pow qnorm reduce log1p logifit lstrip madd mapdiff mapexcept mapselect mapsum max md5 mexp min
regextract regextract_or_else rightpad round roundm rstrip sec2dhms sec2gmt mmul msub nsec2gmt nsec2gmtdate nsec2localdate nsec2localtime os pow qnorm
sec2gmtdate sec2hms sec2localdate sec2localtime select sgn sha1 sha256 sha512 reduce regextract regextract_or_else rightpad round roundm rstrip sec2dhms
sin sinh sort splita splitax splitkv splitkvx splitnv splitnvx sqrt ssub sec2gmt sec2gmtdate sec2hms sec2localdate sec2localtime select sgn sha1 sha256
strftime strftime_local string strip strlen strptime strptime_local sub substr sha512 sin sinh sort splita splitax splitkv splitkvx splitnv splitnvx sqrt
substr0 substr1 system systime systimeint tan tanh tolower toupper truncate ssub strfntime strfntime_local strftime strftime_local string strip strlen
typeof unflatten unformat unformatx uptime urand urand32 urandelement urandint strpntime strpntime_local strptime strptime_local sub substr substr0 substr1
urandrange utf8_to_latin1 version ! != !=~ % & && * ** + - . .* .+ .- ./ / // sysntime system systime systimeint tan tanh tolower toupper truncate typeof
< << <= <=> == =~ > >= >> >>> ?: ?? ??? ^ ^^ | || ~ unflatten unformat unformatx upntime uptime urand urand32 urandelement
urandint urandrange utf8_to_latin1 version ! != !=~ % & && * ** + - . .* .+ .-
./ / // < << <= <=> == =~ > >= >> >>> ?: ?? ??? ^ ^^ | || ~
1mCOMMENTS-IN-DATA FLAGS0m 1mCOMMENTS-IN-DATA FLAGS0m
Miller lets you put comments in your data, such as Miller lets you put comments in your data, such as
@ -1210,13 +1212,13 @@ MILLER(1) MILLER(1)
Note that "mlr filter" is more powerful, but requires you to know field names. Note that "mlr filter" is more powerful, but requires you to know field names.
By contrast, "mlr grep" allows you to regex-match the entire record. It does this By contrast, "mlr grep" allows you to regex-match the entire record. It does this
by formatting each record in memory as DKVP (or NIDX, if -a is supplied), using by formatting each record in memory as DKVP (or NIDX, if -a is supplied), using
OFS "," and OPS "=", and matching the resulting line against the regex specified command-line-specified ORS/OFS/OPS, and matching the resulting line against the
here. In particular, the regex is not applied to the input stream: if you have regex specified here. In particular, the regex is not applied to the input
CSV with header line "x,y,z" and data line "1,2,3" then the regex will be stream: if you have CSV with header line "x,y,z" and data line "1,2,3" then the
matched, not against either of these lines, but against the DKVP line regex will be matched, not against either of these lines, but against the DKVP
"x=1,y=2,z=3". Furthermore, not all the options to system grep are supported, line "x=1,y=2,z=3". Furthermore, not all the options to system grep are
and this command is intended to be merely a keystroke-saver. To get all the supported, and this command is intended to be merely a keystroke-saver. To get
features of system grep, you can do all the features of system grep, you can do
"mlr --odkvp ... | grep ... | mlr --idkvp ..." "mlr --odkvp ... | grep ... | mlr --idkvp ..."
1mgroup-by0m 1mgroup-by0m
@ -2353,6 +2355,11 @@ MILLER(1) MILLER(1)
gmt2localtime("1999-12-31T22:00:00Z") = "2000-01-01 00:00:00" with TZ="Asia/Istanbul" gmt2localtime("1999-12-31T22:00:00Z") = "2000-01-01 00:00:00" with TZ="Asia/Istanbul"
gmt2localtime("1999-12-31T22:00:00Z", "Asia/Istanbul") = "2000-01-01 00:00:00" gmt2localtime("1999-12-31T22:00:00Z", "Asia/Istanbul") = "2000-01-01 00:00:00"
1mgmt2nsec0m
(class=time #args=1) Parses GMT timestamp as integer nanoseconds since the epoch.
Example:
gmt2nsec("2001-02-03T04:05:06Z") = 981173106000000000
1mgmt2sec0m 1mgmt2sec0m
(class=time #args=1) Parses GMT timestamp as integer seconds since the epoch. (class=time #args=1) Parses GMT timestamp as integer seconds since the epoch.
Example: Example:
@ -2518,6 +2525,12 @@ MILLER(1) MILLER(1)
localtime2gmt("2000-01-01 00:00:00") = "1999-12-31T22:00:00Z" with TZ="Asia/Istanbul" localtime2gmt("2000-01-01 00:00:00") = "1999-12-31T22:00:00Z" with TZ="Asia/Istanbul"
localtime2gmt("2000-01-01 00:00:00", "Asia/Istanbul") = "1999-12-31T22:00:00Z" localtime2gmt("2000-01-01 00:00:00", "Asia/Istanbul") = "1999-12-31T22:00:00Z"
1mlocaltime2nsec0m
(class=time #args=1,2) Parses local timestamp as integer nanoseconds since the epoch. Consults $TZ environment variable, unless second argument is supplied.
Examples:
localtime2nsec("2001-02-03 04:05:06") = 981165906000000000 with TZ="Asia/Istanbul"
localtime2nsec("2001-02-03 04:05:06", "Asia/Istanbul") = 981165906000000000"
1mlocaltime2sec0m 1mlocaltime2sec0m
(class=time #args=1,2) Parses local timestamp as integer seconds since the epoch. Consults $TZ environment variable, unless second argument is supplied. (class=time #args=1,2) Parses local timestamp as integer seconds since the epoch. Consults $TZ environment variable, unless second argument is supplied.
Examples: Examples:
@ -2572,6 +2585,32 @@ MILLER(1) MILLER(1)
1mmsub0m 1mmsub0m
(class=arithmetic #args=3) a - b mod m (integers) (class=arithmetic #args=3) a - b mod m (integers)
1mnsec2gmt0m
(class=time #args=1,2) Formats integer nanoseconds since epoch as GMT timestamp. Leaves non-numbers as-is. With second integer argument n, includes n decimal places for the seconds part.
Examples:
nsec2gmt(1234567890000000000) = "2009-02-13T23:31:30Z"
nsec2gmt(1234567890123456789) = "2009-02-13T23:31:30Z"
nsec2gmt(1234567890123456789, 6) = "2009-02-13T23:31:30.123456Z"
1mnsec2gmtdate0m
(class=time #args=1) Formats integer nanoseconds since epoch as GMT timestamp with year-month-date. Leaves non-numbers as-is.
Example:
sec2gmtdate(1440768801700000000) = "2015-08-28".
1mnsec2localdate0m
(class=time #args=1,2) Formats integer nanoseconds since epoch as local timestamp with year-month-date. Leaves non-numbers as-is. Consults $TZ environment variable unless second argument is supplied.
Examples:
nsec2localdate(1440768801700000000) = "2015-08-28" with TZ="Asia/Istanbul"
nsec2localdate(1440768801700000000, "Asia/Istanbul") = "2015-08-28"
1mnsec2localtime0m
(class=time #args=1,2,3) Formats integer nanoseconds since epoch as local timestamp. Consults $TZ environment variable unless third argument is supplied. Leaves non-numbers as-is. With second integer argument n, includes n decimal places for the seconds part
Examples:
nsec2localtime(1234567890000000000) = "2009-02-14 01:31:30" with TZ="Asia/Istanbul"
nsec2localtime(1234567890123456789) = "2009-02-14 01:31:30" with TZ="Asia/Istanbul"
nsec2localtime(1234567890123456789, 6) = "2009-02-14 01:31:30.123456" with TZ="Asia/Istanbul"
nsec2localtime(1234567890123456789, 6, "Asia/Istanbul") = "2009-02-14 01:31:30.123456"
1mos0m 1mos0m
(class=system #args=0) Returns the operating-system name as a string. (class=system #args=0) Returns the operating-system name as a string.
@ -2725,6 +2764,21 @@ MILLER(1) MILLER(1)
Example: Example:
ssub("abc.def", ".", "X") gives "abcXdef" ssub("abc.def", ".", "X") gives "abcXdef"
1mstrfntime0m
(class=time #args=2) Formats integer nanoseconds 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 https://miller.readthedocs.io/en/latest/reference-dsl-time/ for more information on the differences from the C library ("man strftime" on your system). See also strftime_local.
Examples:
strfntime(1440768801123456789,"%Y-%m-%dT%H:%M:%SZ") = "2015-08-28T13:33:21Z"
strfntime(1440768801123456789,"%Y-%m-%dT%H:%M:%3SZ") = "2015-08-28T13:33:21.123Z"
strfntime(1440768801123456789,"%Y-%m-%dT%H:%M:%6SZ") = "2015-08-28T13:33:21.123456Z"
1mstrfntime_local0m
(class=time #args=2,3) Like strfntime but consults the $TZ environment variable to get local time zone.
Examples:
strfntime_local(1440768801123456789, "%Y-%m-%d %H:%M:%S %z") = "2015-08-28 16:33:21 +0300" with TZ="Asia/Istanbul"
strfntime_local(1440768801123456789, "%Y-%m-%d %H:%M:%3S %z") = "2015-08-28 16:33:21.123 +0300" with TZ="Asia/Istanbul"
strfntime_local(1440768801123456789, "%Y-%m-%d %H:%M:%3S %z", "Asia/Istanbul") = "2015-08-28 16:33:21.123 +0300"
strfntime_local(1440768801123456789, "%Y-%m-%d %H:%M:%9S %z", "Asia/Istanbul") = "2015-08-28 16:33:21.123456789 +0300"
1mstrftime0m 1mstrftime0m
(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 https://miller.readthedocs.io/en/latest/reference-dsl-time/ for more information on the differences from the C library ("man strftime" on your system). See also strftime_local. (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 https://miller.readthedocs.io/en/latest/reference-dsl-time/ for more information on the differences from the C library ("man strftime" on your system). See also strftime_local.
Examples: Examples:
@ -2747,16 +2801,32 @@ MILLER(1) MILLER(1)
1mstrlen0m 1mstrlen0m
(class=string #args=1) String length. (class=string #args=1) String length.
1mstrpntime0m
(class=time #args=2) strpntime: Parses timestamp as integer nanoseconds since the epoch. See also strpntime_local.
Examples:
strpntime("2015-08-28T13:33:21Z", "%Y-%m-%dT%H:%M:%SZ") = 1440768801000000000
strpntime("2015-08-28T13:33:21.345Z", "%Y-%m-%dT%H:%M:%SZ") = 1440768801345000000
strpntime("1970-01-01 00:00:00 -0400", "%Y-%m-%d %H:%M:%S %z") = 14400000000000
strpntime("1970-01-01 00:00:00 +0200", "%Y-%m-%d %H:%M:%S %z") = -7200000000000
1mstrpntime_local0m
(class=time #args=2,3) Like strpntime but consults the $TZ environment variable to get local time zone.
Examples:
strpntime_local("2015-08-28T13:33:21Z", "%Y-%m-%dT%H:%M:%SZ") = 1440758001000000000 with TZ="Asia/Istanbul"
strpntime_local("2015-08-28T13:33:21.345Z","%Y-%m-%dT%H:%M:%SZ") = 1440758001345000000 with TZ="Asia/Istanbul"
strpntime_local("2015-08-28 13:33:21", "%Y-%m-%d %H:%M:%S") = 1440758001000000000 with TZ="Asia/Istanbul"
strpntime_local("2015-08-28 13:33:21", "%Y-%m-%d %H:%M:%S", "Asia/Istanbul") = 1440758001000000000
1mstrptime0m 1mstrptime0m
(class=time #args=2) strptime: Parses timestamp as floating-point seconds since the epoch. See also strptime_local. (class=time #args=2) strptime: Parses timestamp as floating-point seconds since the epoch. See also strptime_local.
Examples: Examples:
strptime("2015-08-28T13:33:21Z", "%Y-%m-%dT%H:%M:%SZ") = 1440768801.000000 strptime("2015-08-28T13:33:21Z", "%Y-%m-%dT%H:%M:%SZ") = 1440768801.000000
strptime("2015-08-28T13:33:21.345Z", "%Y-%m-%dT%H:%M:%SZ") = 1440768801.345000 strptime("2015-08-28T13:33:21.345Z", "%Y-%m-%dT%H:%M:%SZ") = 1440768801.345000
strptime("1970-01-01 00:00:00 -0400", "%Y-%m-%d %H:%M:%S %z") = 14400 strptime("1970-01-01 00:00:00 -0400", "%Y-%m-%d %H:%M:%S %z") = 14400
strptime("1970-01-01 00:00:00 EET", "%Y-%m-%d %H:%M:%S %Z") = -7200 strptime("1970-01-01 00:00:00 +0200", "%Y-%m-%d %H:%M:%S %z") = -7200
1mstrptime_local0m 1mstrptime_local0m
(class=time #args=2,3) Like strftime but consults the $TZ environment variable to get local time zone. (class=time #args=2,3) Like strptime but consults the $TZ environment variable to get local time zone.
Examples: Examples:
strptime_local("2015-08-28T13:33:21Z", "%Y-%m-%dT%H:%M:%SZ") = 1440758001 with TZ="Asia/Istanbul" strptime_local("2015-08-28T13:33:21Z", "%Y-%m-%dT%H:%M:%SZ") = 1440758001 with TZ="Asia/Istanbul"
strptime_local("2015-08-28T13:33:21.345Z","%Y-%m-%dT%H:%M:%SZ") = 1440758001.345 with TZ="Asia/Istanbul" strptime_local("2015-08-28T13:33:21.345Z","%Y-%m-%dT%H:%M:%SZ") = 1440758001.345 with TZ="Asia/Istanbul"
@ -2781,6 +2851,9 @@ MILLER(1) MILLER(1)
1msubstr10m 1msubstr10m
(class=string #args=3) substr1(s,m,n) gives substring of s from 1-up position m to n inclusive. Negative indices -len .. -1 alias to 1 .. len. See also substr and substr0. (class=string #args=3) substr1(s,m,n) gives substring of s from 1-up position m to n inclusive. Negative indices -len .. -1 alias to 1 .. len. See also substr and substr0.
1msysntime0m
(class=time #args=0) Returns the system time in 64-bit nanoseconds since the epoch.
1msystem0m 1msystem0m
(class=system #args=1) Run command string, yielding its stdout minus final carriage return. (class=system #args=1) Run command string, yielding its stdout minus final carriage return.
@ -2827,6 +2900,9 @@ MILLER(1) MILLER(1)
unformatx("{}h{}m{}s", "3h47m22s") gives ["3", "47", "22"]. unformatx("{}h{}m{}s", "3h47m22s") gives ["3", "47", "22"].
is_error(unformatx("{}h{}m{}s", "3:47:22")) gives true. is_error(unformatx("{}h{}m{}s", "3:47:22")) gives true.
1mupntime0m
(class=time #args=0) Returns the time in 64-bit nanoseconds since the current Miller program was started.
1muptime0m 1muptime0m
(class=time #args=0) Returns the time in floating-point seconds since the current Miller program was started. (class=time #args=0) Returns the time in floating-point seconds since the current Miller program was started.
@ -3354,5 +3430,5 @@ MILLER(1) MILLER(1)
2023-06-06 MILLER(1) 2023-06-24 MILLER(1)
</pre> </pre>

View file

@ -190,21 +190,23 @@ MILLER(1) MILLER(1)
capitalize cbrt ceil clean_whitespace collapse_whitespace concat cos cosh capitalize cbrt ceil clean_whitespace collapse_whitespace concat cos cosh
depth dhms2fsec dhms2sec erf erfc every exec exp expm1 flatten float floor depth dhms2fsec dhms2sec erf erfc every exec exp expm1 flatten float floor
fmtifnum fmtnum fold format fsec2dhms fsec2hms get_keys get_values fmtifnum fmtnum fold format fsec2dhms fsec2hms get_keys get_values
gmt2localtime gmt2sec gssub gsub haskey hexfmt hms2fsec hms2sec hostname index gmt2localtime gmt2nsec gmt2sec gssub gsub haskey hexfmt hms2fsec hms2sec
int invqnorm is_absent is_array is_bool is_boolean is_empty is_empty_map hostname index int invqnorm is_absent is_array is_bool is_boolean is_empty
is_error is_float is_int is_map is_nan is_nonempty_map is_not_array is_empty_map is_error is_float is_int is_map is_nan is_nonempty_map
is_not_empty is_not_map is_not_null is_null is_numeric is_present is_string is_not_array is_not_empty is_not_map is_not_null is_null is_numeric is_present
joink joinkv joinv json_parse json_stringify latin1_to_utf8 leafcount leftpad is_string joink joinkv joinv json_parse json_stringify latin1_to_utf8
length localtime2gmt localtime2sec log log10 log1p logifit lstrip madd mapdiff leafcount leftpad length localtime2gmt localtime2nsec localtime2sec log log10
mapexcept mapselect mapsum max md5 mexp min mmul msub os pow qnorm reduce log1p logifit lstrip madd mapdiff mapexcept mapselect mapsum max md5 mexp min
regextract regextract_or_else rightpad round roundm rstrip sec2dhms sec2gmt mmul msub nsec2gmt nsec2gmtdate nsec2localdate nsec2localtime os pow qnorm
sec2gmtdate sec2hms sec2localdate sec2localtime select sgn sha1 sha256 sha512 reduce regextract regextract_or_else rightpad round roundm rstrip sec2dhms
sin sinh sort splita splitax splitkv splitkvx splitnv splitnvx sqrt ssub sec2gmt sec2gmtdate sec2hms sec2localdate sec2localtime select sgn sha1 sha256
strftime strftime_local string strip strlen strptime strptime_local sub substr sha512 sin sinh sort splita splitax splitkv splitkvx splitnv splitnvx sqrt
substr0 substr1 system systime systimeint tan tanh tolower toupper truncate ssub strfntime strfntime_local strftime strftime_local string strip strlen
typeof unflatten unformat unformatx uptime urand urand32 urandelement urandint strpntime strpntime_local strptime strptime_local sub substr substr0 substr1
urandrange utf8_to_latin1 version ! != !=~ % & && * ** + - . .* .+ .- ./ / // sysntime system systime systimeint tan tanh tolower toupper truncate typeof
< << <= <=> == =~ > >= >> >>> ?: ?? ??? ^ ^^ | || ~ unflatten unformat unformatx upntime uptime urand urand32 urandelement
urandint urandrange utf8_to_latin1 version ! != !=~ % & && * ** + - . .* .+ .-
./ / // < << <= <=> == =~ > >= >> >>> ?: ?? ??? ^ ^^ | || ~
1mCOMMENTS-IN-DATA FLAGS0m 1mCOMMENTS-IN-DATA FLAGS0m
Miller lets you put comments in your data, such as Miller lets you put comments in your data, such as
@ -1189,13 +1191,13 @@ MILLER(1) MILLER(1)
Note that "mlr filter" is more powerful, but requires you to know field names. Note that "mlr filter" is more powerful, but requires you to know field names.
By contrast, "mlr grep" allows you to regex-match the entire record. It does this By contrast, "mlr grep" allows you to regex-match the entire record. It does this
by formatting each record in memory as DKVP (or NIDX, if -a is supplied), using by formatting each record in memory as DKVP (or NIDX, if -a is supplied), using
OFS "," and OPS "=", and matching the resulting line against the regex specified command-line-specified ORS/OFS/OPS, and matching the resulting line against the
here. In particular, the regex is not applied to the input stream: if you have regex specified here. In particular, the regex is not applied to the input
CSV with header line "x,y,z" and data line "1,2,3" then the regex will be stream: if you have CSV with header line "x,y,z" and data line "1,2,3" then the
matched, not against either of these lines, but against the DKVP line regex will be matched, not against either of these lines, but against the DKVP
"x=1,y=2,z=3". Furthermore, not all the options to system grep are supported, line "x=1,y=2,z=3". Furthermore, not all the options to system grep are
and this command is intended to be merely a keystroke-saver. To get all the supported, and this command is intended to be merely a keystroke-saver. To get
features of system grep, you can do all the features of system grep, you can do
"mlr --odkvp ... | grep ... | mlr --idkvp ..." "mlr --odkvp ... | grep ... | mlr --idkvp ..."
1mgroup-by0m 1mgroup-by0m
@ -2332,6 +2334,11 @@ MILLER(1) MILLER(1)
gmt2localtime("1999-12-31T22:00:00Z") = "2000-01-01 00:00:00" with TZ="Asia/Istanbul" gmt2localtime("1999-12-31T22:00:00Z") = "2000-01-01 00:00:00" with TZ="Asia/Istanbul"
gmt2localtime("1999-12-31T22:00:00Z", "Asia/Istanbul") = "2000-01-01 00:00:00" gmt2localtime("1999-12-31T22:00:00Z", "Asia/Istanbul") = "2000-01-01 00:00:00"
1mgmt2nsec0m
(class=time #args=1) Parses GMT timestamp as integer nanoseconds since the epoch.
Example:
gmt2nsec("2001-02-03T04:05:06Z") = 981173106000000000
1mgmt2sec0m 1mgmt2sec0m
(class=time #args=1) Parses GMT timestamp as integer seconds since the epoch. (class=time #args=1) Parses GMT timestamp as integer seconds since the epoch.
Example: Example:
@ -2497,6 +2504,12 @@ MILLER(1) MILLER(1)
localtime2gmt("2000-01-01 00:00:00") = "1999-12-31T22:00:00Z" with TZ="Asia/Istanbul" localtime2gmt("2000-01-01 00:00:00") = "1999-12-31T22:00:00Z" with TZ="Asia/Istanbul"
localtime2gmt("2000-01-01 00:00:00", "Asia/Istanbul") = "1999-12-31T22:00:00Z" localtime2gmt("2000-01-01 00:00:00", "Asia/Istanbul") = "1999-12-31T22:00:00Z"
1mlocaltime2nsec0m
(class=time #args=1,2) Parses local timestamp as integer nanoseconds since the epoch. Consults $TZ environment variable, unless second argument is supplied.
Examples:
localtime2nsec("2001-02-03 04:05:06") = 981165906000000000 with TZ="Asia/Istanbul"
localtime2nsec("2001-02-03 04:05:06", "Asia/Istanbul") = 981165906000000000"
1mlocaltime2sec0m 1mlocaltime2sec0m
(class=time #args=1,2) Parses local timestamp as integer seconds since the epoch. Consults $TZ environment variable, unless second argument is supplied. (class=time #args=1,2) Parses local timestamp as integer seconds since the epoch. Consults $TZ environment variable, unless second argument is supplied.
Examples: Examples:
@ -2551,6 +2564,32 @@ MILLER(1) MILLER(1)
1mmsub0m 1mmsub0m
(class=arithmetic #args=3) a - b mod m (integers) (class=arithmetic #args=3) a - b mod m (integers)
1mnsec2gmt0m
(class=time #args=1,2) Formats integer nanoseconds since epoch as GMT timestamp. Leaves non-numbers as-is. With second integer argument n, includes n decimal places for the seconds part.
Examples:
nsec2gmt(1234567890000000000) = "2009-02-13T23:31:30Z"
nsec2gmt(1234567890123456789) = "2009-02-13T23:31:30Z"
nsec2gmt(1234567890123456789, 6) = "2009-02-13T23:31:30.123456Z"
1mnsec2gmtdate0m
(class=time #args=1) Formats integer nanoseconds since epoch as GMT timestamp with year-month-date. Leaves non-numbers as-is.
Example:
sec2gmtdate(1440768801700000000) = "2015-08-28".
1mnsec2localdate0m
(class=time #args=1,2) Formats integer nanoseconds since epoch as local timestamp with year-month-date. Leaves non-numbers as-is. Consults $TZ environment variable unless second argument is supplied.
Examples:
nsec2localdate(1440768801700000000) = "2015-08-28" with TZ="Asia/Istanbul"
nsec2localdate(1440768801700000000, "Asia/Istanbul") = "2015-08-28"
1mnsec2localtime0m
(class=time #args=1,2,3) Formats integer nanoseconds since epoch as local timestamp. Consults $TZ environment variable unless third argument is supplied. Leaves non-numbers as-is. With second integer argument n, includes n decimal places for the seconds part
Examples:
nsec2localtime(1234567890000000000) = "2009-02-14 01:31:30" with TZ="Asia/Istanbul"
nsec2localtime(1234567890123456789) = "2009-02-14 01:31:30" with TZ="Asia/Istanbul"
nsec2localtime(1234567890123456789, 6) = "2009-02-14 01:31:30.123456" with TZ="Asia/Istanbul"
nsec2localtime(1234567890123456789, 6, "Asia/Istanbul") = "2009-02-14 01:31:30.123456"
1mos0m 1mos0m
(class=system #args=0) Returns the operating-system name as a string. (class=system #args=0) Returns the operating-system name as a string.
@ -2704,6 +2743,21 @@ MILLER(1) MILLER(1)
Example: Example:
ssub("abc.def", ".", "X") gives "abcXdef" ssub("abc.def", ".", "X") gives "abcXdef"
1mstrfntime0m
(class=time #args=2) Formats integer nanoseconds 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 https://miller.readthedocs.io/en/latest/reference-dsl-time/ for more information on the differences from the C library ("man strftime" on your system). See also strftime_local.
Examples:
strfntime(1440768801123456789,"%Y-%m-%dT%H:%M:%SZ") = "2015-08-28T13:33:21Z"
strfntime(1440768801123456789,"%Y-%m-%dT%H:%M:%3SZ") = "2015-08-28T13:33:21.123Z"
strfntime(1440768801123456789,"%Y-%m-%dT%H:%M:%6SZ") = "2015-08-28T13:33:21.123456Z"
1mstrfntime_local0m
(class=time #args=2,3) Like strfntime but consults the $TZ environment variable to get local time zone.
Examples:
strfntime_local(1440768801123456789, "%Y-%m-%d %H:%M:%S %z") = "2015-08-28 16:33:21 +0300" with TZ="Asia/Istanbul"
strfntime_local(1440768801123456789, "%Y-%m-%d %H:%M:%3S %z") = "2015-08-28 16:33:21.123 +0300" with TZ="Asia/Istanbul"
strfntime_local(1440768801123456789, "%Y-%m-%d %H:%M:%3S %z", "Asia/Istanbul") = "2015-08-28 16:33:21.123 +0300"
strfntime_local(1440768801123456789, "%Y-%m-%d %H:%M:%9S %z", "Asia/Istanbul") = "2015-08-28 16:33:21.123456789 +0300"
1mstrftime0m 1mstrftime0m
(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 https://miller.readthedocs.io/en/latest/reference-dsl-time/ for more information on the differences from the C library ("man strftime" on your system). See also strftime_local. (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 https://miller.readthedocs.io/en/latest/reference-dsl-time/ for more information on the differences from the C library ("man strftime" on your system). See also strftime_local.
Examples: Examples:
@ -2726,16 +2780,32 @@ MILLER(1) MILLER(1)
1mstrlen0m 1mstrlen0m
(class=string #args=1) String length. (class=string #args=1) String length.
1mstrpntime0m
(class=time #args=2) strpntime: Parses timestamp as integer nanoseconds since the epoch. See also strpntime_local.
Examples:
strpntime("2015-08-28T13:33:21Z", "%Y-%m-%dT%H:%M:%SZ") = 1440768801000000000
strpntime("2015-08-28T13:33:21.345Z", "%Y-%m-%dT%H:%M:%SZ") = 1440768801345000000
strpntime("1970-01-01 00:00:00 -0400", "%Y-%m-%d %H:%M:%S %z") = 14400000000000
strpntime("1970-01-01 00:00:00 +0200", "%Y-%m-%d %H:%M:%S %z") = -7200000000000
1mstrpntime_local0m
(class=time #args=2,3) Like strpntime but consults the $TZ environment variable to get local time zone.
Examples:
strpntime_local("2015-08-28T13:33:21Z", "%Y-%m-%dT%H:%M:%SZ") = 1440758001000000000 with TZ="Asia/Istanbul"
strpntime_local("2015-08-28T13:33:21.345Z","%Y-%m-%dT%H:%M:%SZ") = 1440758001345000000 with TZ="Asia/Istanbul"
strpntime_local("2015-08-28 13:33:21", "%Y-%m-%d %H:%M:%S") = 1440758001000000000 with TZ="Asia/Istanbul"
strpntime_local("2015-08-28 13:33:21", "%Y-%m-%d %H:%M:%S", "Asia/Istanbul") = 1440758001000000000
1mstrptime0m 1mstrptime0m
(class=time #args=2) strptime: Parses timestamp as floating-point seconds since the epoch. See also strptime_local. (class=time #args=2) strptime: Parses timestamp as floating-point seconds since the epoch. See also strptime_local.
Examples: Examples:
strptime("2015-08-28T13:33:21Z", "%Y-%m-%dT%H:%M:%SZ") = 1440768801.000000 strptime("2015-08-28T13:33:21Z", "%Y-%m-%dT%H:%M:%SZ") = 1440768801.000000
strptime("2015-08-28T13:33:21.345Z", "%Y-%m-%dT%H:%M:%SZ") = 1440768801.345000 strptime("2015-08-28T13:33:21.345Z", "%Y-%m-%dT%H:%M:%SZ") = 1440768801.345000
strptime("1970-01-01 00:00:00 -0400", "%Y-%m-%d %H:%M:%S %z") = 14400 strptime("1970-01-01 00:00:00 -0400", "%Y-%m-%d %H:%M:%S %z") = 14400
strptime("1970-01-01 00:00:00 EET", "%Y-%m-%d %H:%M:%S %Z") = -7200 strptime("1970-01-01 00:00:00 +0200", "%Y-%m-%d %H:%M:%S %z") = -7200
1mstrptime_local0m 1mstrptime_local0m
(class=time #args=2,3) Like strftime but consults the $TZ environment variable to get local time zone. (class=time #args=2,3) Like strptime but consults the $TZ environment variable to get local time zone.
Examples: Examples:
strptime_local("2015-08-28T13:33:21Z", "%Y-%m-%dT%H:%M:%SZ") = 1440758001 with TZ="Asia/Istanbul" strptime_local("2015-08-28T13:33:21Z", "%Y-%m-%dT%H:%M:%SZ") = 1440758001 with TZ="Asia/Istanbul"
strptime_local("2015-08-28T13:33:21.345Z","%Y-%m-%dT%H:%M:%SZ") = 1440758001.345 with TZ="Asia/Istanbul" strptime_local("2015-08-28T13:33:21.345Z","%Y-%m-%dT%H:%M:%SZ") = 1440758001.345 with TZ="Asia/Istanbul"
@ -2760,6 +2830,9 @@ MILLER(1) MILLER(1)
1msubstr10m 1msubstr10m
(class=string #args=3) substr1(s,m,n) gives substring of s from 1-up position m to n inclusive. Negative indices -len .. -1 alias to 1 .. len. See also substr and substr0. (class=string #args=3) substr1(s,m,n) gives substring of s from 1-up position m to n inclusive. Negative indices -len .. -1 alias to 1 .. len. See also substr and substr0.
1msysntime0m
(class=time #args=0) Returns the system time in 64-bit nanoseconds since the epoch.
1msystem0m 1msystem0m
(class=system #args=1) Run command string, yielding its stdout minus final carriage return. (class=system #args=1) Run command string, yielding its stdout minus final carriage return.
@ -2806,6 +2879,9 @@ MILLER(1) MILLER(1)
unformatx("{}h{}m{}s", "3h47m22s") gives ["3", "47", "22"]. unformatx("{}h{}m{}s", "3h47m22s") gives ["3", "47", "22"].
is_error(unformatx("{}h{}m{}s", "3:47:22")) gives true. is_error(unformatx("{}h{}m{}s", "3:47:22")) gives true.
1mupntime0m
(class=time #args=0) Returns the time in 64-bit nanoseconds since the current Miller program was started.
1muptime0m 1muptime0m
(class=time #args=0) Returns the time in floating-point seconds since the current Miller program was started. (class=time #args=0) Returns the time in floating-point seconds since the current Miller program was started.
@ -3333,4 +3409,4 @@ MILLER(1) MILLER(1)
2023-06-06 MILLER(1) 2023-06-24 MILLER(1)

View file

@ -143,6 +143,9 @@ gmt2localtime (class=time #args=1,2) Convert from a GMT-time string to a local-
Examples: Examples:
gmt2localtime("1999-12-31T22:00:00Z") = "2000-01-01 00:00:00" with TZ="Asia/Istanbul" gmt2localtime("1999-12-31T22:00:00Z") = "2000-01-01 00:00:00" with TZ="Asia/Istanbul"
gmt2localtime("1999-12-31T22:00:00Z", "Asia/Istanbul") = "2000-01-01 00:00:00" gmt2localtime("1999-12-31T22:00:00Z", "Asia/Istanbul") = "2000-01-01 00:00:00"
gmt2nsec (class=time #args=1) Parses GMT timestamp as integer nanoseconds since the epoch.
Example:
gmt2nsec("2001-02-03T04:05:06Z") = 981173106000000000
gmt2sec (class=time #args=1) Parses GMT timestamp as integer seconds since the epoch. gmt2sec (class=time #args=1) Parses GMT timestamp as integer seconds since the epoch.
Example: Example:
gmt2sec("2001-02-03T04:05:06Z") = 981173106 gmt2sec("2001-02-03T04:05:06Z") = 981173106
@ -150,6 +153,14 @@ localtime2gmt (class=time #args=1,2) Convert from a local-time string to a GMT-
Examples: Examples:
localtime2gmt("2000-01-01 00:00:00") = "1999-12-31T22:00:00Z" with TZ="Asia/Istanbul" localtime2gmt("2000-01-01 00:00:00") = "1999-12-31T22:00:00Z" with TZ="Asia/Istanbul"
localtime2gmt("2000-01-01 00:00:00", "Asia/Istanbul") = "1999-12-31T22:00:00Z" localtime2gmt("2000-01-01 00:00:00", "Asia/Istanbul") = "1999-12-31T22:00:00Z"
nsec2gmt (class=time #args=1,2) Formats integer nanoseconds since epoch as GMT timestamp. Leaves non-numbers as-is. With second integer argument n, includes n decimal places for the seconds part.
Examples:
nsec2gmt(1234567890000000000) = "2009-02-13T23:31:30Z"
nsec2gmt(1234567890123456789) = "2009-02-13T23:31:30Z"
nsec2gmt(1234567890123456789, 6) = "2009-02-13T23:31:30.123456Z"
nsec2gmtdate (class=time #args=1) Formats integer nanoseconds since epoch as GMT timestamp with year-month-date. Leaves non-numbers as-is.
Example:
sec2gmtdate(1440768801700000000) = "2015-08-28".
sec2gmt (class=time #args=1,2) Formats seconds since epoch as GMT timestamp. Leaves non-numbers as-is. With second integer argument n, includes n decimal places for the seconds part. sec2gmt (class=time #args=1,2) Formats seconds since epoch as GMT timestamp. Leaves non-numbers as-is. With second integer argument n, includes n decimal places for the seconds part.
Examples: Examples:
sec2gmt(1234567890) = "2009-02-13T23:31:30Z" sec2gmt(1234567890) = "2009-02-13T23:31:30Z"

View file

@ -76,7 +76,7 @@ is 2. Unary operators such as `!` and `~` show argument-count of 1; the ternary
* [**Math functions**](#math-functions): [abs](#abs), [acos](#acos), [acosh](#acosh), [asin](#asin), [asinh](#asinh), [atan](#atan), [atan2](#atan2), [atanh](#atanh), [cbrt](#cbrt), [ceil](#ceil), [cos](#cos), [cosh](#cosh), [erf](#erf), [erfc](#erfc), [exp](#exp), [expm1](#expm1), [floor](#floor), [invqnorm](#invqnorm), [log](#log), [log10](#log10), [log1p](#log1p), [logifit](#logifit), [max](#max), [min](#min), [qnorm](#qnorm), [round](#round), [roundm](#roundm), [sgn](#sgn), [sin](#sin), [sinh](#sinh), [sqrt](#sqrt), [tan](#tan), [tanh](#tanh), [urand](#urand), [urand32](#urand32), [urandelement](#urandelement), [urandint](#urandint), [urandrange](#urandrange). * [**Math functions**](#math-functions): [abs](#abs), [acos](#acos), [acosh](#acosh), [asin](#asin), [asinh](#asinh), [atan](#atan), [atan2](#atan2), [atanh](#atanh), [cbrt](#cbrt), [ceil](#ceil), [cos](#cos), [cosh](#cosh), [erf](#erf), [erfc](#erfc), [exp](#exp), [expm1](#expm1), [floor](#floor), [invqnorm](#invqnorm), [log](#log), [log10](#log10), [log1p](#log1p), [logifit](#logifit), [max](#max), [min](#min), [qnorm](#qnorm), [round](#round), [roundm](#roundm), [sgn](#sgn), [sin](#sin), [sinh](#sinh), [sqrt](#sqrt), [tan](#tan), [tanh](#tanh), [urand](#urand), [urand32](#urand32), [urandelement](#urandelement), [urandint](#urandint), [urandrange](#urandrange).
* [**String functions**](#string-functions): [capitalize](#capitalize), [clean_whitespace](#clean_whitespace), [collapse_whitespace](#collapse_whitespace), [format](#format), [gssub](#gssub), [gsub](#gsub), [index](#index), [latin1_to_utf8](#latin1_to_utf8), [leftpad](#leftpad), [lstrip](#lstrip), [regextract](#regextract), [regextract_or_else](#regextract_or_else), [rightpad](#rightpad), [rstrip](#rstrip), [ssub](#ssub), [strip](#strip), [strlen](#strlen), [sub](#sub), [substr](#substr), [substr0](#substr0), [substr1](#substr1), [tolower](#tolower), [toupper](#toupper), [truncate](#truncate), [unformat](#unformat), [unformatx](#unformatx), [utf8_to_latin1](#utf8_to_latin1), [\.](#dot). * [**String functions**](#string-functions): [capitalize](#capitalize), [clean_whitespace](#clean_whitespace), [collapse_whitespace](#collapse_whitespace), [format](#format), [gssub](#gssub), [gsub](#gsub), [index](#index), [latin1_to_utf8](#latin1_to_utf8), [leftpad](#leftpad), [lstrip](#lstrip), [regextract](#regextract), [regextract_or_else](#regextract_or_else), [rightpad](#rightpad), [rstrip](#rstrip), [ssub](#ssub), [strip](#strip), [strlen](#strlen), [sub](#sub), [substr](#substr), [substr0](#substr0), [substr1](#substr1), [tolower](#tolower), [toupper](#toupper), [truncate](#truncate), [unformat](#unformat), [unformatx](#unformatx), [utf8_to_latin1](#utf8_to_latin1), [\.](#dot).
* [**System functions**](#system-functions): [exec](#exec), [hostname](#hostname), [os](#os), [system](#system), [version](#version). * [**System functions**](#system-functions): [exec](#exec), [hostname](#hostname), [os](#os), [system](#system), [version](#version).
* [**Time functions**](#time-functions): [dhms2fsec](#dhms2fsec), [dhms2sec](#dhms2sec), [fsec2dhms](#fsec2dhms), [fsec2hms](#fsec2hms), [gmt2localtime](#gmt2localtime), [gmt2sec](#gmt2sec), [hms2fsec](#hms2fsec), [hms2sec](#hms2sec), [localtime2gmt](#localtime2gmt), [localtime2sec](#localtime2sec), [sec2dhms](#sec2dhms), [sec2gmt](#sec2gmt), [sec2gmtdate](#sec2gmtdate), [sec2hms](#sec2hms), [sec2localdate](#sec2localdate), [sec2localtime](#sec2localtime), [strftime](#strftime), [strftime_local](#strftime_local), [strptime](#strptime), [strptime_local](#strptime_local), [systime](#systime), [systimeint](#systimeint), [uptime](#uptime). * [**Time functions**](#time-functions): [dhms2fsec](#dhms2fsec), [dhms2sec](#dhms2sec), [fsec2dhms](#fsec2dhms), [fsec2hms](#fsec2hms), [gmt2localtime](#gmt2localtime), [gmt2nsec](#gmt2nsec), [gmt2sec](#gmt2sec), [hms2fsec](#hms2fsec), [hms2sec](#hms2sec), [localtime2gmt](#localtime2gmt), [localtime2nsec](#localtime2nsec), [localtime2sec](#localtime2sec), [nsec2gmt](#nsec2gmt), [nsec2gmtdate](#nsec2gmtdate), [nsec2localdate](#nsec2localdate), [nsec2localtime](#nsec2localtime), [sec2dhms](#sec2dhms), [sec2gmt](#sec2gmt), [sec2gmtdate](#sec2gmtdate), [sec2hms](#sec2hms), [sec2localdate](#sec2localdate), [sec2localtime](#sec2localtime), [strfntime](#strfntime), [strfntime_local](#strfntime_local), [strftime](#strftime), [strftime_local](#strftime_local), [strpntime](#strpntime), [strpntime_local](#strpntime_local), [strptime](#strptime), [strptime_local](#strptime_local), [sysntime](#sysntime), [systime](#systime), [systimeint](#systimeint), [upntime](#upntime), [uptime](#uptime).
* [**Typing functions**](#typing-functions): [asserting_absent](#asserting_absent), [asserting_array](#asserting_array), [asserting_bool](#asserting_bool), [asserting_boolean](#asserting_boolean), [asserting_empty](#asserting_empty), [asserting_empty_map](#asserting_empty_map), [asserting_error](#asserting_error), [asserting_float](#asserting_float), [asserting_int](#asserting_int), [asserting_map](#asserting_map), [asserting_nonempty_map](#asserting_nonempty_map), [asserting_not_array](#asserting_not_array), [asserting_not_empty](#asserting_not_empty), [asserting_not_map](#asserting_not_map), [asserting_not_null](#asserting_not_null), [asserting_null](#asserting_null), [asserting_numeric](#asserting_numeric), [asserting_present](#asserting_present), [asserting_string](#asserting_string), [is_absent](#is_absent), [is_array](#is_array), [is_bool](#is_bool), [is_boolean](#is_boolean), [is_empty](#is_empty), [is_empty_map](#is_empty_map), [is_error](#is_error), [is_float](#is_float), [is_int](#is_int), [is_map](#is_map), [is_nan](#is_nan), [is_nonempty_map](#is_nonempty_map), [is_not_array](#is_not_array), [is_not_empty](#is_not_empty), [is_not_map](#is_not_map), [is_not_null](#is_not_null), [is_null](#is_null), [is_numeric](#is_numeric), [is_present](#is_present), [is_string](#is_string), [typeof](#typeof). * [**Typing functions**](#typing-functions): [asserting_absent](#asserting_absent), [asserting_array](#asserting_array), [asserting_bool](#asserting_bool), [asserting_boolean](#asserting_boolean), [asserting_empty](#asserting_empty), [asserting_empty_map](#asserting_empty_map), [asserting_error](#asserting_error), [asserting_float](#asserting_float), [asserting_int](#asserting_int), [asserting_map](#asserting_map), [asserting_nonempty_map](#asserting_nonempty_map), [asserting_not_array](#asserting_not_array), [asserting_not_empty](#asserting_not_empty), [asserting_not_map](#asserting_not_map), [asserting_not_null](#asserting_not_null), [asserting_null](#asserting_null), [asserting_numeric](#asserting_numeric), [asserting_present](#asserting_present), [asserting_string](#asserting_string), [is_absent](#is_absent), [is_array](#is_array), [is_bool](#is_bool), [is_boolean](#is_boolean), [is_empty](#is_empty), [is_empty_map](#is_empty_map), [is_error](#is_error), [is_float](#is_float), [is_int](#is_int), [is_map](#is_map), [is_nan](#is_nan), [is_nonempty_map](#is_nonempty_map), [is_not_array](#is_not_array), [is_not_empty](#is_not_empty), [is_not_map](#is_not_map), [is_not_null](#is_not_null), [is_null](#is_null), [is_numeric](#is_numeric), [is_present](#is_present), [is_string](#is_string), [typeof](#typeof).
## Arithmetic functions ## Arithmetic functions
@ -1267,6 +1267,14 @@ gmt2localtime("1999-12-31T22:00:00Z", "Asia/Istanbul") = "2000-01-01 00:00:00"
</pre> </pre>
### gmt2nsec
<pre class="pre-non-highlight-non-pair">
gmt2nsec (class=time #args=1) Parses GMT timestamp as integer nanoseconds since the epoch.
Example:
gmt2nsec("2001-02-03T04:05:06Z") = 981173106000000000
</pre>
### gmt2sec ### gmt2sec
<pre class="pre-non-highlight-non-pair"> <pre class="pre-non-highlight-non-pair">
gmt2sec (class=time #args=1) Parses GMT timestamp as integer seconds since the epoch. gmt2sec (class=time #args=1) Parses GMT timestamp as integer seconds since the epoch.
@ -1296,6 +1304,15 @@ localtime2gmt("2000-01-01 00:00:00", "Asia/Istanbul") = "1999-12-31T22:00:00Z"
</pre> </pre>
### localtime2nsec
<pre class="pre-non-highlight-non-pair">
localtime2nsec (class=time #args=1,2) Parses local timestamp as integer nanoseconds since the epoch. Consults $TZ environment variable, unless second argument is supplied.
Examples:
localtime2nsec("2001-02-03 04:05:06") = 981165906000000000 with TZ="Asia/Istanbul"
localtime2nsec("2001-02-03 04:05:06", "Asia/Istanbul") = 981165906000000000"
</pre>
### localtime2sec ### localtime2sec
<pre class="pre-non-highlight-non-pair"> <pre class="pre-non-highlight-non-pair">
localtime2sec (class=time #args=1,2) Parses local timestamp as integer seconds since the epoch. Consults $TZ environment variable, unless second argument is supplied. localtime2sec (class=time #args=1,2) Parses local timestamp as integer seconds since the epoch. Consults $TZ environment variable, unless second argument is supplied.
@ -1305,6 +1322,44 @@ localtime2sec("2001-02-03 04:05:06", "Asia/Istanbul") = 981165906"
</pre> </pre>
### nsec2gmt
<pre class="pre-non-highlight-non-pair">
nsec2gmt (class=time #args=1,2) Formats integer nanoseconds since epoch as GMT timestamp. Leaves non-numbers as-is. With second integer argument n, includes n decimal places for the seconds part.
Examples:
nsec2gmt(1234567890000000000) = "2009-02-13T23:31:30Z"
nsec2gmt(1234567890123456789) = "2009-02-13T23:31:30Z"
nsec2gmt(1234567890123456789, 6) = "2009-02-13T23:31:30.123456Z"
</pre>
### nsec2gmtdate
<pre class="pre-non-highlight-non-pair">
nsec2gmtdate (class=time #args=1) Formats integer nanoseconds since epoch as GMT timestamp with year-month-date. Leaves non-numbers as-is.
Example:
sec2gmtdate(1440768801700000000) = "2015-08-28".
</pre>
### nsec2localdate
<pre class="pre-non-highlight-non-pair">
nsec2localdate (class=time #args=1,2) Formats integer nanoseconds since epoch as local timestamp with year-month-date. Leaves non-numbers as-is. Consults $TZ environment variable unless second argument is supplied.
Examples:
nsec2localdate(1440768801700000000) = "2015-08-28" with TZ="Asia/Istanbul"
nsec2localdate(1440768801700000000, "Asia/Istanbul") = "2015-08-28"
</pre>
### nsec2localtime
<pre class="pre-non-highlight-non-pair">
nsec2localtime (class=time #args=1,2,3) Formats integer nanoseconds since epoch as local timestamp. Consults $TZ environment variable unless third argument is supplied. Leaves non-numbers as-is. With second integer argument n, includes n decimal places for the seconds part
Examples:
nsec2localtime(1234567890000000000) = "2009-02-14 01:31:30" with TZ="Asia/Istanbul"
nsec2localtime(1234567890123456789) = "2009-02-14 01:31:30" with TZ="Asia/Istanbul"
nsec2localtime(1234567890123456789, 6) = "2009-02-14 01:31:30.123456" with TZ="Asia/Istanbul"
nsec2localtime(1234567890123456789, 6, "Asia/Istanbul") = "2009-02-14 01:31:30.123456"
</pre>
### sec2dhms ### sec2dhms
<pre class="pre-non-highlight-non-pair"> <pre class="pre-non-highlight-non-pair">
sec2dhms (class=time #args=1) Formats integer seconds as in sec2dhms(500000) = "5d18h53m20s" sec2dhms (class=time #args=1) Formats integer seconds as in sec2dhms(500000) = "5d18h53m20s"
@ -1355,6 +1410,27 @@ sec2localtime(1234567890.123456, 6, "Asia/Istanbul") = "2009-02-14 01:31:30.1234
</pre> </pre>
### strfntime
<pre class="pre-non-highlight-non-pair">
strfntime (class=time #args=2) Formats integer nanoseconds 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 https://miller.readthedocs.io/en/latest/reference-dsl-time/ for more information on the differences from the C library ("man strftime" on your system). See also strftime_local.
Examples:
strfntime(1440768801123456789,"%Y-%m-%dT%H:%M:%SZ") = "2015-08-28T13:33:21Z"
strfntime(1440768801123456789,"%Y-%m-%dT%H:%M:%3SZ") = "2015-08-28T13:33:21.123Z"
strfntime(1440768801123456789,"%Y-%m-%dT%H:%M:%6SZ") = "2015-08-28T13:33:21.123456Z"
</pre>
### strfntime_local
<pre class="pre-non-highlight-non-pair">
strfntime_local (class=time #args=2,3) Like strfntime but consults the $TZ environment variable to get local time zone.
Examples:
strfntime_local(1440768801123456789, "%Y-%m-%d %H:%M:%S %z") = "2015-08-28 16:33:21 +0300" with TZ="Asia/Istanbul"
strfntime_local(1440768801123456789, "%Y-%m-%d %H:%M:%3S %z") = "2015-08-28 16:33:21.123 +0300" with TZ="Asia/Istanbul"
strfntime_local(1440768801123456789, "%Y-%m-%d %H:%M:%3S %z", "Asia/Istanbul") = "2015-08-28 16:33:21.123 +0300"
strfntime_local(1440768801123456789, "%Y-%m-%d %H:%M:%9S %z", "Asia/Istanbul") = "2015-08-28 16:33:21.123456789 +0300"
</pre>
### strftime ### strftime
<pre class="pre-non-highlight-non-pair"> <pre class="pre-non-highlight-non-pair">
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 https://miller.readthedocs.io/en/latest/reference-dsl-time/ for more information on the differences from the C library ("man strftime" on your system). See also strftime_local. 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 https://miller.readthedocs.io/en/latest/reference-dsl-time/ for more information on the differences from the C library ("man strftime" on your system). See also strftime_local.
@ -1374,6 +1450,28 @@ strftime_local(1440768801.7, "%Y-%m-%d %H:%M:%3S %z", "Asia/Istanbul") = "2015-0
</pre> </pre>
### strpntime
<pre class="pre-non-highlight-non-pair">
strpntime (class=time #args=2) strpntime: Parses timestamp as integer nanoseconds since the epoch. See also strpntime_local.
Examples:
strpntime("2015-08-28T13:33:21Z", "%Y-%m-%dT%H:%M:%SZ") = 1440768801000000000
strpntime("2015-08-28T13:33:21.345Z", "%Y-%m-%dT%H:%M:%SZ") = 1440768801345000000
strpntime("1970-01-01 00:00:00 -0400", "%Y-%m-%d %H:%M:%S %z") = 14400000000000
strpntime("1970-01-01 00:00:00 +0200", "%Y-%m-%d %H:%M:%S %z") = -7200000000000
</pre>
### strpntime_local
<pre class="pre-non-highlight-non-pair">
strpntime_local (class=time #args=2,3) Like strpntime but consults the $TZ environment variable to get local time zone.
Examples:
strpntime_local("2015-08-28T13:33:21Z", "%Y-%m-%dT%H:%M:%SZ") = 1440758001000000000 with TZ="Asia/Istanbul"
strpntime_local("2015-08-28T13:33:21.345Z","%Y-%m-%dT%H:%M:%SZ") = 1440758001345000000 with TZ="Asia/Istanbul"
strpntime_local("2015-08-28 13:33:21", "%Y-%m-%d %H:%M:%S") = 1440758001000000000 with TZ="Asia/Istanbul"
strpntime_local("2015-08-28 13:33:21", "%Y-%m-%d %H:%M:%S", "Asia/Istanbul") = 1440758001000000000
</pre>
### strptime ### strptime
<pre class="pre-non-highlight-non-pair"> <pre class="pre-non-highlight-non-pair">
strptime (class=time #args=2) strptime: Parses timestamp as floating-point seconds since the epoch. See also strptime_local. strptime (class=time #args=2) strptime: Parses timestamp as floating-point seconds since the epoch. See also strptime_local.
@ -1381,13 +1479,13 @@ Examples:
strptime("2015-08-28T13:33:21Z", "%Y-%m-%dT%H:%M:%SZ") = 1440768801.000000 strptime("2015-08-28T13:33:21Z", "%Y-%m-%dT%H:%M:%SZ") = 1440768801.000000
strptime("2015-08-28T13:33:21.345Z", "%Y-%m-%dT%H:%M:%SZ") = 1440768801.345000 strptime("2015-08-28T13:33:21.345Z", "%Y-%m-%dT%H:%M:%SZ") = 1440768801.345000
strptime("1970-01-01 00:00:00 -0400", "%Y-%m-%d %H:%M:%S %z") = 14400 strptime("1970-01-01 00:00:00 -0400", "%Y-%m-%d %H:%M:%S %z") = 14400
strptime("1970-01-01 00:00:00 EET", "%Y-%m-%d %H:%M:%S %Z") = -7200 strptime("1970-01-01 00:00:00 +0200", "%Y-%m-%d %H:%M:%S %z") = -7200
</pre> </pre>
### strptime_local ### strptime_local
<pre class="pre-non-highlight-non-pair"> <pre class="pre-non-highlight-non-pair">
strptime_local (class=time #args=2,3) Like strftime but consults the $TZ environment variable to get local time zone. strptime_local (class=time #args=2,3) Like strptime but consults the $TZ environment variable to get local time zone.
Examples: Examples:
strptime_local("2015-08-28T13:33:21Z", "%Y-%m-%dT%H:%M:%SZ") = 1440758001 with TZ="Asia/Istanbul" strptime_local("2015-08-28T13:33:21Z", "%Y-%m-%dT%H:%M:%SZ") = 1440758001 with TZ="Asia/Istanbul"
strptime_local("2015-08-28T13:33:21.345Z","%Y-%m-%dT%H:%M:%SZ") = 1440758001.345 with TZ="Asia/Istanbul" strptime_local("2015-08-28T13:33:21.345Z","%Y-%m-%dT%H:%M:%SZ") = 1440758001.345 with TZ="Asia/Istanbul"
@ -1396,6 +1494,12 @@ strptime_local("2015-08-28 13:33:21", "%Y-%m-%d %H:%M:%S", "Asia/Istanbul")
</pre> </pre>
### sysntime
<pre class="pre-non-highlight-non-pair">
sysntime (class=time #args=0) Returns the system time in 64-bit nanoseconds since the epoch.
</pre>
### systime ### systime
<pre class="pre-non-highlight-non-pair"> <pre class="pre-non-highlight-non-pair">
systime (class=time #args=0) Returns the system time in floating-point seconds since the epoch. systime (class=time #args=0) Returns the system time in floating-point seconds since the epoch.
@ -1408,6 +1512,12 @@ systimeint (class=time #args=0) Returns the system time in integer seconds sinc
</pre> </pre>
### upntime
<pre class="pre-non-highlight-non-pair">
upntime (class=time #args=0) Returns the time in 64-bit nanoseconds since the current Miller program was started.
</pre>
### uptime ### uptime
<pre class="pre-non-highlight-non-pair"> <pre class="pre-non-highlight-non-pair">
uptime (class=time #args=0) Returns the time in floating-point seconds since the current Miller program was started. uptime (class=time #args=0) Returns the time in floating-point seconds since the current Miller program was started.

View file

@ -1355,13 +1355,13 @@ Options:
Note that "mlr filter" is more powerful, but requires you to know field names. Note that "mlr filter" is more powerful, but requires you to know field names.
By contrast, "mlr grep" allows you to regex-match the entire record. It does this By contrast, "mlr grep" allows you to regex-match the entire record. It does this
by formatting each record in memory as DKVP (or NIDX, if -a is supplied), using by formatting each record in memory as DKVP (or NIDX, if -a is supplied), using
OFS "," and OPS "=", and matching the resulting line against the regex specified command-line-specified ORS/OFS/OPS, and matching the resulting line against the
here. In particular, the regex is not applied to the input stream: if you have regex specified here. In particular, the regex is not applied to the input
CSV with header line "x,y,z" and data line "1,2,3" then the regex will be stream: if you have CSV with header line "x,y,z" and data line "1,2,3" then the
matched, not against either of these lines, but against the DKVP line regex will be matched, not against either of these lines, but against the DKVP
"x=1,y=2,z=3". Furthermore, not all the options to system grep are supported, line "x=1,y=2,z=3". Furthermore, not all the options to system grep are
and this command is intended to be merely a keystroke-saver. To get all the supported, and this command is intended to be merely a keystroke-saver. To get
features of system grep, you can do all the features of system grep, you can do
"mlr --odkvp ... | grep ... | mlr --idkvp ..." "mlr --odkvp ... | grep ... | mlr --idkvp ..."
</pre> </pre>

View file

@ -28,16 +28,27 @@ func BIF_systimeint() *mlrval.Mlrval {
return mlrval.FromInt(time.Now().Unix()) return mlrval.FromInt(time.Now().Unix())
} }
func BIF_sysntime() *mlrval.Mlrval {
return mlrval.FromInt(time.Now().UnixNano())
}
var startTime float64 var startTime float64
var startNTime int64
func init() { func init() {
startTime = float64(time.Now().UnixNano()) / 1.0e9 startTime = float64(time.Now().UnixNano()) / 1.0e9
startNTime = time.Now().UnixNano()
} }
func BIF_uptime() *mlrval.Mlrval { func BIF_uptime() *mlrval.Mlrval {
return mlrval.FromFloat( return mlrval.FromFloat(
float64(time.Now().UnixNano())/1.0e9 - startTime, float64(time.Now().UnixNano())/1.0e9 - startTime,
) )
} }
func BIF_upntime() *mlrval.Mlrval {
return mlrval.FromInt(
time.Now().UnixNano() - startNTime,
)
}
// ================================================================ // ================================================================
@ -46,75 +57,125 @@ func BIF_sec2gmt_unary(input1 *mlrval.Mlrval) *mlrval.Mlrval {
if !isNumeric { if !isNumeric {
return input1 return input1
} }
numDecimalPlaces := 0 numDecimalPlaces := 0
return mlrval.FromString(lib.Sec2GMT(floatValue, numDecimalPlaces)) return mlrval.FromString(lib.Sec2GMT(floatValue, numDecimalPlaces))
} }
func BIF_nsec2gmt_unary(input1 *mlrval.Mlrval) *mlrval.Mlrval {
intValue, ok := input1.GetIntValue()
if !ok {
return mlrval.ERROR
}
numDecimalPlaces := 0
return mlrval.FromString(lib.Nsec2GMT(intValue, numDecimalPlaces))
}
func BIF_sec2gmt_binary(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval { func BIF_sec2gmt_binary(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
floatValue, isNumeric := input1.GetNumericToFloatValue() floatValue, isNumeric := input1.GetNumericToFloatValue()
if !isNumeric { if !isNumeric {
return input1 return input1
} }
numDecimalPlaces, isInt := input2.GetIntValue() numDecimalPlaces, isInt := input2.GetIntValue()
if !isInt { if !isInt {
return mlrval.ERROR return mlrval.ERROR
} }
return mlrval.FromString(lib.Sec2GMT(floatValue, int(numDecimalPlaces))) return mlrval.FromString(lib.Sec2GMT(floatValue, int(numDecimalPlaces)))
} }
func BIF_nsec2gmt_binary(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
intValue, ok := input1.GetIntValue()
if !ok {
return input1
}
numDecimalPlaces, isInt := input2.GetIntValue()
if !isInt {
return mlrval.ERROR
}
return mlrval.FromString(lib.Nsec2GMT(intValue, int(numDecimalPlaces)))
}
func BIF_sec2localtime_unary(input1 *mlrval.Mlrval) *mlrval.Mlrval { func BIF_sec2localtime_unary(input1 *mlrval.Mlrval) *mlrval.Mlrval {
floatValue, isNumeric := input1.GetNumericToFloatValue() floatValue, isNumeric := input1.GetNumericToFloatValue()
if !isNumeric { if !isNumeric {
return input1 return input1
} }
numDecimalPlaces := 0 numDecimalPlaces := 0
return mlrval.FromString(lib.Sec2LocalTime(floatValue, numDecimalPlaces)) return mlrval.FromString(lib.Sec2LocalTime(floatValue, numDecimalPlaces))
} }
func BIF_nsec2localtime_unary(input1 *mlrval.Mlrval) *mlrval.Mlrval {
intValue, ok := input1.GetIntValue()
if !ok {
return input1
}
numDecimalPlaces := 0
return mlrval.FromString(lib.Nsec2LocalTime(intValue, numDecimalPlaces))
}
func BIF_sec2localtime_binary(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval { func BIF_sec2localtime_binary(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
floatValue, isNumeric := input1.GetNumericToFloatValue() floatValue, isNumeric := input1.GetNumericToFloatValue()
if !isNumeric { if !isNumeric {
return input1 return input1
} }
numDecimalPlaces, isInt := input2.GetIntValue() numDecimalPlaces, isInt := input2.GetIntValue()
if !isInt { if !isInt {
return mlrval.ERROR return mlrval.ERROR
} }
return mlrval.FromString(lib.Sec2LocalTime(floatValue, int(numDecimalPlaces))) return mlrval.FromString(lib.Sec2LocalTime(floatValue, int(numDecimalPlaces)))
} }
func BIF_nsec2localtime_binary(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
intValue, ok := input1.GetIntValue()
if !ok {
return input1
}
numDecimalPlaces, isInt := input2.GetIntValue()
if !isInt {
return mlrval.ERROR
}
return mlrval.FromString(lib.Nsec2LocalTime(intValue, int(numDecimalPlaces)))
}
func BIF_sec2localtime_ternary(input1, input2, input3 *mlrval.Mlrval) *mlrval.Mlrval { func BIF_sec2localtime_ternary(input1, input2, input3 *mlrval.Mlrval) *mlrval.Mlrval {
floatValue, isNumeric := input1.GetNumericToFloatValue() floatValue, isNumeric := input1.GetNumericToFloatValue()
if !isNumeric { if !isNumeric {
return input1 return input1
} }
numDecimalPlaces, isInt := input2.GetIntValue() numDecimalPlaces, isInt := input2.GetIntValue()
if !isInt { if !isInt {
return mlrval.ERROR return mlrval.ERROR
} }
locationString, isString := input3.GetStringValue() locationString, isString := input3.GetStringValue()
if !isString { if !isString {
return mlrval.ERROR return mlrval.ERROR
} }
location, err := time.LoadLocation(locationString) location, err := time.LoadLocation(locationString)
if err != nil { if err != nil {
return mlrval.ERROR return mlrval.ERROR
} }
return mlrval.FromString(lib.Sec2LocationTime(floatValue, int(numDecimalPlaces), location)) return mlrval.FromString(lib.Sec2LocationTime(floatValue, int(numDecimalPlaces), location))
} }
func BIF_nsec2localtime_ternary(input1, input2, input3 *mlrval.Mlrval) *mlrval.Mlrval {
intValue, isNumeric := input1.GetIntValue()
if !isNumeric {
return input1
}
numDecimalPlaces, isInt := input2.GetIntValue()
if !isInt {
return mlrval.ERROR
}
locationString, isString := input3.GetStringValue()
if !isString {
return mlrval.ERROR
}
location, err := time.LoadLocation(locationString)
if err != nil {
return mlrval.ERROR
}
return mlrval.FromString(lib.Nsec2LocationTime(intValue, int(numDecimalPlaces), location))
}
func BIF_sec2gmtdate(input1 *mlrval.Mlrval) *mlrval.Mlrval { func BIF_sec2gmtdate(input1 *mlrval.Mlrval) *mlrval.Mlrval {
if !input1.IsNumeric() { if !input1.IsNumeric() {
return input1 return input1
@ -122,6 +183,13 @@ func BIF_sec2gmtdate(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return BIF_strftime(input1, ptr_YMD_FORMAT) return BIF_strftime(input1, ptr_YMD_FORMAT)
} }
func BIF_nsec2gmtdate(input1 *mlrval.Mlrval) *mlrval.Mlrval {
if !input1.IsNumeric() {
return input1
}
return BIF_strfntime(input1, ptr_YMD_FORMAT)
}
func BIF_sec2localdate_unary(input1 *mlrval.Mlrval) *mlrval.Mlrval { func BIF_sec2localdate_unary(input1 *mlrval.Mlrval) *mlrval.Mlrval {
if !input1.IsNumeric() { if !input1.IsNumeric() {
return input1 return input1
@ -129,6 +197,13 @@ func BIF_sec2localdate_unary(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return BIF_strftime_local_binary(input1, ptr_YMD_FORMAT) return BIF_strftime_local_binary(input1, ptr_YMD_FORMAT)
} }
func BIF_nsec2localdate_unary(input1 *mlrval.Mlrval) *mlrval.Mlrval {
if !input1.IsNumeric() {
return input1
}
return BIF_strfntime_local_binary(input1, ptr_YMD_FORMAT)
}
func BIF_sec2localdate_binary(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval { func BIF_sec2localdate_binary(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
if !input1.IsNumeric() { if !input1.IsNumeric() {
return input1 return input1
@ -136,34 +211,40 @@ func BIF_sec2localdate_binary(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return BIF_strftime_local_ternary(input1, ptr_YMD_FORMAT, input2) return BIF_strftime_local_ternary(input1, ptr_YMD_FORMAT, input2)
} }
// ---------------------------------------------------------------- func BIF_nsec2localdate_binary(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
if !input1.IsNumeric() {
return input1
}
return BIF_strfntime_local_ternary(input1, ptr_YMD_FORMAT, input2)
}
// ----------------------------------------------------------------
func BIF_localtime2gmt_unary(input1 *mlrval.Mlrval) *mlrval.Mlrval { func BIF_localtime2gmt_unary(input1 *mlrval.Mlrval) *mlrval.Mlrval {
if !input1.IsString() { if !input1.IsString() {
return mlrval.ERROR return mlrval.ERROR
} }
return BIF_sec2gmt_unary(BIF_localtime2sec_unary(input1)) return BIF_nsec2gmt_unary(BIF_localtime2nsec_unary(input1))
} }
func BIF_localtime2gmt_binary(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval { func BIF_localtime2gmt_binary(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
if !input1.IsString() { if !input1.IsString() {
return mlrval.ERROR return mlrval.ERROR
} }
return BIF_sec2gmt_unary(BIF_localtime2sec_binary(input1, input2)) return BIF_nsec2gmt_unary(BIF_localtime2nsec_binary(input1, input2))
} }
func BIF_gmt2localtime_unary(input1 *mlrval.Mlrval) *mlrval.Mlrval { func BIF_gmt2localtime_unary(input1 *mlrval.Mlrval) *mlrval.Mlrval {
if !input1.IsString() { if !input1.IsString() {
return mlrval.ERROR return mlrval.ERROR
} }
return BIF_sec2localtime_unary(BIF_gmt2sec(input1)) return BIF_nsec2localtime_unary(BIF_gmt2nsec(input1))
} }
func BIF_gmt2localtime_binary(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval { func BIF_gmt2localtime_binary(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
if !input1.IsString() { if !input1.IsString() {
return mlrval.ERROR return mlrval.ERROR
} }
return BIF_sec2localtime_ternary(BIF_gmt2sec(input1), mlrval.FromInt(0), input2) return BIF_nsec2localtime_ternary(BIF_gmt2nsec(input1), mlrval.FromInt(0), input2)
} }
// ================================================================ // ================================================================
@ -176,10 +257,18 @@ func BIF_strftime(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return strftimeHelper(input1, input2, false, nil) return strftimeHelper(input1, input2, false, nil)
} }
func BIF_strfntime(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return strfntimeHelper(input1, input2, false, nil)
}
func BIF_strftime_local_binary(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval { func BIF_strftime_local_binary(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return strftimeHelper(input1, input2, true, nil) return strftimeHelper(input1, input2, true, nil)
} }
func BIF_strfntime_local_binary(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return strfntimeHelper(input1, input2, true, nil)
}
func BIF_strftime_local_ternary(input1, input2, input3 *mlrval.Mlrval) *mlrval.Mlrval { func BIF_strftime_local_ternary(input1, input2, input3 *mlrval.Mlrval) *mlrval.Mlrval {
locationString, isString := input3.GetStringValue() locationString, isString := input3.GetStringValue()
if !isString { if !isString {
@ -194,6 +283,18 @@ func BIF_strftime_local_ternary(input1, input2, input3 *mlrval.Mlrval) *mlrval.M
return strftimeHelper(input1, input2, true, location) return strftimeHelper(input1, input2, true, location)
} }
func BIF_strfntime_local_ternary(input1, input2, input3 *mlrval.Mlrval) *mlrval.Mlrval {
locationString, isString := input3.GetStringValue()
if !isString {
return mlrval.ERROR
}
location, err := time.LoadLocation(locationString)
if err != nil {
return mlrval.ERROR
}
return strfntimeHelper(input1, input2, true, location)
}
func strftimeHelper(input1, input2 *mlrval.Mlrval, doLocal bool, location *time.Location) *mlrval.Mlrval { func strftimeHelper(input1, input2 *mlrval.Mlrval, doLocal bool, location *time.Location) *mlrval.Mlrval {
if input1.IsVoid() { if input1.IsVoid() {
return input1 return input1
@ -236,6 +337,48 @@ func strftimeHelper(input1, input2 *mlrval.Mlrval, doLocal bool, location *time.
return mlrval.FromString(outputString) return mlrval.FromString(outputString)
} }
func strfntimeHelper(input1, input2 *mlrval.Mlrval, doLocal bool, location *time.Location) *mlrval.Mlrval {
if input1.IsVoid() {
return input1
}
epochNanoseconds, ok := input1.GetIntValue()
if !ok {
return mlrval.ERROR
}
if !input2.IsString() {
return mlrval.ERROR
}
// Convert argument1 from float seconds since the epoch to a Go time.
var inputTime time.Time
if doLocal {
if location != nil {
inputTime = lib.EpochNanosecondsToLocationTime(epochNanoseconds, location)
} else {
inputTime = lib.EpochNanosecondsToLocalTime(epochNanoseconds)
}
} else {
inputTime = lib.EpochNanosecondsToGMT(epochNanoseconds)
}
// Convert argument 2 to a strfntime format string.
//
// Miller fractional-second formats are like "%6S", and were so in the C
// implementation. However, in the strfntime package we're using in the Go
// port, extension-formats are only a single byte so we need to rewrite
// them to "%6".
formatString := extensionRegex.ReplaceAllString(input2.AcquireStringValue(), "$1")
formatter, err := strftime.New(formatString, strftimeExtensions)
if err != nil {
return mlrval.ERROR
}
outputString := formatter.FormatString(inputTime)
return mlrval.FromString(outputString)
}
// ---------------------------------------------------------------- // ----------------------------------------------------------------
// This is support for %1S .. %9S in format strings, using github.com/lestrrat-go/strftime. // This is support for %1S .. %9S in format strings, using github.com/lestrrat-go/strftime.
@ -301,6 +444,14 @@ func init() {
// Argument 1 is formatted date string like "2021-03-04 02:59:50". // Argument 1 is formatted date string like "2021-03-04 02:59:50".
// Argument 2 is format string like "%Y-%m-%d %H:%M:%S". // Argument 2 is format string like "%Y-%m-%d %H:%M:%S".
func BIF_strptime(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval { func BIF_strptime(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return bif_strptime_unary_aux(input1, input2, false, false)
}
func BIF_strpntime(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return bif_strptime_unary_aux(input1, input2, false, true)
}
func bif_strptime_unary_aux(input1, input2 *mlrval.Mlrval, doLocal, produceNanoseconds bool) *mlrval.Mlrval {
if !input1.IsString() { if !input1.IsString() {
return mlrval.ERROR return mlrval.ERROR
} }
@ -310,15 +461,53 @@ func BIF_strptime(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
timeString := input1.AcquireStringValue() timeString := input1.AcquireStringValue()
formatString := input2.AcquireStringValue() formatString := input2.AcquireStringValue()
t, err := strptime.Parse(timeString, formatString) var t time.Time
var err error
if doLocal {
t, err = strptime.ParseLocal(timeString, formatString)
} else {
t, err = strptime.Parse(timeString, formatString)
}
if err != nil { if err != nil {
return mlrval.ERROR return mlrval.ERROR
} }
return mlrval.FromFloat(float64(t.UnixNano()) / 1.0e9) if produceNanoseconds {
return mlrval.FromInt(t.UnixNano())
} else {
return mlrval.FromFloat(float64(t.UnixNano()) / 1.0e9)
}
} }
// Argument 1 is formatted date string like "2021-03-04T02:59:50Z".
func BIF_gmt2sec(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return bif_strptime_unary_aux(input1, ptr_ISO8601_TIME_FORMAT, false, false)
}
// Argument 1 is formatted date string like "2021-03-04T02:59:50Z".
func BIF_gmt2nsec(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return bif_strptime_unary_aux(input1, ptr_ISO8601_TIME_FORMAT, false, true)
}
func BIF_localtime2sec_unary(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return bif_strptime_unary_aux(input1, ptr_ISO8601_LOCAL_TIME_FORMAT, true, false)
}
func BIF_localtime2nsec_unary(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return bif_strptime_unary_aux(input1, ptr_ISO8601_LOCAL_TIME_FORMAT, true, true)
}
// ----------------------------------------------------------------
func BIF_strptime_local_binary(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval { func BIF_strptime_local_binary(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return bif_strptime_binary_aux(input1, input2, true, false)
}
func BIF_strpntime_local_binary(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return bif_strptime_binary_aux(input1, input2, true, true)
}
func bif_strptime_binary_aux(input1, input2 *mlrval.Mlrval, doLocal, produceNanoseconds bool) *mlrval.Mlrval {
if !input1.IsString() { if !input1.IsString() {
return mlrval.ERROR return mlrval.ERROR
} }
@ -328,15 +517,43 @@ func BIF_strptime_local_binary(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
timeString := input1.AcquireStringValue() timeString := input1.AcquireStringValue()
formatString := input2.AcquireStringValue() formatString := input2.AcquireStringValue()
t, err := strptime.ParseLocal(timeString, formatString) var t time.Time
var err error
if doLocal {
t, err = strptime.ParseLocal(timeString, formatString)
} else {
t, err = strptime.Parse(timeString, formatString)
}
if err != nil { if err != nil {
return mlrval.ERROR return mlrval.ERROR
} }
return mlrval.FromFloat(float64(t.UnixNano()) / 1.0e9) if produceNanoseconds {
return mlrval.FromInt(t.UnixNano())
} else {
return mlrval.FromFloat(float64(t.UnixNano()) / 1.0e9)
}
} }
// ----------------------------------------------------------------
func BIF_strptime_local_ternary(input1, input2, input3 *mlrval.Mlrval) *mlrval.Mlrval { func BIF_strptime_local_ternary(input1, input2, input3 *mlrval.Mlrval) *mlrval.Mlrval {
return bif_strptime_local_ternary_aux(input1, input2, input3, false)
}
func BIF_strpntime_local_ternary(input1, input2, input3 *mlrval.Mlrval) *mlrval.Mlrval {
return bif_strptime_local_ternary_aux(input1, input2, input3, true)
}
func BIF_localtime2sec_binary(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return bif_strptime_local_ternary_aux(input1, ptr_ISO8601_LOCAL_TIME_FORMAT, input2, false)
}
func BIF_localtime2nsec_binary(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return bif_strptime_local_ternary_aux(input1, ptr_ISO8601_LOCAL_TIME_FORMAT, input2, true)
}
func bif_strptime_local_ternary_aux(input1, input2, input3 *mlrval.Mlrval, produceNanoseconds bool) *mlrval.Mlrval {
if !input1.IsString() { if !input1.IsString() {
return mlrval.ERROR return mlrval.ERROR
} }
@ -356,26 +573,14 @@ func BIF_strptime_local_ternary(input1, input2, input3 *mlrval.Mlrval) *mlrval.M
return mlrval.ERROR return mlrval.ERROR
} }
// TODO: use location
t, err := strptime.ParseLocation(timeString, formatString, location) t, err := strptime.ParseLocation(timeString, formatString, location)
if err != nil { if err != nil {
return mlrval.ERROR return mlrval.ERROR
} }
return mlrval.FromFloat(float64(t.UnixNano()) / 1.0e9) if produceNanoseconds {
} return mlrval.FromInt(t.UnixNano())
} else {
// ================================================================ return mlrval.FromFloat(float64(t.UnixNano()) / 1.0e9)
// Argument 1 is formatted date string like "2021-03-04T02:59:50Z". }
func BIF_gmt2sec(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return BIF_strptime(input1, ptr_ISO8601_TIME_FORMAT)
}
func BIF_localtime2sec_unary(input1 *mlrval.Mlrval) *mlrval.Mlrval {
return BIF_strptime_local_binary(input1, ptr_ISO8601_LOCAL_TIME_FORMAT)
}
func BIF_localtime2sec_binary(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return BIF_strptime_local_ternary(input1, ptr_ISO8601_LOCAL_TIME_FORMAT, input2)
} }

View file

@ -971,6 +971,16 @@ is normally distributed.`,
unaryFunc: bifs.BIF_gmt2sec, unaryFunc: bifs.BIF_gmt2sec,
}, },
{
name: "gmt2nsec",
class: FUNC_CLASS_TIME,
help: `Parses GMT timestamp as integer nanoseconds since the epoch.`,
examples: []string{
`gmt2nsec("2001-02-03T04:05:06Z") = 981173106000000000`,
},
unaryFunc: bifs.BIF_gmt2nsec,
},
{ {
name: "localtime2sec", name: "localtime2sec",
class: FUNC_CLASS_TIME, class: FUNC_CLASS_TIME,
@ -980,12 +990,25 @@ unless second argument is supplied.`,
`localtime2sec("2001-02-03 04:05:06") = 981165906 with TZ="Asia/Istanbul"`, `localtime2sec("2001-02-03 04:05:06") = 981165906 with TZ="Asia/Istanbul"`,
`localtime2sec("2001-02-03 04:05:06", "Asia/Istanbul") = 981165906"`, `localtime2sec("2001-02-03 04:05:06", "Asia/Istanbul") = 981165906"`,
}, },
// TODO: help-string
unaryFunc: bifs.BIF_localtime2sec_unary, unaryFunc: bifs.BIF_localtime2sec_unary,
binaryFunc: bifs.BIF_localtime2sec_binary, binaryFunc: bifs.BIF_localtime2sec_binary,
hasMultipleArities: true, hasMultipleArities: true,
}, },
{
name: "localtime2nsec",
class: FUNC_CLASS_TIME,
help: `Parses local timestamp as integer nanoseconds since the epoch. Consults $TZ environment variable,
unless second argument is supplied.`,
examples: []string{
`localtime2nsec("2001-02-03 04:05:06") = 981165906000000000 with TZ="Asia/Istanbul"`,
`localtime2nsec("2001-02-03 04:05:06", "Asia/Istanbul") = 981165906000000000"`,
},
unaryFunc: bifs.BIF_localtime2nsec_unary,
binaryFunc: bifs.BIF_localtime2nsec_binary,
hasMultipleArities: true,
},
{ {
name: "sec2gmt", name: "sec2gmt",
class: FUNC_CLASS_TIME, class: FUNC_CLASS_TIME,
@ -1001,6 +1024,21 @@ argument n, includes n decimal places for the seconds part.`,
hasMultipleArities: true, hasMultipleArities: true,
}, },
{
name: "nsec2gmt",
class: FUNC_CLASS_TIME,
help: `Formats integer nanoseconds since epoch as GMT timestamp. Leaves non-numbers as-is. With second integer
argument n, includes n decimal places for the seconds part.`,
examples: []string{
`nsec2gmt(1234567890000000000) = "2009-02-13T23:31:30Z"`,
`nsec2gmt(1234567890123456789) = "2009-02-13T23:31:30Z"`,
`nsec2gmt(1234567890123456789, 6) = "2009-02-13T23:31:30.123456Z"`,
},
unaryFunc: bifs.BIF_nsec2gmt_unary,
binaryFunc: bifs.BIF_nsec2gmt_binary,
hasMultipleArities: true,
},
{ {
name: "sec2localtime", name: "sec2localtime",
class: FUNC_CLASS_TIME, class: FUNC_CLASS_TIME,
@ -1019,6 +1057,24 @@ includes n decimal places for the seconds part`,
hasMultipleArities: true, hasMultipleArities: true,
}, },
{
name: "nsec2localtime",
class: FUNC_CLASS_TIME,
help: `Formats integer nanoseconds since epoch as local timestamp. Consults $TZ
environment variable unless third argument is supplied. Leaves non-numbers as-is. With second integer argument n,
includes n decimal places for the seconds part`,
examples: []string{
`nsec2localtime(1234567890000000000) = "2009-02-14 01:31:30" with TZ="Asia/Istanbul"`,
`nsec2localtime(1234567890123456789) = "2009-02-14 01:31:30" with TZ="Asia/Istanbul"`,
`nsec2localtime(1234567890123456789, 6) = "2009-02-14 01:31:30.123456" with TZ="Asia/Istanbul"`,
`nsec2localtime(1234567890123456789, 6, "Asia/Istanbul") = "2009-02-14 01:31:30.123456"`,
},
unaryFunc: bifs.BIF_nsec2localtime_unary,
binaryFunc: bifs.BIF_nsec2localtime_binary,
ternaryFunc: bifs.BIF_nsec2localtime_ternary,
hasMultipleArities: true,
},
{ {
name: "sec2gmtdate", name: "sec2gmtdate",
class: FUNC_CLASS_TIME, class: FUNC_CLASS_TIME,
@ -1030,6 +1086,17 @@ Leaves non-numbers as-is.`,
unaryFunc: bifs.BIF_sec2gmtdate, unaryFunc: bifs.BIF_sec2gmtdate,
}, },
{
name: "nsec2gmtdate",
class: FUNC_CLASS_TIME,
help: `Formats integer nanoseconds since epoch as GMT timestamp with year-month-date.
Leaves non-numbers as-is.`,
examples: []string{
`sec2gmtdate(1440768801700000000) = "2015-08-28".`,
},
unaryFunc: bifs.BIF_nsec2gmtdate,
},
{ {
name: "sec2localdate", name: "sec2localdate",
class: FUNC_CLASS_TIME, class: FUNC_CLASS_TIME,
@ -1044,6 +1111,20 @@ Leaves non-numbers as-is. Consults $TZ environment variable unless second argume
hasMultipleArities: true, hasMultipleArities: true,
}, },
{
name: "nsec2localdate",
class: FUNC_CLASS_TIME,
help: `Formats integer nanoseconds since epoch as local timestamp with year-month-date.
Leaves non-numbers as-is. Consults $TZ environment variable unless second argument is supplied.`,
examples: []string{
`nsec2localdate(1440768801700000000) = "2015-08-28" with TZ="Asia/Istanbul"`,
`nsec2localdate(1440768801700000000, "Asia/Istanbul") = "2015-08-28"`,
},
unaryFunc: bifs.BIF_nsec2localdate_unary,
binaryFunc: bifs.BIF_nsec2localdate_binary,
hasMultipleArities: true,
},
{ {
name: "localtime2gmt", name: "localtime2gmt",
class: FUNC_CLASS_TIME, class: FUNC_CLASS_TIME,
@ -1088,17 +1169,19 @@ See also strftime_local.`,
}, },
{ {
name: "strptime", name: "strfntime",
class: FUNC_CLASS_TIME, class: FUNC_CLASS_TIME,
help: `strptime: Parses timestamp as floating-point seconds since the epoch. See also strptime_local.`, help: `Formats integer nanoseconds 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 ` + lib.DOC_URL + `/en/latest/reference-dsl-time/ for more information on the differences from the C library ("man strftime" on your system).
See also strftime_local.`,
examples: []string{ examples: []string{
`strptime("2015-08-28T13:33:21Z", "%Y-%m-%dT%H:%M:%SZ") = 1440768801.000000`, `strfntime(1440768801123456789,"%Y-%m-%dT%H:%M:%SZ") = "2015-08-28T13:33:21Z"`,
`strptime("2015-08-28T13:33:21.345Z", "%Y-%m-%dT%H:%M:%SZ") = 1440768801.345000`, `strfntime(1440768801123456789,"%Y-%m-%dT%H:%M:%3SZ") = "2015-08-28T13:33:21.123Z"`,
`strptime("1970-01-01 00:00:00 -0400", "%Y-%m-%d %H:%M:%S %z") = 14400`, `strfntime(1440768801123456789,"%Y-%m-%dT%H:%M:%6SZ") = "2015-08-28T13:33:21.123456Z"`,
`strptime("1970-01-01 00:00:00 EET", "%Y-%m-%d %H:%M:%S %Z") = -7200`,
}, },
binaryFunc: bifs.BIF_strfntime,
binaryFunc: bifs.BIF_strptime,
}, },
{ {
@ -1115,10 +1198,51 @@ See also strftime_local.`,
hasMultipleArities: true, hasMultipleArities: true,
}, },
{
name: "strfntime_local",
class: FUNC_CLASS_TIME,
help: `Like strfntime but consults the $TZ environment variable to get local time zone.`,
examples: []string{
`strfntime_local(1440768801123456789, "%Y-%m-%d %H:%M:%S %z") = "2015-08-28 16:33:21 +0300" with TZ="Asia/Istanbul"`,
`strfntime_local(1440768801123456789, "%Y-%m-%d %H:%M:%3S %z") = "2015-08-28 16:33:21.123 +0300" with TZ="Asia/Istanbul"`,
`strfntime_local(1440768801123456789, "%Y-%m-%d %H:%M:%3S %z", "Asia/Istanbul") = "2015-08-28 16:33:21.123 +0300"`,
`strfntime_local(1440768801123456789, "%Y-%m-%d %H:%M:%9S %z", "Asia/Istanbul") = "2015-08-28 16:33:21.123456789 +0300"`,
},
binaryFunc: bifs.BIF_strfntime_local_binary,
ternaryFunc: bifs.BIF_strfntime_local_ternary,
hasMultipleArities: true,
},
{
name: "strptime",
class: FUNC_CLASS_TIME,
help: `strptime: Parses timestamp as floating-point seconds since the epoch. See also strptime_local.`,
examples: []string{
`strptime("2015-08-28T13:33:21Z", "%Y-%m-%dT%H:%M:%SZ") = 1440768801.000000`,
`strptime("2015-08-28T13:33:21.345Z", "%Y-%m-%dT%H:%M:%SZ") = 1440768801.345000`,
`strptime("1970-01-01 00:00:00 -0400", "%Y-%m-%d %H:%M:%S %z") = 14400`,
`strptime("1970-01-01 00:00:00 +0200", "%Y-%m-%d %H:%M:%S %z") = -7200`,
},
binaryFunc: bifs.BIF_strptime,
},
{
name: "strpntime",
class: FUNC_CLASS_TIME,
help: `strpntime: Parses timestamp as integer nanoseconds since the epoch. See also strpntime_local.`,
examples: []string{
`strpntime("2015-08-28T13:33:21Z", "%Y-%m-%dT%H:%M:%SZ") = 1440768801000000000`,
`strpntime("2015-08-28T13:33:21.345Z", "%Y-%m-%dT%H:%M:%SZ") = 1440768801345000000`,
`strpntime("1970-01-01 00:00:00 -0400", "%Y-%m-%d %H:%M:%S %z") = 14400000000000`,
`strpntime("1970-01-01 00:00:00 +0200", "%Y-%m-%d %H:%M:%S %z") = -7200000000000`,
},
binaryFunc: bifs.BIF_strpntime,
},
{ {
name: "strptime_local", name: "strptime_local",
class: FUNC_CLASS_TIME, class: FUNC_CLASS_TIME,
help: `Like strftime but consults the $TZ environment variable to get local time zone.`, help: `Like strptime but consults the $TZ environment variable to get local time zone.`,
examples: []string{ examples: []string{
`strptime_local("2015-08-28T13:33:21Z", "%Y-%m-%dT%H:%M:%SZ") = 1440758001 with TZ="Asia/Istanbul"`, `strptime_local("2015-08-28T13:33:21Z", "%Y-%m-%dT%H:%M:%SZ") = 1440758001 with TZ="Asia/Istanbul"`,
`strptime_local("2015-08-28T13:33:21.345Z","%Y-%m-%dT%H:%M:%SZ") = 1440758001.345 with TZ="Asia/Istanbul"`, `strptime_local("2015-08-28T13:33:21.345Z","%Y-%m-%dT%H:%M:%SZ") = 1440758001.345 with TZ="Asia/Istanbul"`,
@ -1132,6 +1256,23 @@ See also strftime_local.`,
hasMultipleArities: true, hasMultipleArities: true,
}, },
{
name: "strpntime_local",
class: FUNC_CLASS_TIME,
help: `Like strpntime but consults the $TZ environment variable to get local time zone.`,
examples: []string{
`strpntime_local("2015-08-28T13:33:21Z", "%Y-%m-%dT%H:%M:%SZ") = 1440758001000000000 with TZ="Asia/Istanbul"`,
`strpntime_local("2015-08-28T13:33:21.345Z","%Y-%m-%dT%H:%M:%SZ") = 1440758001345000000 with TZ="Asia/Istanbul"`,
`strpntime_local("2015-08-28 13:33:21", "%Y-%m-%d %H:%M:%S") = 1440758001000000000 with TZ="Asia/Istanbul"`,
`strpntime_local("2015-08-28 13:33:21", "%Y-%m-%d %H:%M:%S", "Asia/Istanbul") = 1440758001000000000`,
// TODO: fix parse error on decimal part
//`strpntime_local("2015-08-28 13:33:21.345","%Y-%m-%d %H:%M:%S") = 1440758001.345`,
},
binaryFunc: bifs.BIF_strpntime_local_binary,
ternaryFunc: bifs.BIF_strpntime_local_ternary,
hasMultipleArities: true,
},
{ {
name: "dhms2fsec", name: "dhms2fsec",
class: FUNC_CLASS_TIME, class: FUNC_CLASS_TIME,
@ -1195,6 +1336,13 @@ See also strftime_local.`,
zaryFunc: bifs.BIF_systime, zaryFunc: bifs.BIF_systime,
}, },
{
name: "sysntime",
class: FUNC_CLASS_TIME,
help: "Returns the system time in 64-bit nanoseconds since the epoch.",
zaryFunc: bifs.BIF_sysntime,
},
{ {
name: "systimeint", name: "systimeint",
class: FUNC_CLASS_TIME, class: FUNC_CLASS_TIME,
@ -1209,6 +1357,13 @@ See also strftime_local.`,
zaryFunc: bifs.BIF_uptime, zaryFunc: bifs.BIF_uptime,
}, },
{
name: "upntime",
class: FUNC_CLASS_TIME,
help: "Returns the time in 64-bit nanoseconds since the current Miller program was started.",
zaryFunc: bifs.BIF_upntime,
},
// ---------------------------------------------------------------- // ----------------------------------------------------------------
// FUNC_CLASS_TYPING // FUNC_CLASS_TYPING

View file

@ -2,7 +2,6 @@ package lib
import ( import (
"fmt" "fmt"
"math"
"os" "os"
"time" "time"
) )
@ -26,33 +25,67 @@ func SetTZFromEnv() error {
} }
func Sec2GMT(epochSeconds float64, numDecimalPlaces int) string { func Sec2GMT(epochSeconds float64, numDecimalPlaces int) string {
return sec2Time(epochSeconds, numDecimalPlaces, false, nil) return secToFormattedTime(epochSeconds, numDecimalPlaces, false, nil)
} }
func Nsec2GMT(epochNanoseconds int64, numDecimalPlaces int) string {
return nsecToFormattedTime(epochNanoseconds, numDecimalPlaces, false, nil)
}
func Sec2LocalTime(epochSeconds float64, numDecimalPlaces int) string { func Sec2LocalTime(epochSeconds float64, numDecimalPlaces int) string {
return sec2Time(epochSeconds, numDecimalPlaces, true, nil) return secToFormattedTime(epochSeconds, numDecimalPlaces, true, nil)
}
func Nsec2LocalTime(epochNanoseconds int64, numDecimalPlaces int) string {
return nsecToFormattedTime(epochNanoseconds, numDecimalPlaces, true, nil)
} }
func Sec2LocationTime(epochSeconds float64, numDecimalPlaces int, location *time.Location) string { func Sec2LocationTime(epochSeconds float64, numDecimalPlaces int, location *time.Location) string {
return sec2Time(epochSeconds, numDecimalPlaces, true, location) return secToFormattedTime(epochSeconds, numDecimalPlaces, true, location)
} }
// sec2Time is for DSL functions sec2gmt and sec2localtime. If doLocal is func Nsec2LocationTime(epochNanoseconds int64, numDecimalPlaces int, location *time.Location) string {
return nsecToFormattedTime(epochNanoseconds, numDecimalPlaces, true, location)
}
// secToFormattedTime is for DSL functions sec2gmt and sec2localtime. If doLocal is
// false, use UTC. Else if location is nil, use $TZ environment variable. Else // false, use UTC. Else if location is nil, use $TZ environment variable. Else
// use the specified location. // use the specified location.
func sec2Time(epochSeconds float64, numDecimalPlaces int, doLocal bool, location *time.Location) string { func secToFormattedTime(epochSeconds float64, numDecimalPlaces int, doLocal bool, location *time.Location) string {
if numDecimalPlaces > 9 {
numDecimalPlaces = 9
}
intPart := int64(epochSeconds) intPart := int64(epochSeconds)
fractionalPart := epochSeconds - float64(intPart) fractionalPart := epochSeconds - float64(intPart)
if fractionalPart < 0 { if fractionalPart < 0 {
intPart -= 1 intPart -= 1
fractionalPart += 1.0 fractionalPart += 1.0
} }
decimalPart := int64(fractionalPart * math.Pow(10.0, float64(numDecimalPlaces)))
t := time.Unix(intPart, 0) t := time.Unix(intPart, int64(fractionalPart*1e9))
return goTimeToFormattedTime(t, numDecimalPlaces, doLocal, location)
}
// nsecToFormattedTime is for DSL functions nsec2gmt and nsec2localtime. If doLocal is
// false, use UTC. Else if location is nil, use $TZ environment variable. Else
// use the specified location.
func nsecToFormattedTime(epochNanoseconds int64, numDecimalPlaces int, doLocal bool, location *time.Location) string {
t := time.Unix(epochNanoseconds/1000000000, epochNanoseconds%1000000000)
return goTimeToFormattedTime(t, numDecimalPlaces, doLocal, location)
}
// This is how much to divide nanoseconds by to get a desired number of decimal places
var nsToFracDivisors = []int{
/* 0 */ 0, /* unused */
/* 1 */ 100000000,
/* 2 */ 10000000,
/* 3 */ 1000000,
/* 4 */ 100000,
/* 5 */ 10000,
/* 6 */ 1000,
/* 7 */ 100,
/* 8 */ 10,
/* 9 */ 1,
}
func goTimeToFormattedTime(t time.Time, numDecimalPlaces int, doLocal bool, location *time.Location) string {
if doLocal { if doLocal {
if location != nil { if location != nil {
t = t.In(location) t = t.In(location)
@ -70,6 +103,12 @@ func sec2Time(epochSeconds float64, numDecimalPlaces int, doLocal bool, location
mm := t.Minute() mm := t.Minute()
ss := t.Second() ss := t.Second()
if numDecimalPlaces < 0 {
numDecimalPlaces = 0
} else if numDecimalPlaces > 9 {
numDecimalPlaces = 9
}
if numDecimalPlaces == 0 { if numDecimalPlaces == 0 {
if doLocal { if doLocal {
return fmt.Sprintf( return fmt.Sprintf(
@ -81,14 +120,15 @@ func sec2Time(epochSeconds float64, numDecimalPlaces int, doLocal bool, location
YYYY, MM, DD, hh, mm, ss) YYYY, MM, DD, hh, mm, ss)
} }
} else { } else {
fractionalPart := t.Nanosecond() / nsToFracDivisors[numDecimalPlaces]
if doLocal { if doLocal {
return fmt.Sprintf( return fmt.Sprintf(
"%04d-%02d-%02d %02d:%02d:%02d.%0*d", "%04d-%02d-%02d %02d:%02d:%02d.%0*d",
YYYY, MM, DD, hh, mm, ss, numDecimalPlaces, decimalPart) YYYY, MM, DD, hh, mm, ss, numDecimalPlaces, fractionalPart)
} else { } else {
return fmt.Sprintf( return fmt.Sprintf(
"%04d-%02d-%02dT%02d:%02d:%02d.%0*dZ", "%04d-%02d-%02dT%02d:%02d:%02d.%0*dZ",
YYYY, MM, DD, hh, mm, ss, numDecimalPlaces, decimalPart) YYYY, MM, DD, hh, mm, ss, numDecimalPlaces, fractionalPart)
} }
} }
} }
@ -97,14 +137,26 @@ func EpochSecondsToGMT(epochSeconds float64) time.Time {
return epochSecondsToTime(epochSeconds, false, nil) return epochSecondsToTime(epochSeconds, false, nil)
} }
func EpochNanosecondsToGMT(epochNanoseconds int64) time.Time {
return epochNanosecondsToTime(epochNanoseconds, false, nil)
}
func EpochSecondsToLocalTime(epochSeconds float64) time.Time { func EpochSecondsToLocalTime(epochSeconds float64) time.Time {
return epochSecondsToTime(epochSeconds, true, nil) return epochSecondsToTime(epochSeconds, true, nil)
} }
func EpochNanosecondsToLocalTime(epochNanoseconds int64) time.Time {
return epochNanosecondsToTime(epochNanoseconds, true, nil)
}
func EpochSecondsToLocationTime(epochSeconds float64, location *time.Location) time.Time { func EpochSecondsToLocationTime(epochSeconds float64, location *time.Location) time.Time {
return epochSecondsToTime(epochSeconds, true, location) return epochSecondsToTime(epochSeconds, true, location)
} }
func EpochNanosecondsToLocationTime(epochNanoseconds int64, location *time.Location) time.Time {
return epochNanosecondsToTime(epochNanoseconds, true, location)
}
func epochSecondsToTime(epochSeconds float64, doLocal bool, location *time.Location) time.Time { func epochSecondsToTime(epochSeconds float64, doLocal bool, location *time.Location) time.Time {
intPart := int64(epochSeconds) intPart := int64(epochSeconds)
fractionalPart := epochSeconds - float64(intPart) fractionalPart := epochSeconds - float64(intPart)
@ -119,3 +171,17 @@ func epochSecondsToTime(epochSeconds float64, doLocal bool, location *time.Locat
return time.Unix(intPart, decimalPart).UTC() return time.Unix(intPart, decimalPart).UTC()
} }
} }
func epochNanosecondsToTime(epochNanoseconds int64, doLocal bool, location *time.Location) time.Time {
intPart := epochNanoseconds / 1000000000
fractionalPart := epochNanoseconds % 1000000000
if doLocal {
if location == nil {
return time.Unix(intPart, fractionalPart).Local()
} else {
return time.Unix(intPart, fractionalPart).In(location)
}
} else {
return time.Unix(intPart, fractionalPart).UTC()
}
}

View file

@ -0,0 +1,101 @@
// ================================================================
// Most Miller tests (thousands of them) are command-line-driven via
// mlr regtest. Here are some cases needing special focus.
// ================================================================
package lib
import (
"time"
"github.com/stretchr/testify/assert"
"testing"
)
// ----------------------------------------------------------------
type tDataForSec2GMT struct {
epochSeconds float64
numDecimalPlaces int
expectedOutput string
}
var dataForSec2GMT = []tDataForSec2GMT{
{0.0, 0, "1970-01-01T00:00:00Z"},
{0.0, 6, "1970-01-01T00:00:00.000000Z"},
{1.0, 6, "1970-01-01T00:00:01.000000Z"},
{123456789.25, 3, "1973-11-29T21:33:09.250Z"},
}
func TestSec2GMT(t *testing.T) {
for _, entry := range dataForSec2GMT {
assert.Equal(t, entry.expectedOutput, Sec2GMT(entry.epochSeconds, entry.numDecimalPlaces))
}
}
// ----------------------------------------------------------------
type tDataForNsec2GMT struct {
epochNanoseconds int64
numDecimalPlaces int
expectedOutput string
}
var dataForNsec2GMT = []tDataForNsec2GMT{
{0, 0, "1970-01-01T00:00:00Z"},
{0, 6, "1970-01-01T00:00:00.000000Z"},
{946684800123456789, 0, "2000-01-01T00:00:00Z"},
{946684800123456789, 1, "2000-01-01T00:00:00.1Z"},
{946684800123456789, 2, "2000-01-01T00:00:00.12Z"},
{946684800123456789, 3, "2000-01-01T00:00:00.123Z"},
{946684800123456789, 4, "2000-01-01T00:00:00.1234Z"},
{946684800123456789, 5, "2000-01-01T00:00:00.12345Z"},
{946684800123456789, 6, "2000-01-01T00:00:00.123456Z"},
{946684800123456789, 7, "2000-01-01T00:00:00.1234567Z"},
{946684800123456789, 8, "2000-01-01T00:00:00.12345678Z"},
{946684800123456789, 9, "2000-01-01T00:00:00.123456789Z"},
}
func TestNsec2GMT(t *testing.T) {
for _, entry := range dataForNsec2GMT {
actualOutput := Nsec2GMT(entry.epochNanoseconds, entry.numDecimalPlaces)
assert.Equal(t, entry.expectedOutput, actualOutput)
}
}
// ----------------------------------------------------------------
type tDataForEpochSecondsToGMT struct {
epochSeconds float64
expectedOutput time.Time
}
var dataForEpochSecondsToGMT = []tDataForEpochSecondsToGMT{
{0.0, time.Unix(0, 0).UTC()},
{1.25, time.Unix(1, 250000000).UTC()},
{123456789.25, time.Unix(123456789, 250000000).UTC()},
}
func TestEpochSecondsToGMT(t *testing.T) {
for _, entry := range dataForEpochSecondsToGMT {
assert.Equal(t, entry.expectedOutput, EpochSecondsToGMT(entry.epochSeconds))
}
}
// ----------------------------------------------------------------
type tDataForEpochNanosecondsToGMT struct {
epochNanoseconds int64
expectedOutput time.Time
}
var dataForEpochNanosecondsToGMT = []tDataForEpochNanosecondsToGMT{
{0, time.Unix(0, 0).UTC()},
{1000000000, time.Unix(1, 0).UTC()},
{1200000000, time.Unix(1, 200000000).UTC()},
{-1000000000, time.Unix(-1, 0).UTC()},
{-1200000000, time.Unix(-1, -200000000).UTC()},
{123456789250000047, time.Unix(123456789, 250000047).UTC()},
}
func TestEpochNanosecondsToGMT(t *testing.T) {
for _, entry := range dataForEpochNanosecondsToGMT {
assert.Equal(t, entry.expectedOutput, EpochNanosecondsToGMT(entry.epochNanoseconds))
}
}

View file

@ -190,21 +190,23 @@ MILLER(1) MILLER(1)
capitalize cbrt ceil clean_whitespace collapse_whitespace concat cos cosh capitalize cbrt ceil clean_whitespace collapse_whitespace concat cos cosh
depth dhms2fsec dhms2sec erf erfc every exec exp expm1 flatten float floor depth dhms2fsec dhms2sec erf erfc every exec exp expm1 flatten float floor
fmtifnum fmtnum fold format fsec2dhms fsec2hms get_keys get_values fmtifnum fmtnum fold format fsec2dhms fsec2hms get_keys get_values
gmt2localtime gmt2sec gssub gsub haskey hexfmt hms2fsec hms2sec hostname index gmt2localtime gmt2nsec gmt2sec gssub gsub haskey hexfmt hms2fsec hms2sec
int invqnorm is_absent is_array is_bool is_boolean is_empty is_empty_map hostname index int invqnorm is_absent is_array is_bool is_boolean is_empty
is_error is_float is_int is_map is_nan is_nonempty_map is_not_array is_empty_map is_error is_float is_int is_map is_nan is_nonempty_map
is_not_empty is_not_map is_not_null is_null is_numeric is_present is_string is_not_array is_not_empty is_not_map is_not_null is_null is_numeric is_present
joink joinkv joinv json_parse json_stringify latin1_to_utf8 leafcount leftpad is_string joink joinkv joinv json_parse json_stringify latin1_to_utf8
length localtime2gmt localtime2sec log log10 log1p logifit lstrip madd mapdiff leafcount leftpad length localtime2gmt localtime2nsec localtime2sec log log10
mapexcept mapselect mapsum max md5 mexp min mmul msub os pow qnorm reduce log1p logifit lstrip madd mapdiff mapexcept mapselect mapsum max md5 mexp min
regextract regextract_or_else rightpad round roundm rstrip sec2dhms sec2gmt mmul msub nsec2gmt nsec2gmtdate nsec2localdate nsec2localtime os pow qnorm
sec2gmtdate sec2hms sec2localdate sec2localtime select sgn sha1 sha256 sha512 reduce regextract regextract_or_else rightpad round roundm rstrip sec2dhms
sin sinh sort splita splitax splitkv splitkvx splitnv splitnvx sqrt ssub sec2gmt sec2gmtdate sec2hms sec2localdate sec2localtime select sgn sha1 sha256
strftime strftime_local string strip strlen strptime strptime_local sub substr sha512 sin sinh sort splita splitax splitkv splitkvx splitnv splitnvx sqrt
substr0 substr1 system systime systimeint tan tanh tolower toupper truncate ssub strfntime strfntime_local strftime strftime_local string strip strlen
typeof unflatten unformat unformatx uptime urand urand32 urandelement urandint strpntime strpntime_local strptime strptime_local sub substr substr0 substr1
urandrange utf8_to_latin1 version ! != !=~ % & && * ** + - . .* .+ .- ./ / // sysntime system systime systimeint tan tanh tolower toupper truncate typeof
< << <= <=> == =~ > >= >> >>> ?: ?? ??? ^ ^^ | || ~ unflatten unformat unformatx upntime uptime urand urand32 urandelement
urandint urandrange utf8_to_latin1 version ! != !=~ % & && * ** + - . .* .+ .-
./ / // < << <= <=> == =~ > >= >> >>> ?: ?? ??? ^ ^^ | || ~
1mCOMMENTS-IN-DATA FLAGS0m 1mCOMMENTS-IN-DATA FLAGS0m
Miller lets you put comments in your data, such as Miller lets you put comments in your data, such as
@ -1189,13 +1191,13 @@ MILLER(1) MILLER(1)
Note that "mlr filter" is more powerful, but requires you to know field names. Note that "mlr filter" is more powerful, but requires you to know field names.
By contrast, "mlr grep" allows you to regex-match the entire record. It does this By contrast, "mlr grep" allows you to regex-match the entire record. It does this
by formatting each record in memory as DKVP (or NIDX, if -a is supplied), using by formatting each record in memory as DKVP (or NIDX, if -a is supplied), using
OFS "," and OPS "=", and matching the resulting line against the regex specified command-line-specified ORS/OFS/OPS, and matching the resulting line against the
here. In particular, the regex is not applied to the input stream: if you have regex specified here. In particular, the regex is not applied to the input
CSV with header line "x,y,z" and data line "1,2,3" then the regex will be stream: if you have CSV with header line "x,y,z" and data line "1,2,3" then the
matched, not against either of these lines, but against the DKVP line regex will be matched, not against either of these lines, but against the DKVP
"x=1,y=2,z=3". Furthermore, not all the options to system grep are supported, line "x=1,y=2,z=3". Furthermore, not all the options to system grep are
and this command is intended to be merely a keystroke-saver. To get all the supported, and this command is intended to be merely a keystroke-saver. To get
features of system grep, you can do all the features of system grep, you can do
"mlr --odkvp ... | grep ... | mlr --idkvp ..." "mlr --odkvp ... | grep ... | mlr --idkvp ..."
1mgroup-by0m 1mgroup-by0m
@ -2332,6 +2334,11 @@ MILLER(1) MILLER(1)
gmt2localtime("1999-12-31T22:00:00Z") = "2000-01-01 00:00:00" with TZ="Asia/Istanbul" gmt2localtime("1999-12-31T22:00:00Z") = "2000-01-01 00:00:00" with TZ="Asia/Istanbul"
gmt2localtime("1999-12-31T22:00:00Z", "Asia/Istanbul") = "2000-01-01 00:00:00" gmt2localtime("1999-12-31T22:00:00Z", "Asia/Istanbul") = "2000-01-01 00:00:00"
1mgmt2nsec0m
(class=time #args=1) Parses GMT timestamp as integer nanoseconds since the epoch.
Example:
gmt2nsec("2001-02-03T04:05:06Z") = 981173106000000000
1mgmt2sec0m 1mgmt2sec0m
(class=time #args=1) Parses GMT timestamp as integer seconds since the epoch. (class=time #args=1) Parses GMT timestamp as integer seconds since the epoch.
Example: Example:
@ -2497,6 +2504,12 @@ MILLER(1) MILLER(1)
localtime2gmt("2000-01-01 00:00:00") = "1999-12-31T22:00:00Z" with TZ="Asia/Istanbul" localtime2gmt("2000-01-01 00:00:00") = "1999-12-31T22:00:00Z" with TZ="Asia/Istanbul"
localtime2gmt("2000-01-01 00:00:00", "Asia/Istanbul") = "1999-12-31T22:00:00Z" localtime2gmt("2000-01-01 00:00:00", "Asia/Istanbul") = "1999-12-31T22:00:00Z"
1mlocaltime2nsec0m
(class=time #args=1,2) Parses local timestamp as integer nanoseconds since the epoch. Consults $TZ environment variable, unless second argument is supplied.
Examples:
localtime2nsec("2001-02-03 04:05:06") = 981165906000000000 with TZ="Asia/Istanbul"
localtime2nsec("2001-02-03 04:05:06", "Asia/Istanbul") = 981165906000000000"
1mlocaltime2sec0m 1mlocaltime2sec0m
(class=time #args=1,2) Parses local timestamp as integer seconds since the epoch. Consults $TZ environment variable, unless second argument is supplied. (class=time #args=1,2) Parses local timestamp as integer seconds since the epoch. Consults $TZ environment variable, unless second argument is supplied.
Examples: Examples:
@ -2551,6 +2564,32 @@ MILLER(1) MILLER(1)
1mmsub0m 1mmsub0m
(class=arithmetic #args=3) a - b mod m (integers) (class=arithmetic #args=3) a - b mod m (integers)
1mnsec2gmt0m
(class=time #args=1,2) Formats integer nanoseconds since epoch as GMT timestamp. Leaves non-numbers as-is. With second integer argument n, includes n decimal places for the seconds part.
Examples:
nsec2gmt(1234567890000000000) = "2009-02-13T23:31:30Z"
nsec2gmt(1234567890123456789) = "2009-02-13T23:31:30Z"
nsec2gmt(1234567890123456789, 6) = "2009-02-13T23:31:30.123456Z"
1mnsec2gmtdate0m
(class=time #args=1) Formats integer nanoseconds since epoch as GMT timestamp with year-month-date. Leaves non-numbers as-is.
Example:
sec2gmtdate(1440768801700000000) = "2015-08-28".
1mnsec2localdate0m
(class=time #args=1,2) Formats integer nanoseconds since epoch as local timestamp with year-month-date. Leaves non-numbers as-is. Consults $TZ environment variable unless second argument is supplied.
Examples:
nsec2localdate(1440768801700000000) = "2015-08-28" with TZ="Asia/Istanbul"
nsec2localdate(1440768801700000000, "Asia/Istanbul") = "2015-08-28"
1mnsec2localtime0m
(class=time #args=1,2,3) Formats integer nanoseconds since epoch as local timestamp. Consults $TZ environment variable unless third argument is supplied. Leaves non-numbers as-is. With second integer argument n, includes n decimal places for the seconds part
Examples:
nsec2localtime(1234567890000000000) = "2009-02-14 01:31:30" with TZ="Asia/Istanbul"
nsec2localtime(1234567890123456789) = "2009-02-14 01:31:30" with TZ="Asia/Istanbul"
nsec2localtime(1234567890123456789, 6) = "2009-02-14 01:31:30.123456" with TZ="Asia/Istanbul"
nsec2localtime(1234567890123456789, 6, "Asia/Istanbul") = "2009-02-14 01:31:30.123456"
1mos0m 1mos0m
(class=system #args=0) Returns the operating-system name as a string. (class=system #args=0) Returns the operating-system name as a string.
@ -2704,6 +2743,21 @@ MILLER(1) MILLER(1)
Example: Example:
ssub("abc.def", ".", "X") gives "abcXdef" ssub("abc.def", ".", "X") gives "abcXdef"
1mstrfntime0m
(class=time #args=2) Formats integer nanoseconds 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 https://miller.readthedocs.io/en/latest/reference-dsl-time/ for more information on the differences from the C library ("man strftime" on your system). See also strftime_local.
Examples:
strfntime(1440768801123456789,"%Y-%m-%dT%H:%M:%SZ") = "2015-08-28T13:33:21Z"
strfntime(1440768801123456789,"%Y-%m-%dT%H:%M:%3SZ") = "2015-08-28T13:33:21.123Z"
strfntime(1440768801123456789,"%Y-%m-%dT%H:%M:%6SZ") = "2015-08-28T13:33:21.123456Z"
1mstrfntime_local0m
(class=time #args=2,3) Like strfntime but consults the $TZ environment variable to get local time zone.
Examples:
strfntime_local(1440768801123456789, "%Y-%m-%d %H:%M:%S %z") = "2015-08-28 16:33:21 +0300" with TZ="Asia/Istanbul"
strfntime_local(1440768801123456789, "%Y-%m-%d %H:%M:%3S %z") = "2015-08-28 16:33:21.123 +0300" with TZ="Asia/Istanbul"
strfntime_local(1440768801123456789, "%Y-%m-%d %H:%M:%3S %z", "Asia/Istanbul") = "2015-08-28 16:33:21.123 +0300"
strfntime_local(1440768801123456789, "%Y-%m-%d %H:%M:%9S %z", "Asia/Istanbul") = "2015-08-28 16:33:21.123456789 +0300"
1mstrftime0m 1mstrftime0m
(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 https://miller.readthedocs.io/en/latest/reference-dsl-time/ for more information on the differences from the C library ("man strftime" on your system). See also strftime_local. (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 https://miller.readthedocs.io/en/latest/reference-dsl-time/ for more information on the differences from the C library ("man strftime" on your system). See also strftime_local.
Examples: Examples:
@ -2726,16 +2780,32 @@ MILLER(1) MILLER(1)
1mstrlen0m 1mstrlen0m
(class=string #args=1) String length. (class=string #args=1) String length.
1mstrpntime0m
(class=time #args=2) strpntime: Parses timestamp as integer nanoseconds since the epoch. See also strpntime_local.
Examples:
strpntime("2015-08-28T13:33:21Z", "%Y-%m-%dT%H:%M:%SZ") = 1440768801000000000
strpntime("2015-08-28T13:33:21.345Z", "%Y-%m-%dT%H:%M:%SZ") = 1440768801345000000
strpntime("1970-01-01 00:00:00 -0400", "%Y-%m-%d %H:%M:%S %z") = 14400000000000
strpntime("1970-01-01 00:00:00 +0200", "%Y-%m-%d %H:%M:%S %z") = -7200000000000
1mstrpntime_local0m
(class=time #args=2,3) Like strpntime but consults the $TZ environment variable to get local time zone.
Examples:
strpntime_local("2015-08-28T13:33:21Z", "%Y-%m-%dT%H:%M:%SZ") = 1440758001000000000 with TZ="Asia/Istanbul"
strpntime_local("2015-08-28T13:33:21.345Z","%Y-%m-%dT%H:%M:%SZ") = 1440758001345000000 with TZ="Asia/Istanbul"
strpntime_local("2015-08-28 13:33:21", "%Y-%m-%d %H:%M:%S") = 1440758001000000000 with TZ="Asia/Istanbul"
strpntime_local("2015-08-28 13:33:21", "%Y-%m-%d %H:%M:%S", "Asia/Istanbul") = 1440758001000000000
1mstrptime0m 1mstrptime0m
(class=time #args=2) strptime: Parses timestamp as floating-point seconds since the epoch. See also strptime_local. (class=time #args=2) strptime: Parses timestamp as floating-point seconds since the epoch. See also strptime_local.
Examples: Examples:
strptime("2015-08-28T13:33:21Z", "%Y-%m-%dT%H:%M:%SZ") = 1440768801.000000 strptime("2015-08-28T13:33:21Z", "%Y-%m-%dT%H:%M:%SZ") = 1440768801.000000
strptime("2015-08-28T13:33:21.345Z", "%Y-%m-%dT%H:%M:%SZ") = 1440768801.345000 strptime("2015-08-28T13:33:21.345Z", "%Y-%m-%dT%H:%M:%SZ") = 1440768801.345000
strptime("1970-01-01 00:00:00 -0400", "%Y-%m-%d %H:%M:%S %z") = 14400 strptime("1970-01-01 00:00:00 -0400", "%Y-%m-%d %H:%M:%S %z") = 14400
strptime("1970-01-01 00:00:00 EET", "%Y-%m-%d %H:%M:%S %Z") = -7200 strptime("1970-01-01 00:00:00 +0200", "%Y-%m-%d %H:%M:%S %z") = -7200
1mstrptime_local0m 1mstrptime_local0m
(class=time #args=2,3) Like strftime but consults the $TZ environment variable to get local time zone. (class=time #args=2,3) Like strptime but consults the $TZ environment variable to get local time zone.
Examples: Examples:
strptime_local("2015-08-28T13:33:21Z", "%Y-%m-%dT%H:%M:%SZ") = 1440758001 with TZ="Asia/Istanbul" strptime_local("2015-08-28T13:33:21Z", "%Y-%m-%dT%H:%M:%SZ") = 1440758001 with TZ="Asia/Istanbul"
strptime_local("2015-08-28T13:33:21.345Z","%Y-%m-%dT%H:%M:%SZ") = 1440758001.345 with TZ="Asia/Istanbul" strptime_local("2015-08-28T13:33:21.345Z","%Y-%m-%dT%H:%M:%SZ") = 1440758001.345 with TZ="Asia/Istanbul"
@ -2760,6 +2830,9 @@ MILLER(1) MILLER(1)
1msubstr10m 1msubstr10m
(class=string #args=3) substr1(s,m,n) gives substring of s from 1-up position m to n inclusive. Negative indices -len .. -1 alias to 1 .. len. See also substr and substr0. (class=string #args=3) substr1(s,m,n) gives substring of s from 1-up position m to n inclusive. Negative indices -len .. -1 alias to 1 .. len. See also substr and substr0.
1msysntime0m
(class=time #args=0) Returns the system time in 64-bit nanoseconds since the epoch.
1msystem0m 1msystem0m
(class=system #args=1) Run command string, yielding its stdout minus final carriage return. (class=system #args=1) Run command string, yielding its stdout minus final carriage return.
@ -2806,6 +2879,9 @@ MILLER(1) MILLER(1)
unformatx("{}h{}m{}s", "3h47m22s") gives ["3", "47", "22"]. unformatx("{}h{}m{}s", "3h47m22s") gives ["3", "47", "22"].
is_error(unformatx("{}h{}m{}s", "3:47:22")) gives true. is_error(unformatx("{}h{}m{}s", "3:47:22")) gives true.
1mupntime0m
(class=time #args=0) Returns the time in 64-bit nanoseconds since the current Miller program was started.
1muptime0m 1muptime0m
(class=time #args=0) Returns the time in floating-point seconds since the current Miller program was started. (class=time #args=0) Returns the time in floating-point seconds since the current Miller program was started.
@ -3333,4 +3409,4 @@ MILLER(1) MILLER(1)
2023-06-06 MILLER(1) 2023-06-24 MILLER(1)

200
man/mlr.1
View file

@ -2,12 +2,12 @@
.\" Title: mlr .\" Title: mlr
.\" Author: [see the "AUTHOR" section] .\" Author: [see the "AUTHOR" section]
.\" Generator: ./mkman.rb .\" Generator: ./mkman.rb
.\" Date: 2023-06-06 .\" Date: 2023-06-24
.\" Manual: \ \& .\" Manual: \ \&
.\" Source: \ \& .\" Source: \ \&
.\" Language: English .\" Language: English
.\" .\"
.TH "MILLER" "1" "2023-06-06" "\ \&" "\ \&" .TH "MILLER" "1" "2023-06-24" "\ \&" "\ \&"
.\" ----------------------------------------------------------------- .\" -----------------------------------------------------------------
.\" * Portability definitions .\" * Portability definitions
.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -237,21 +237,23 @@ asserting_present asserting_string atan atan2 atanh bitcount boolean
capitalize cbrt ceil clean_whitespace collapse_whitespace concat cos cosh capitalize cbrt ceil clean_whitespace collapse_whitespace concat cos cosh
depth dhms2fsec dhms2sec erf erfc every exec exp expm1 flatten float floor depth dhms2fsec dhms2sec erf erfc every exec exp expm1 flatten float floor
fmtifnum fmtnum fold format fsec2dhms fsec2hms get_keys get_values fmtifnum fmtnum fold format fsec2dhms fsec2hms get_keys get_values
gmt2localtime gmt2sec gssub gsub haskey hexfmt hms2fsec hms2sec hostname index gmt2localtime gmt2nsec gmt2sec gssub gsub haskey hexfmt hms2fsec hms2sec
int invqnorm is_absent is_array is_bool is_boolean is_empty is_empty_map hostname index int invqnorm is_absent is_array is_bool is_boolean is_empty
is_error is_float is_int is_map is_nan is_nonempty_map is_not_array is_empty_map is_error is_float is_int is_map is_nan is_nonempty_map
is_not_empty is_not_map is_not_null is_null is_numeric is_present is_string is_not_array is_not_empty is_not_map is_not_null is_null is_numeric is_present
joink joinkv joinv json_parse json_stringify latin1_to_utf8 leafcount leftpad is_string joink joinkv joinv json_parse json_stringify latin1_to_utf8
length localtime2gmt localtime2sec log log10 log1p logifit lstrip madd mapdiff leafcount leftpad length localtime2gmt localtime2nsec localtime2sec log log10
mapexcept mapselect mapsum max md5 mexp min mmul msub os pow qnorm reduce log1p logifit lstrip madd mapdiff mapexcept mapselect mapsum max md5 mexp min
regextract regextract_or_else rightpad round roundm rstrip sec2dhms sec2gmt mmul msub nsec2gmt nsec2gmtdate nsec2localdate nsec2localtime os pow qnorm
sec2gmtdate sec2hms sec2localdate sec2localtime select sgn sha1 sha256 sha512 reduce regextract regextract_or_else rightpad round roundm rstrip sec2dhms
sin sinh sort splita splitax splitkv splitkvx splitnv splitnvx sqrt ssub sec2gmt sec2gmtdate sec2hms sec2localdate sec2localtime select sgn sha1 sha256
strftime strftime_local string strip strlen strptime strptime_local sub substr sha512 sin sinh sort splita splitax splitkv splitkvx splitnv splitnvx sqrt
substr0 substr1 system systime systimeint tan tanh tolower toupper truncate ssub strfntime strfntime_local strftime strftime_local string strip strlen
typeof unflatten unformat unformatx uptime urand urand32 urandelement urandint strpntime strpntime_local strptime strptime_local sub substr substr0 substr1
urandrange utf8_to_latin1 version ! != !=~ % & && * ** + - . .* .+ .- ./ / // sysntime system systime systimeint tan tanh tolower toupper truncate typeof
< << <= <=> == =~ > >= >> >>> ?: ?? ??? ^ ^^ | || ~ unflatten unformat unformatx upntime uptime urand urand32 urandelement
urandint urandrange utf8_to_latin1 version ! != !=~ % & && * ** + - . .* .+ .-
\&./ / // < << <= <=> == =~ > >= >> >>> ?: ?? ??? ^ ^^ | || ~
.fi .fi
.if n \{\ .if n \{\
.RE .RE
@ -1480,13 +1482,13 @@ Options:
Note that "mlr filter" is more powerful, but requires you to know field names. Note that "mlr filter" is more powerful, but requires you to know field names.
By contrast, "mlr grep" allows you to regex-match the entire record. It does this By contrast, "mlr grep" allows you to regex-match the entire record. It does this
by formatting each record in memory as DKVP (or NIDX, if -a is supplied), using by formatting each record in memory as DKVP (or NIDX, if -a is supplied), using
OFS "," and OPS "=", and matching the resulting line against the regex specified command-line-specified ORS/OFS/OPS, and matching the resulting line against the
here. In particular, the regex is not applied to the input stream: if you have regex specified here. In particular, the regex is not applied to the input
CSV with header line "x,y,z" and data line "1,2,3" then the regex will be stream: if you have CSV with header line "x,y,z" and data line "1,2,3" then the
matched, not against either of these lines, but against the DKVP line regex will be matched, not against either of these lines, but against the DKVP
"x=1,y=2,z=3". Furthermore, not all the options to system grep are supported, line "x=1,y=2,z=3". Furthermore, not all the options to system grep are
and this command is intended to be merely a keystroke-saver. To get all the supported, and this command is intended to be merely a keystroke-saver. To get
features of system grep, you can do all the features of system grep, you can do
"mlr --odkvp ... | grep ... | mlr --idkvp ..." "mlr --odkvp ... | grep ... | mlr --idkvp ..."
.fi .fi
.if n \{\ .if n \{\
@ -3269,6 +3271,17 @@ gmt2localtime("1999-12-31T22:00:00Z", "Asia/Istanbul") = "2000-01-01 00:00:00"
.fi .fi
.if n \{\ .if n \{\
.RE .RE
.SS "gmt2nsec"
.if n \{\
.RS 0
.\}
.nf
(class=time #args=1) Parses GMT timestamp as integer nanoseconds since the epoch.
Example:
gmt2nsec("2001-02-03T04:05:06Z") = 981173106000000000
.fi
.if n \{\
.RE
.SS "gmt2sec" .SS "gmt2sec"
.if n \{\ .if n \{\
.RS 0 .RS 0
@ -3680,6 +3693,18 @@ localtime2gmt("2000-01-01 00:00:00", "Asia/Istanbul") = "1999-12-31T22:00:00Z"
.fi .fi
.if n \{\ .if n \{\
.RE .RE
.SS "localtime2nsec"
.if n \{\
.RS 0
.\}
.nf
(class=time #args=1,2) Parses local timestamp as integer nanoseconds since the epoch. Consults $TZ environment variable, unless second argument is supplied.
Examples:
localtime2nsec("2001-02-03 04:05:06") = 981165906000000000 with TZ="Asia/Istanbul"
localtime2nsec("2001-02-03 04:05:06", "Asia/Istanbul") = 981165906000000000"
.fi
.if n \{\
.RE
.SS "localtime2sec" .SS "localtime2sec"
.if n \{\ .if n \{\
.RS 0 .RS 0
@ -3836,6 +3861,56 @@ localtime2sec("2001-02-03 04:05:06", "Asia/Istanbul") = 981165906"
.fi .fi
.if n \{\ .if n \{\
.RE .RE
.SS "nsec2gmt"
.if n \{\
.RS 0
.\}
.nf
(class=time #args=1,2) Formats integer nanoseconds since epoch as GMT timestamp. Leaves non-numbers as-is. With second integer argument n, includes n decimal places for the seconds part.
Examples:
nsec2gmt(1234567890000000000) = "2009-02-13T23:31:30Z"
nsec2gmt(1234567890123456789) = "2009-02-13T23:31:30Z"
nsec2gmt(1234567890123456789, 6) = "2009-02-13T23:31:30.123456Z"
.fi
.if n \{\
.RE
.SS "nsec2gmtdate"
.if n \{\
.RS 0
.\}
.nf
(class=time #args=1) Formats integer nanoseconds since epoch as GMT timestamp with year-month-date. Leaves non-numbers as-is.
Example:
sec2gmtdate(1440768801700000000) = "2015-08-28".
.fi
.if n \{\
.RE
.SS "nsec2localdate"
.if n \{\
.RS 0
.\}
.nf
(class=time #args=1,2) Formats integer nanoseconds since epoch as local timestamp with year-month-date. Leaves non-numbers as-is. Consults $TZ environment variable unless second argument is supplied.
Examples:
nsec2localdate(1440768801700000000) = "2015-08-28" with TZ="Asia/Istanbul"
nsec2localdate(1440768801700000000, "Asia/Istanbul") = "2015-08-28"
.fi
.if n \{\
.RE
.SS "nsec2localtime"
.if n \{\
.RS 0
.\}
.nf
(class=time #args=1,2,3) Formats integer nanoseconds since epoch as local timestamp. Consults $TZ environment variable unless third argument is supplied. Leaves non-numbers as-is. With second integer argument n, includes n decimal places for the seconds part
Examples:
nsec2localtime(1234567890000000000) = "2009-02-14 01:31:30" with TZ="Asia/Istanbul"
nsec2localtime(1234567890123456789) = "2009-02-14 01:31:30" with TZ="Asia/Istanbul"
nsec2localtime(1234567890123456789, 6) = "2009-02-14 01:31:30.123456" with TZ="Asia/Istanbul"
nsec2localtime(1234567890123456789, 6, "Asia/Istanbul") = "2009-02-14 01:31:30.123456"
.fi
.if n \{\
.RE
.SS "os" .SS "os"
.if n \{\ .if n \{\
.RS 0 .RS 0
@ -4181,6 +4256,33 @@ ssub("abc.def", ".", "X") gives "abcXdef"
.fi .fi
.if n \{\ .if n \{\
.RE .RE
.SS "strfntime"
.if n \{\
.RS 0
.\}
.nf
(class=time #args=2) Formats integer nanoseconds 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 https://miller.readthedocs.io/en/latest/reference-dsl-time/ for more information on the differences from the C library ("man strftime" on your system). See also strftime_local.
Examples:
strfntime(1440768801123456789,"%Y-%m-%dT%H:%M:%SZ") = "2015-08-28T13:33:21Z"
strfntime(1440768801123456789,"%Y-%m-%dT%H:%M:%3SZ") = "2015-08-28T13:33:21.123Z"
strfntime(1440768801123456789,"%Y-%m-%dT%H:%M:%6SZ") = "2015-08-28T13:33:21.123456Z"
.fi
.if n \{\
.RE
.SS "strfntime_local"
.if n \{\
.RS 0
.\}
.nf
(class=time #args=2,3) Like strfntime but consults the $TZ environment variable to get local time zone.
Examples:
strfntime_local(1440768801123456789, "%Y-%m-%d %H:%M:%S %z") = "2015-08-28 16:33:21 +0300" with TZ="Asia/Istanbul"
strfntime_local(1440768801123456789, "%Y-%m-%d %H:%M:%3S %z") = "2015-08-28 16:33:21.123 +0300" with TZ="Asia/Istanbul"
strfntime_local(1440768801123456789, "%Y-%m-%d %H:%M:%3S %z", "Asia/Istanbul") = "2015-08-28 16:33:21.123 +0300"
strfntime_local(1440768801123456789, "%Y-%m-%d %H:%M:%9S %z", "Asia/Istanbul") = "2015-08-28 16:33:21.123456789 +0300"
.fi
.if n \{\
.RE
.SS "strftime" .SS "strftime"
.if n \{\ .if n \{\
.RS 0 .RS 0
@ -4233,6 +4335,34 @@ strftime_local(1440768801.7, "%Y-%m-%d %H:%M:%3S %z", "Asia/Istanbul") = "2015-0
.fi .fi
.if n \{\ .if n \{\
.RE .RE
.SS "strpntime"
.if n \{\
.RS 0
.\}
.nf
(class=time #args=2) strpntime: Parses timestamp as integer nanoseconds since the epoch. See also strpntime_local.
Examples:
strpntime("2015-08-28T13:33:21Z", "%Y-%m-%dT%H:%M:%SZ") = 1440768801000000000
strpntime("2015-08-28T13:33:21.345Z", "%Y-%m-%dT%H:%M:%SZ") = 1440768801345000000
strpntime("1970-01-01 00:00:00 -0400", "%Y-%m-%d %H:%M:%S %z") = 14400000000000
strpntime("1970-01-01 00:00:00 +0200", "%Y-%m-%d %H:%M:%S %z") = -7200000000000
.fi
.if n \{\
.RE
.SS "strpntime_local"
.if n \{\
.RS 0
.\}
.nf
(class=time #args=2,3) Like strpntime but consults the $TZ environment variable to get local time zone.
Examples:
strpntime_local("2015-08-28T13:33:21Z", "%Y-%m-%dT%H:%M:%SZ") = 1440758001000000000 with TZ="Asia/Istanbul"
strpntime_local("2015-08-28T13:33:21.345Z","%Y-%m-%dT%H:%M:%SZ") = 1440758001345000000 with TZ="Asia/Istanbul"
strpntime_local("2015-08-28 13:33:21", "%Y-%m-%d %H:%M:%S") = 1440758001000000000 with TZ="Asia/Istanbul"
strpntime_local("2015-08-28 13:33:21", "%Y-%m-%d %H:%M:%S", "Asia/Istanbul") = 1440758001000000000
.fi
.if n \{\
.RE
.SS "strptime" .SS "strptime"
.if n \{\ .if n \{\
.RS 0 .RS 0
@ -4243,7 +4373,7 @@ Examples:
strptime("2015-08-28T13:33:21Z", "%Y-%m-%dT%H:%M:%SZ") = 1440768801.000000 strptime("2015-08-28T13:33:21Z", "%Y-%m-%dT%H:%M:%SZ") = 1440768801.000000
strptime("2015-08-28T13:33:21.345Z", "%Y-%m-%dT%H:%M:%SZ") = 1440768801.345000 strptime("2015-08-28T13:33:21.345Z", "%Y-%m-%dT%H:%M:%SZ") = 1440768801.345000
strptime("1970-01-01 00:00:00 -0400", "%Y-%m-%d %H:%M:%S %z") = 14400 strptime("1970-01-01 00:00:00 -0400", "%Y-%m-%d %H:%M:%S %z") = 14400
strptime("1970-01-01 00:00:00 EET", "%Y-%m-%d %H:%M:%S %Z") = -7200 strptime("1970-01-01 00:00:00 +0200", "%Y-%m-%d %H:%M:%S %z") = -7200
.fi .fi
.if n \{\ .if n \{\
.RE .RE
@ -4252,7 +4382,7 @@ strptime("1970-01-01 00:00:00 EET", "%Y-%m-%d %H:%M:%S %Z") = -7200
.RS 0 .RS 0
.\} .\}
.nf .nf
(class=time #args=2,3) Like strftime but consults the $TZ environment variable to get local time zone. (class=time #args=2,3) Like strptime but consults the $TZ environment variable to get local time zone.
Examples: Examples:
strptime_local("2015-08-28T13:33:21Z", "%Y-%m-%dT%H:%M:%SZ") = 1440758001 with TZ="Asia/Istanbul" strptime_local("2015-08-28T13:33:21Z", "%Y-%m-%dT%H:%M:%SZ") = 1440758001 with TZ="Asia/Istanbul"
strptime_local("2015-08-28T13:33:21.345Z","%Y-%m-%dT%H:%M:%SZ") = 1440758001.345 with TZ="Asia/Istanbul" strptime_local("2015-08-28T13:33:21.345Z","%Y-%m-%dT%H:%M:%SZ") = 1440758001.345 with TZ="Asia/Istanbul"
@ -4303,6 +4433,15 @@ sub("prefix4529:suffix8567", "suffix([0-9]+)", "name\e1") gives "prefix4529:name
.fi .fi
.if n \{\ .if n \{\
.RE .RE
.SS "sysntime"
.if n \{\
.RS 0
.\}
.nf
(class=time #args=0) Returns the system time in 64-bit nanoseconds since the epoch.
.fi
.if n \{\
.RE
.SS "system" .SS "system"
.if n \{\ .if n \{\
.RS 0 .RS 0
@ -4421,6 +4560,15 @@ is_error(unformatx("{}h{}m{}s", "3:47:22")) gives true.
.fi .fi
.if n \{\ .if n \{\
.RE .RE
.SS "upntime"
.if n \{\
.RS 0
.\}
.nf
(class=time #args=0) Returns the time in 64-bit nanoseconds since the current Miller program was started.
.fi
.if n \{\
.RE
.SS "uptime" .SS "uptime"
.if n \{\ .if n \{\
.RS 0 .RS 0

View file

@ -0,0 +1 @@
mlr --csvlite put -f ${CASEDIR}/mlr test/input/gmt2nsec

View file

@ -0,0 +1,29 @@
gmt,sec
1970-01-01T00:00:00Z,0
1970-01-01T00:00:00.Z,(error)
1970-01-01T00:00:01Z,1000000000
1970-01-01T00:00:01.0Z,1000000000
1970-01-01T00:00:10Z,10000000000
1970-01-01T00:00:10.00Z,10000000000
1970-01-01T00:01:40Z,100000000000
1970-01-01T00:01:40.1Z,100100000000
1970-01-01T00:16:40Z,1000000000000
1970-01-01T00:16:40.12Z,1000120000000
1970-01-01T02:46:40Z,10000000000000
1970-01-01T02:46:40.123Z,10000123000000
1970-01-02T03:46:40Z,100000000000000
1970-01-02T03:46:40.1234Z,100000123400000
1970-01-12T13:46:40Z,1000000000000000
1970-01-12T13:46:40.12345Z,1000000123450000
1970-04-26T17:46:40Z,10000000000000000
1970-04-26T17:46:40.123456Z,10000000123456000
1973-03-03T09:46:40Z,100000000000000000
1973-03-03T09:46:40.1234567Z,100000000123456700
2001-09-09T01:46:40Z,1000000000000000000
2001-09-09T01:46:40.12345678Z,1000000000123456780
2015-05-19T11:49:40Z,1432036180000000000
2015-05-19T11:49:40.123456789Z,1432036180123456789
2017-07-14T02:40:00Z,1500000000000000000
2017-07-14T02:40:00.999Z,1500000000999000000
2033-05-18T03:33:20Z,2000000000000000000
2033-05-18T03:33:20.999999Z,2000000000999999000

View file

@ -0,0 +1 @@
$sec = gmt2nsec($gmt)

View file

@ -0,0 +1 @@
mlr --icsv --opprint put -f ${CASEDIR}/mlr test/input/gmt2nsec

View file

@ -0,0 +1,29 @@
gmt sec
1970-01-01T00:00:00Z 0
1970-01-01T00:00:00.Z (error)
1970-01-01T00:00:01Z 1000000000
1970-01-01T00:00:01.0Z 1000000000
1970-01-01T00:00:10Z 10000000000
1970-01-01T00:00:10.00Z 10000000000
1970-01-01T00:01:40Z 100000000000
1970-01-01T00:01:40.1Z 100100000000
1970-01-01T00:16:40Z 1000000000000
1970-01-01T00:16:40.12Z 1000120000000
1970-01-01T02:46:40Z 10000000000000
1970-01-01T02:46:40.123Z 10000123000000
1970-01-02T03:46:40Z 100000000000000
1970-01-02T03:46:40.1234Z 100000123400000
1970-01-12T13:46:40Z 1000000000000000
1970-01-12T13:46:40.12345Z 1000000123450000
1970-04-26T17:46:40Z 10000000000000000
1970-04-26T17:46:40.123456Z 10000000123456000
1973-03-03T09:46:40Z 100000000000000000
1973-03-03T09:46:40.1234567Z 100000000123456700
2001-09-09T01:46:40Z 1000000000000000000
2001-09-09T01:46:40.12345678Z 1000000000123456780
2015-05-19T11:49:40Z 1432036180000000000
2015-05-19T11:49:40.123456789Z 1432036180123456789
2017-07-14T02:40:00Z 1500000000000000000
2017-07-14T02:40:00.999Z 1500000000999000000
2033-05-18T03:33:20Z 2000000000000000000
2033-05-18T03:33:20.999999Z 2000000000999999000

View file

@ -0,0 +1 @@
$sec = strpntime($gmt, "%Y-%m-%dT%H:%M:%SZ")

View file

@ -0,0 +1 @@
mlr --icsv --opprint put -f ${CASEDIR}/mlr test/input/gmt2sec

View file

@ -0,0 +1,29 @@
gmt sec
1970-01-01T00:00:00Z 0.00000000
1970-01-01T00:00:00.Z (error)
1970-01-01T00:00:01Z 1.00000000
1970-01-01T00:00:01.0Z 1.00000000
1970-01-01T00:00:10Z 10.00000000
1970-01-01T00:00:10.00Z 10.00000000
1970-01-01T00:01:40Z 100.00000000
1970-01-01T00:01:40.1Z 100.10000000
1970-01-01T00:16:40Z 1000.00000000
1970-01-01T00:16:40.12Z 1000.12000000
1970-01-01T02:46:40Z 10000.00000000
1970-01-01T02:46:40.123Z 10000.12300000
1970-01-02T03:46:40Z 100000.00000000
1970-01-02T03:46:40.1234Z 100000.12340000
1970-01-12T13:46:40Z 1000000.00000000
1970-01-12T13:46:40.12345Z 1000000.12345000
1970-04-26T17:46:40Z 10000000.00000000
1970-04-26T17:46:40.123456Z 10000000.12345600
1973-03-03T09:46:40Z 100000000.00000000
1973-03-03T09:46:40.1234567Z 100000000.12345670
2001-09-09T01:46:40Z 1000000000.00000000
2001-09-09T01:46:40.12345678Z 1000000000.12345672
2015-05-19T11:49:40Z 1432036180.00000000
2015-05-19T11:49:40.123456789Z 1432036180.12345672
2017-07-14T02:40:00Z 1500000000.00000000
2017-07-14T02:40:00.999Z 1500000000.99900007
2033-05-18T03:33:20Z 2000000000.00000000
2033-05-18T03:33:20.999999Z 2000000000.99999905

View file

@ -0,0 +1 @@
$sec = strptime($gmt, "%FT%TZ")

View file

@ -0,0 +1 @@
mlr --icsv --opprint put -f ${CASEDIR}/mlr test/input/gmt2nsec

View file

@ -0,0 +1,29 @@
gmt sec
1970-01-01T00:00:00Z 0
1970-01-01T00:00:00.Z (error)
1970-01-01T00:00:01Z 1000000000
1970-01-01T00:00:01.0Z 1000000000
1970-01-01T00:00:10Z 10000000000
1970-01-01T00:00:10.00Z 10000000000
1970-01-01T00:01:40Z 100000000000
1970-01-01T00:01:40.1Z 100100000000
1970-01-01T00:16:40Z 1000000000000
1970-01-01T00:16:40.12Z 1000120000000
1970-01-01T02:46:40Z 10000000000000
1970-01-01T02:46:40.123Z 10000123000000
1970-01-02T03:46:40Z 100000000000000
1970-01-02T03:46:40.1234Z 100000123400000
1970-01-12T13:46:40Z 1000000000000000
1970-01-12T13:46:40.12345Z 1000000123450000
1970-04-26T17:46:40Z 10000000000000000
1970-04-26T17:46:40.123456Z 10000000123456000
1973-03-03T09:46:40Z 100000000000000000
1973-03-03T09:46:40.1234567Z 100000000123456700
2001-09-09T01:46:40Z 1000000000000000000
2001-09-09T01:46:40.12345678Z 1000000000123456780
2015-05-19T11:49:40Z 1432036180000000000
2015-05-19T11:49:40.123456789Z 1432036180123456789
2017-07-14T02:40:00Z 1500000000000000000
2017-07-14T02:40:00.999Z 1500000000999000000
2033-05-18T03:33:20Z 2000000000000000000
2033-05-18T03:33:20.999999Z 2000000000999999000

View file

@ -0,0 +1 @@
$sec = strpntime($gmt, "%FT%TZ")

View file

@ -0,0 +1 @@
mlr -n put -f ${CASEDIR}/mlr

View file

@ -0,0 +1,10 @@
0
0
14400000000000
0
0
31276800000000000
80430000000000
138000000000000
(error)
31536000123456000.00000000

View file

@ -0,0 +1,12 @@
end {
print strpntime("1970-01-01T00:00:00Z", "%Y-%m-%dT%H:%M:%SZ");
print strpntime("1970-01-01T00:00:00Z", "%Y-%m-%dT%H:%M:%SZ");
print strpntime("1970-01-01 00:00:00 -0400", "%Y-%m-%d %H:%M:%S %z");
print strpntime("1970-01-01%00:00:00Z", "%Y-%m-%d%%%H:%M:%SZ");
print strpntime("1970-01-01T00:00:00Z", "%FT%TZ");
print strpntime("1970:363", "%Y:%j");
print strpntime("1970-01-01 10:20:30 PM", "%F %r");
print strpntime("01/02/70 14:20", "%D %R");
print strpntime("01/02/70 14:20", "%D %X"); # no such format code
print fmtnum(strpntime("1971-01-01T00:00:00.123456Z", "%Y-%m-%dT%H:%M:%S.%fZ"), "%.6f");
}

View file

@ -0,0 +1 @@
mlr --opprint --from ${CASEDIR}/input put -f ${CASEDIR}/mlr

View file

@ -0,0 +1 @@
TZ=America/Sao_Paulo

View file

@ -0,0 +1,11 @@
a b c tz
2017-02-18 23:00:00 1487466000000000000 2017-02-18 23:00:00 America/Sao_Paulo
2017-02-18 23:59:59 1487469599000000000 2017-02-18 23:59:59 America/Sao_Paulo
2017-02-19 00:00:00 1487473200000000000 2017-02-19 00:00:00 America/Sao_Paulo
2017-02-19 00:30:00 1487475000000000000 2017-02-19 00:30:00 America/Sao_Paulo
2017-02-19 01:00:00 1487476800000000000 2017-02-19 01:00:00 America/Sao_Paulo
2017-10-14 23:00:00 1508032800000000000 2017-10-14 23:00:00 America/Sao_Paulo
2017-10-14 23:59:59 1508036399000000000 2017-10-14 23:59:59 America/Sao_Paulo
2017-10-15 00:00:00 1508032800000000000 2017-10-14 23:00:00 America/Sao_Paulo
2017-10-15 00:30:00 1508034600000000000 2017-10-14 23:30:00 America/Sao_Paulo
2017-10-15 01:00:00 1508036400000000000 2017-10-15 01:00:00 America/Sao_Paulo

View file

@ -0,0 +1,10 @@
a=2017-02-18 23:00:00
a=2017-02-18 23:59:59
a=2017-02-19 00:00:00
a=2017-02-19 00:30:00
a=2017-02-19 01:00:00
a=2017-10-14 23:00:00
a=2017-10-14 23:59:59
a=2017-10-15 00:00:00
a=2017-10-15 00:30:00
a=2017-10-15 01:00:00

View file

@ -0,0 +1,3 @@
$b = strpntime_local($a, "%Y-%m-%d %H:%M:%S");
$c = strfntime_local($b, "%Y-%m-%d %H:%M:%S");
$tz = ENV["TZ"];

View file

@ -0,0 +1 @@
mlr --opprint --from ${CASEDIR}/input put -f ${CASEDIR}/mlr

View file

@ -0,0 +1 @@
TZ=America/Sao_Paulo

View file

@ -0,0 +1,11 @@
a b c tz
2017-02-18 23:00:00 1487466000000000000 2017-02-18 23:00:00 America/Sao_Paulo
2017-02-18 23:59:59 1487469599000000000 2017-02-18 23:59:59 America/Sao_Paulo
2017-02-19 00:00:00 1487473200000000000 2017-02-19 00:00:00 America/Sao_Paulo
2017-02-19 00:30:00 1487475000000000000 2017-02-19 00:30:00 America/Sao_Paulo
2017-02-19 01:00:00 1487476800000000000 2017-02-19 01:00:00 America/Sao_Paulo
2017-10-14 23:00:00 1508032800000000000 2017-10-14 23:00:00 America/Sao_Paulo
2017-10-14 23:59:59 1508036399000000000 2017-10-14 23:59:59 America/Sao_Paulo
2017-10-15 00:00:00 1508032800000000000 2017-10-14 23:00:00 America/Sao_Paulo
2017-10-15 00:30:00 1508034600000000000 2017-10-14 23:30:00 America/Sao_Paulo
2017-10-15 01:00:00 1508036400000000000 2017-10-15 01:00:00 America/Sao_Paulo

View file

@ -0,0 +1,10 @@
a=2017-02-18 23:00:00
a=2017-02-18 23:59:59
a=2017-02-19 00:00:00
a=2017-02-19 00:30:00
a=2017-02-19 01:00:00
a=2017-10-14 23:00:00
a=2017-10-14 23:59:59
a=2017-10-15 00:00:00
a=2017-10-15 00:30:00
a=2017-10-15 01:00:00

View file

@ -0,0 +1,3 @@
$b = strpntime_local($a, "%Y-%m-%d %H:%M:%S");
$c = strfntime_local($b, "%Y-%m-%d %H:%M:%S");
$tz = ENV["TZ"];

View file

@ -0,0 +1 @@
mlr -n put -f ${CASEDIR}/mlr

View file

@ -0,0 +1,23 @@
1969-12-31 21:00:00
1970-01-01 02:00:00
1969-12-31
1970-01-01
10800000000000
-7200000000000
10800000000000
-7200000000000
10800000000000
-7200000000000
1969-12-31 21:00:00
1970-01-01 02:00:00
1969-12-31 21:00:00
1970-01-01 02:00:00
1970-01-01T03:00:00Z
1969-12-31T22:00:00Z

View file

@ -0,0 +1,39 @@
end {
sao = "America/Sao_Paulo";
ist = "Asia/Istanbul";
iso = "%Y-%m-%dT%H:%M:%SZ";
loc = "%Y-%m-%d %H:%M:%S";
zeg = "1970-01-01T00:00:00Z";
zel = "1970-01-01 00:00:00";
print(nsec2localtime(0, 0, sao));
print(nsec2localtime(0, 0, ist));
print;
print(nsec2localdate(0, sao));
print(nsec2localdate(0, ist));
print;
print(localtime2nsec(zel, sao));
print(localtime2nsec(zel, ist));
print;
print(localtime2nsec(zel, sao));
print(localtime2nsec(zel, ist));
print;
print(strpntime_local(zel, loc, sao));
print(strpntime_local(zel, loc, ist));
print;
print(strfntime_local(0, loc, sao));
print(strfntime_local(0, loc, ist));
print;
print(gmt2localtime(zeg, sao));
print(gmt2localtime(zeg, ist));
print;
print(localtime2gmt(zel, sao));
print(localtime2gmt(zel, ist));
}

View file

@ -0,0 +1 @@
mlr --tz Asia/Istanbul -n put -f test/input/strfntime-tz.mlr

View file

@ -0,0 +1,12 @@
---------------------------------------------------------------- TIMEZONE
TZ is Asia/Istanbul
---------------------------------------------------------------- STRFNTIME
1970-01-01T00:00:00Z
1970-01-01 00:00:00
1970-01-01 00:00:00.000
1970-01-01 00:00:00 UTC
1970-01-01 00:00:00 +0000
1970-01-01 00:00:00 UTC
1970-01-01 00:00:00 +0000
1970-01-01 00:00:00 UTC
1970-01-01 00:00:00 +0000

View file

@ -0,0 +1 @@
mlr --tz America/Sao_Paulo -n put -f test/input/strfntime-tz.mlr

View file

@ -0,0 +1,12 @@
---------------------------------------------------------------- TIMEZONE
TZ is America/Sao_Paulo
---------------------------------------------------------------- STRFNTIME
1970-01-01T00:00:00Z
1970-01-01 00:00:00
1970-01-01 00:00:00.000
1970-01-01 00:00:00 UTC
1970-01-01 00:00:00 +0000
1970-01-01 00:00:00 UTC
1970-01-01 00:00:00 +0000
1970-01-01 00:00:00 UTC
1970-01-01 00:00:00 +0000

View file

@ -0,0 +1 @@
mlr --tz UTC -n put -f test/input/strfntime-tz.mlr

View file

@ -0,0 +1,12 @@
---------------------------------------------------------------- TIMEZONE
TZ is UTC
---------------------------------------------------------------- STRFNTIME
1970-01-01T00:00:00Z
1970-01-01 00:00:00
1970-01-01 00:00:00.000
1970-01-01 00:00:00 UTC
1970-01-01 00:00:00 +0000
1970-01-01 00:00:00 UTC
1970-01-01 00:00:00 +0000
1970-01-01 00:00:00 UTC
1970-01-01 00:00:00 +0000

View file

@ -0,0 +1 @@
mlr --tz Asia/Istanbul -n put -f test/input/strfntime_local-tz.mlr

View file

@ -0,0 +1,11 @@
---------------------------------------------------------------- TIMEZONE
TZ is Asia/Istanbul
---------------------------------------------------------------- STRFNTIME_LOCAL
1970-01-01 02:00:00
1970-01-01 02:00:00.000
1970-01-01 02:00:00 EET
1970-01-01 02:00:00 +0200
1970-01-01 02:00:00 EET
1970-01-01 02:00:00 +0200
1970-01-01 02:00:00 EET
1970-01-01 02:00:00 +0200

View file

@ -0,0 +1 @@
mlr --tz America/Sao_Paulo -n put -f test/input/strfntime_local-tz.mlr

View file

@ -0,0 +1,11 @@
---------------------------------------------------------------- TIMEZONE
TZ is America/Sao_Paulo
---------------------------------------------------------------- STRFNTIME_LOCAL
1969-12-31 21:00:00
1969-12-31 21:00:00.000
1969-12-31 21:00:00 -03
1969-12-31 21:00:00 -0300
1969-12-31 21:00:00 -03
1969-12-31 21:00:00 -0300
1969-12-31 21:00:00 -03
1969-12-31 21:00:00 -0300

View file

@ -0,0 +1 @@
mlr --tz UTC -n put -f test/input/strfntime_local-tz.mlr

View file

@ -0,0 +1,11 @@
---------------------------------------------------------------- TIMEZONE
TZ is UTC
---------------------------------------------------------------- STRFNTIME_LOCAL
1970-01-01 00:00:00
1970-01-01 00:00:00.000
1970-01-01 00:00:00 UTC
1970-01-01 00:00:00 +0000
1970-01-01 00:00:00 UTC
1970-01-01 00:00:00 +0000
1970-01-01 00:00:00 UTC
1970-01-01 00:00:00 +0000

View file

@ -0,0 +1 @@
mlr --tz Asia/Istanbul -n put -f test/input/strpntime-tz.mlr

View file

@ -0,0 +1,9 @@
---------------------------------------------------------------- TIMEZONE
TZ is Asia/Istanbul
---------------------------------------------------------------- STRPNTIME
0
345000000
345000000
345000000
14400345000000
-14399655000000

View file

@ -0,0 +1 @@
mlr --tz UTC -n put -f ${CASEDIR}/mlr

View file

@ -0,0 +1,2 @@
2021-01-01
2021-12-29

View file

@ -0,0 +1,4 @@
end {
print strfntime(strpntime("001 2021", "%j %Y"),"%Y-%m-%d");
print strfntime(strpntime("363 2021", "%j %Y"),"%Y-%m-%d");
}

View file

@ -0,0 +1 @@
mlr --tz America/Sao_Paulo -n put -f test/input/strpntime-tz.mlr

View file

@ -0,0 +1,9 @@
---------------------------------------------------------------- TIMEZONE
TZ is America/Sao_Paulo
---------------------------------------------------------------- STRPNTIME
0
345000000
345000000
345000000
14400345000000
-14399655000000

View file

@ -0,0 +1 @@
mlr --tz UTC -n put -f test/input/strpntime-tz.mlr

View file

@ -0,0 +1,9 @@
---------------------------------------------------------------- TIMEZONE
TZ is UTC
---------------------------------------------------------------- STRPNTIME
0
345000000
345000000
345000000
14400345000000
-14399655000000

View file

@ -0,0 +1 @@
mlr -n put -f ${CASEDIR}/mlr

View file

@ -0,0 +1,15 @@
TZ UTC
intime 1970-01-01T00:00:00-0400
parsed 14400000000000
formatted 1970-01-01T04:00:00+0000
TZ America/Sao_Paulo
intime 1970-01-01T00:00:00-0400
parsed 14400000000000
formatted 1970-01-01T04:00:00+0000
TZ Asia/Istanbul
intime 1970-01-01T00:00:00-0400
parsed 14400000000000
formatted 1970-01-01T04:00:00+0000

View file

@ -0,0 +1,17 @@
end {
tzs = ["UTC", "America/Sao_Paulo", "Asia/Istanbul"];
for (tz in tzs) {
ENV["TZ"] = tz;
# Expect these to not vary with $TZ since we are using %z
intime = "1970-01-01T00:00:00-0400";
parsed = strpntime(intime, "%Y-%m-%dT%H:%M:%S%z");
formatted = strfntime(parsed, "%Y-%m-%dT%H:%M:%S%z");
print;
print "TZ ", tz;
print "intime ", intime;
print "parsed ", parsed;
print "formatted", formatted;
}
}

View file

@ -0,0 +1 @@
mlr --tz Asia/Istanbul -n put -f test/input/strpntime_local-tz.mlr

View file

@ -0,0 +1,4 @@
---------------------------------------------------------------- TIMEZONE
TZ is Asia/Istanbul
---------------------------------------------------------------- STRPNTIME_LOCAL
-7200000000000

View file

@ -0,0 +1 @@
mlr --tz America/Sao_Paulo -n put -f test/input/strpntime_local-tz.mlr

View file

@ -0,0 +1,4 @@
---------------------------------------------------------------- TIMEZONE
TZ is America/Sao_Paulo
---------------------------------------------------------------- STRPNTIME_LOCAL
10800000000000

View file

@ -0,0 +1 @@
mlr --tz UTC -n put -f test/input/strpntime_local-tz.mlr

View file

@ -0,0 +1,4 @@
---------------------------------------------------------------- TIMEZONE
TZ is UTC
---------------------------------------------------------------- STRPNTIME_LOCAL
0

View file

@ -0,0 +1 @@
mlr --from test/input/ten.dkvp --opprint put '$z=nsec2gmt($i)'

View file

View file

@ -0,0 +1,11 @@
a b i x y z
pan pan 1 0.34679014 0.72680286 1970-01-01T00:00:00Z
eks pan 2 0.75867996 -0.52215111 1970-01-01T00:00:00Z
wye wye 3 0.20460331 0.33831853 1970-01-01T00:00:00Z
eks wye 4 0.38139939 -0.13418874 1970-01-01T00:00:00Z
wye pan 5 0.57328892 0.86362447 1970-01-01T00:00:00Z
zee pan 6 0.52712616 -0.49322129 1970-01-01T00:00:00Z
eks zee 7 0.61178406 0.18788492 1970-01-01T00:00:00Z
zee wye 8 0.59855401 0.97618139 1970-01-01T00:00:00Z
hat wye 9 0.03144188 -0.74955076 1970-01-01T00:00:00Z
pan wye 10 0.50262601 0.95261836 1970-01-01T00:00:00Z

View file

@ -0,0 +1 @@
mlr --from test/input/ten.dkvp --opprint put '$z=nsec2gmt($i, $i-1)'

View file

View file

@ -0,0 +1,11 @@
a b i x y z
pan pan 1 0.34679014 0.72680286 1970-01-01T00:00:00Z
eks pan 2 0.75867996 -0.52215111 1970-01-01T00:00:00.0Z
wye wye 3 0.20460331 0.33831853 1970-01-01T00:00:00.00Z
eks wye 4 0.38139939 -0.13418874 1970-01-01T00:00:00.000Z
wye pan 5 0.57328892 0.86362447 1970-01-01T00:00:00.0000Z
zee pan 6 0.52712616 -0.49322129 1970-01-01T00:00:00.00000Z
eks zee 7 0.61178406 0.18788492 1970-01-01T00:00:00.000000Z
zee wye 8 0.59855401 0.97618139 1970-01-01T00:00:00.0000000Z
hat wye 9 0.03144188 -0.74955076 1970-01-01T00:00:00.00000000Z
pan wye 10 0.50262601 0.95261836 1970-01-01T00:00:00.000000010Z

View file

@ -0,0 +1 @@
mlr --from test/input/ten.dkvp --opprint put '$z=nsec2gmt($i * 1000000000 * 123456789)'

View file

View file

@ -0,0 +1,11 @@
a b i x y z
pan pan 1 0.34679014 0.72680286 1973-11-29T21:33:09Z
eks pan 2 0.75867996 -0.52215111 1977-10-28T19:06:18Z
wye wye 3 0.20460331 0.33831853 1981-09-26T16:39:27Z
eks wye 4 0.38139939 -0.13418874 1985-08-25T14:12:36Z
wye pan 5 0.57328892 0.86362447 1989-07-24T11:45:45Z
zee pan 6 0.52712616 -0.49322129 1993-06-22T09:18:54Z
eks zee 7 0.61178406 0.18788492 1997-05-21T06:52:03Z
zee wye 8 0.59855401 0.97618139 2001-04-19T04:25:12Z
hat wye 9 0.03144188 -0.74955076 2005-03-18T01:58:21Z
pan wye 10 0.50262601 0.95261836 2009-02-13T23:31:30Z

Some files were not shown because too many files have changed in this diff Show more