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
depth dhms2fsec dhms2sec erf erfc every exec exp expm1 flatten float floor
fmtifnum fmtnum fold format fsec2dhms fsec2hms get_keys get_values
gmt2localtime gmt2sec gssub gsub haskey hexfmt hms2fsec hms2sec hostname index
int invqnorm is_absent is_array is_bool is_boolean is_empty is_empty_map
is_error is_float is_int is_map is_nan is_nonempty_map is_not_array
is_not_empty is_not_map is_not_null is_null is_numeric is_present is_string
joink joinkv joinv json_parse json_stringify latin1_to_utf8 leafcount leftpad
length localtime2gmt localtime2sec log log10 log1p logifit lstrip madd mapdiff
mapexcept mapselect mapsum max md5 mexp min mmul msub os pow qnorm reduce
regextract regextract_or_else rightpad round roundm rstrip sec2dhms sec2gmt
sec2gmtdate sec2hms sec2localdate sec2localtime select sgn sha1 sha256 sha512
sin sinh sort splita splitax splitkv splitkvx splitnv splitnvx sqrt ssub
strftime strftime_local string strip strlen strptime strptime_local sub substr
substr0 substr1 system systime systimeint tan tanh tolower toupper truncate
typeof unflatten unformat unformatx uptime urand urand32 urandelement urandint
urandrange utf8_to_latin1 version ! != !=~ % & && * ** + - . .* .+ .- ./ / //
< << <= <=> == =~ > >= >> >>> ?: ?? ??? ^ ^^ | || ~
gmt2localtime gmt2nsec gmt2sec gssub gsub haskey hexfmt hms2fsec hms2sec
hostname index int invqnorm is_absent is_array is_bool is_boolean is_empty
is_empty_map is_error is_float is_int is_map is_nan is_nonempty_map
is_not_array is_not_empty is_not_map is_not_null is_null is_numeric is_present
is_string joink joinkv joinv json_parse json_stringify latin1_to_utf8
leafcount leftpad length localtime2gmt localtime2nsec localtime2sec log log10
log1p logifit lstrip madd mapdiff mapexcept mapselect mapsum max md5 mexp min
mmul msub nsec2gmt nsec2gmtdate nsec2localdate nsec2localtime os pow qnorm
reduce regextract regextract_or_else rightpad round roundm rstrip sec2dhms
sec2gmt sec2gmtdate sec2hms sec2localdate sec2localtime select sgn sha1 sha256
sha512 sin sinh sort splita splitax splitkv splitkvx splitnv splitnvx sqrt
ssub strfntime strfntime_local strftime strftime_local string strip strlen
strpntime strpntime_local strptime strptime_local sub substr substr0 substr1
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
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.
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
OFS "," and OPS "=", and matching the resulting line against the regex specified
here. In particular, the regex is not applied to the input stream: if you have
CSV with header line "x,y,z" and data line "1,2,3" then the regex will be
matched, not against either of these lines, but against the DKVP line
"x=1,y=2,z=3". Furthermore, not all the options to system grep are supported,
and this command is intended to be merely a keystroke-saver. To get all the
features of system grep, you can do
command-line-specified ORS/OFS/OPS, and matching the resulting line against the
regex specified here. In particular, the regex is not applied to the input
stream: if you have CSV with header line "x,y,z" and data line "1,2,3" then the
regex will be matched, not against either of these lines, but against the DKVP
line "x=1,y=2,z=3". Furthermore, not all the options to system grep are
supported, and this command is intended to be merely a keystroke-saver. To get
all the features of system grep, you can do
"mlr --odkvp ... | grep ... | mlr --idkvp ..."
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", "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
(class=time #args=1) Parses GMT timestamp as integer seconds since the epoch.
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", "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
(class=time #args=1,2) Parses local timestamp as integer seconds since the epoch. Consults $TZ environment variable, unless second argument is supplied.
Examples:
@ -2572,6 +2585,32 @@ MILLER(1) MILLER(1)
1mmsub0m
(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
(class=system #args=0) Returns the operating-system name as a string.
@ -2725,6 +2764,21 @@ MILLER(1) MILLER(1)
Example:
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
(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:
@ -2747,16 +2801,32 @@ MILLER(1) MILLER(1)
1mstrlen0m
(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
(class=time #args=2) strptime: Parses timestamp as floating-point seconds since the epoch. See also strptime_local.
Examples:
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 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
(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:
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"
@ -2781,6 +2851,9 @@ MILLER(1) MILLER(1)
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.
1msysntime0m
(class=time #args=0) Returns the system time in 64-bit nanoseconds since the epoch.
1msystem0m
(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"].
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
(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>

View file

@ -190,21 +190,23 @@ MILLER(1) MILLER(1)
capitalize cbrt ceil clean_whitespace collapse_whitespace concat cos cosh
depth dhms2fsec dhms2sec erf erfc every exec exp expm1 flatten float floor
fmtifnum fmtnum fold format fsec2dhms fsec2hms get_keys get_values
gmt2localtime gmt2sec gssub gsub haskey hexfmt hms2fsec hms2sec hostname index
int invqnorm is_absent is_array is_bool is_boolean is_empty is_empty_map
is_error is_float is_int is_map is_nan is_nonempty_map is_not_array
is_not_empty is_not_map is_not_null is_null is_numeric is_present is_string
joink joinkv joinv json_parse json_stringify latin1_to_utf8 leafcount leftpad
length localtime2gmt localtime2sec log log10 log1p logifit lstrip madd mapdiff
mapexcept mapselect mapsum max md5 mexp min mmul msub os pow qnorm reduce
regextract regextract_or_else rightpad round roundm rstrip sec2dhms sec2gmt
sec2gmtdate sec2hms sec2localdate sec2localtime select sgn sha1 sha256 sha512
sin sinh sort splita splitax splitkv splitkvx splitnv splitnvx sqrt ssub
strftime strftime_local string strip strlen strptime strptime_local sub substr
substr0 substr1 system systime systimeint tan tanh tolower toupper truncate
typeof unflatten unformat unformatx uptime urand urand32 urandelement urandint
urandrange utf8_to_latin1 version ! != !=~ % & && * ** + - . .* .+ .- ./ / //
< << <= <=> == =~ > >= >> >>> ?: ?? ??? ^ ^^ | || ~
gmt2localtime gmt2nsec gmt2sec gssub gsub haskey hexfmt hms2fsec hms2sec
hostname index int invqnorm is_absent is_array is_bool is_boolean is_empty
is_empty_map is_error is_float is_int is_map is_nan is_nonempty_map
is_not_array is_not_empty is_not_map is_not_null is_null is_numeric is_present
is_string joink joinkv joinv json_parse json_stringify latin1_to_utf8
leafcount leftpad length localtime2gmt localtime2nsec localtime2sec log log10
log1p logifit lstrip madd mapdiff mapexcept mapselect mapsum max md5 mexp min
mmul msub nsec2gmt nsec2gmtdate nsec2localdate nsec2localtime os pow qnorm
reduce regextract regextract_or_else rightpad round roundm rstrip sec2dhms
sec2gmt sec2gmtdate sec2hms sec2localdate sec2localtime select sgn sha1 sha256
sha512 sin sinh sort splita splitax splitkv splitkvx splitnv splitnvx sqrt
ssub strfntime strfntime_local strftime strftime_local string strip strlen
strpntime strpntime_local strptime strptime_local sub substr substr0 substr1
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
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.
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
OFS "," and OPS "=", and matching the resulting line against the regex specified
here. In particular, the regex is not applied to the input stream: if you have
CSV with header line "x,y,z" and data line "1,2,3" then the regex will be
matched, not against either of these lines, but against the DKVP line
"x=1,y=2,z=3". Furthermore, not all the options to system grep are supported,
and this command is intended to be merely a keystroke-saver. To get all the
features of system grep, you can do
command-line-specified ORS/OFS/OPS, and matching the resulting line against the
regex specified here. In particular, the regex is not applied to the input
stream: if you have CSV with header line "x,y,z" and data line "1,2,3" then the
regex will be matched, not against either of these lines, but against the DKVP
line "x=1,y=2,z=3". Furthermore, not all the options to system grep are
supported, and this command is intended to be merely a keystroke-saver. To get
all the features of system grep, you can do
"mlr --odkvp ... | grep ... | mlr --idkvp ..."
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", "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
(class=time #args=1) Parses GMT timestamp as integer seconds since the epoch.
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", "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
(class=time #args=1,2) Parses local timestamp as integer seconds since the epoch. Consults $TZ environment variable, unless second argument is supplied.
Examples:
@ -2551,6 +2564,32 @@ MILLER(1) MILLER(1)
1mmsub0m
(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
(class=system #args=0) Returns the operating-system name as a string.
@ -2704,6 +2743,21 @@ MILLER(1) MILLER(1)
Example:
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
(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:
@ -2726,16 +2780,32 @@ MILLER(1) MILLER(1)
1mstrlen0m
(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
(class=time #args=2) strptime: Parses timestamp as floating-point seconds since the epoch. See also strptime_local.
Examples:
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 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
(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:
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"
@ -2760,6 +2830,9 @@ MILLER(1) MILLER(1)
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.
1msysntime0m
(class=time #args=0) Returns the system time in 64-bit nanoseconds since the epoch.
1msystem0m
(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"].
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
(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:
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"
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.
Example:
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:
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"
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.
Examples:
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).
* [**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).
* [**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).
## Arithmetic functions
@ -1267,6 +1267,14 @@ gmt2localtime("1999-12-31T22:00:00Z", "Asia/Istanbul") = "2000-01-01 00:00:00"
</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
<pre class="pre-non-highlight-non-pair">
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>
### 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
<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.
@ -1305,6 +1322,44 @@ localtime2sec("2001-02-03 04:05:06", "Asia/Istanbul") = 981165906"
</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
<pre class="pre-non-highlight-non-pair">
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>
### 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
<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.
@ -1374,6 +1450,28 @@ strftime_local(1440768801.7, "%Y-%m-%d %H:%M:%3S %z", "Asia/Istanbul") = "2015-0
</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
<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.
@ -1381,13 +1479,13 @@ Examples:
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 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>
### strptime_local
<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:
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"
@ -1396,6 +1494,12 @@ strptime_local("2015-08-28 13:33:21", "%Y-%m-%d %H:%M:%S", "Asia/Istanbul")
</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
<pre class="pre-non-highlight-non-pair">
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>
### 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
<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.

View file

@ -1355,13 +1355,13 @@ Options:
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 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
here. In particular, the regex is not applied to the input stream: if you have
CSV with header line "x,y,z" and data line "1,2,3" then the regex will be
matched, not against either of these lines, but against the DKVP line
"x=1,y=2,z=3". Furthermore, not all the options to system grep are supported,
and this command is intended to be merely a keystroke-saver. To get all the
features of system grep, you can do
command-line-specified ORS/OFS/OPS, and matching the resulting line against the
regex specified here. In particular, the regex is not applied to the input
stream: if you have CSV with header line "x,y,z" and data line "1,2,3" then the
regex will be matched, not against either of these lines, but against the DKVP
line "x=1,y=2,z=3". Furthermore, not all the options to system grep are
supported, and this command is intended to be merely a keystroke-saver. To get
all the features of system grep, you can do
"mlr --odkvp ... | grep ... | mlr --idkvp ..."
</pre>

View file

@ -28,16 +28,27 @@ func BIF_systimeint() *mlrval.Mlrval {
return mlrval.FromInt(time.Now().Unix())
}
func BIF_sysntime() *mlrval.Mlrval {
return mlrval.FromInt(time.Now().UnixNano())
}
var startTime float64
var startNTime int64
func init() {
startTime = float64(time.Now().UnixNano()) / 1.0e9
startNTime = time.Now().UnixNano()
}
func BIF_uptime() *mlrval.Mlrval {
return mlrval.FromFloat(
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 {
return input1
}
numDecimalPlaces := 0
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 {
floatValue, isNumeric := input1.GetNumericToFloatValue()
if !isNumeric {
return input1
}
numDecimalPlaces, isInt := input2.GetIntValue()
if !isInt {
return mlrval.ERROR
}
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 {
floatValue, isNumeric := input1.GetNumericToFloatValue()
if !isNumeric {
return input1
}
numDecimalPlaces := 0
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 {
floatValue, isNumeric := input1.GetNumericToFloatValue()
if !isNumeric {
return input1
}
numDecimalPlaces, isInt := input2.GetIntValue()
if !isInt {
return mlrval.ERROR
}
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 {
floatValue, isNumeric := input1.GetNumericToFloatValue()
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.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 {
if !input1.IsNumeric() {
return input1
@ -122,6 +183,13 @@ func BIF_sec2gmtdate(input1 *mlrval.Mlrval) *mlrval.Mlrval {
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 {
if !input1.IsNumeric() {
return input1
@ -129,6 +197,13 @@ func BIF_sec2localdate_unary(input1 *mlrval.Mlrval) *mlrval.Mlrval {
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 {
if !input1.IsNumeric() {
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)
}
// ----------------------------------------------------------------
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 {
if !input1.IsString() {
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 {
if !input1.IsString() {
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 {
if !input1.IsString() {
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 {
if !input1.IsString() {
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)
}
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 {
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 {
locationString, isString := input3.GetStringValue()
if !isString {
@ -194,6 +283,18 @@ func BIF_strftime_local_ternary(input1, input2, input3 *mlrval.Mlrval) *mlrval.M
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 {
if input1.IsVoid() {
return input1
@ -236,6 +337,48 @@ func strftimeHelper(input1, input2 *mlrval.Mlrval, doLocal bool, location *time.
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.
@ -301,6 +444,14 @@ func init() {
// 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".
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() {
return mlrval.ERROR
}
@ -310,15 +461,53 @@ func BIF_strptime(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
timeString := input1.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 {
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 {
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() {
return mlrval.ERROR
}
@ -328,15 +517,43 @@ func BIF_strptime_local_binary(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
timeString := input1.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 {
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 {
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() {
return mlrval.ERROR
}
@ -356,26 +573,14 @@ func BIF_strptime_local_ternary(input1, input2, input3 *mlrval.Mlrval) *mlrval.M
return mlrval.ERROR
}
// TODO: use location
t, err := strptime.ParseLocation(timeString, formatString, location)
if err != nil {
return mlrval.ERROR
}
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)
if produceNanoseconds {
return mlrval.FromInt(t.UnixNano())
} else {
return mlrval.FromFloat(float64(t.UnixNano()) / 1.0e9)
}
}

View file

@ -971,6 +971,16 @@ is normally distributed.`,
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",
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", "Asia/Istanbul") = 981165906"`,
},
// TODO: help-string
unaryFunc: bifs.BIF_localtime2sec_unary,
binaryFunc: bifs.BIF_localtime2sec_binary,
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",
class: FUNC_CLASS_TIME,
@ -1001,6 +1024,21 @@ argument n, includes n decimal places for the seconds part.`,
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",
class: FUNC_CLASS_TIME,
@ -1019,6 +1057,24 @@ includes n decimal places for the seconds part`,
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",
class: FUNC_CLASS_TIME,
@ -1030,6 +1086,17 @@ Leaves non-numbers as-is.`,
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",
class: FUNC_CLASS_TIME,
@ -1044,6 +1111,20 @@ Leaves non-numbers as-is. Consults $TZ environment variable unless second argume
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",
class: FUNC_CLASS_TIME,
@ -1088,17 +1169,19 @@ See also strftime_local.`,
},
{
name: "strptime",
name: "strfntime",
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{
`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 EET", "%Y-%m-%d %H:%M:%S %Z") = -7200`,
`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"`,
},
binaryFunc: bifs.BIF_strptime,
binaryFunc: bifs.BIF_strfntime,
},
{
@ -1115,10 +1198,51 @@ See also strftime_local.`,
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",
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{
`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"`,
@ -1132,6 +1256,23 @@ See also strftime_local.`,
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",
class: FUNC_CLASS_TIME,
@ -1195,6 +1336,13 @@ See also strftime_local.`,
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",
class: FUNC_CLASS_TIME,
@ -1209,6 +1357,13 @@ See also strftime_local.`,
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

View file

@ -2,7 +2,6 @@ package lib
import (
"fmt"
"math"
"os"
"time"
)
@ -26,33 +25,67 @@ func SetTZFromEnv() error {
}
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 {
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 {
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
// use the specified location.
func sec2Time(epochSeconds float64, numDecimalPlaces int, doLocal bool, location *time.Location) string {
if numDecimalPlaces > 9 {
numDecimalPlaces = 9
}
func secToFormattedTime(epochSeconds float64, numDecimalPlaces int, doLocal bool, location *time.Location) string {
intPart := int64(epochSeconds)
fractionalPart := epochSeconds - float64(intPart)
if fractionalPart < 0 {
intPart -= 1
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 location != nil {
t = t.In(location)
@ -70,6 +103,12 @@ func sec2Time(epochSeconds float64, numDecimalPlaces int, doLocal bool, location
mm := t.Minute()
ss := t.Second()
if numDecimalPlaces < 0 {
numDecimalPlaces = 0
} else if numDecimalPlaces > 9 {
numDecimalPlaces = 9
}
if numDecimalPlaces == 0 {
if doLocal {
return fmt.Sprintf(
@ -81,14 +120,15 @@ func sec2Time(epochSeconds float64, numDecimalPlaces int, doLocal bool, location
YYYY, MM, DD, hh, mm, ss)
}
} else {
fractionalPart := t.Nanosecond() / nsToFracDivisors[numDecimalPlaces]
if doLocal {
return fmt.Sprintf(
"%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 {
return fmt.Sprintf(
"%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)
}
func EpochNanosecondsToGMT(epochNanoseconds int64) time.Time {
return epochNanosecondsToTime(epochNanoseconds, false, nil)
}
func EpochSecondsToLocalTime(epochSeconds float64) time.Time {
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 {
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 {
intPart := int64(epochSeconds)
fractionalPart := epochSeconds - float64(intPart)
@ -119,3 +171,17 @@ func epochSecondsToTime(epochSeconds float64, doLocal bool, location *time.Locat
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
depth dhms2fsec dhms2sec erf erfc every exec exp expm1 flatten float floor
fmtifnum fmtnum fold format fsec2dhms fsec2hms get_keys get_values
gmt2localtime gmt2sec gssub gsub haskey hexfmt hms2fsec hms2sec hostname index
int invqnorm is_absent is_array is_bool is_boolean is_empty is_empty_map
is_error is_float is_int is_map is_nan is_nonempty_map is_not_array
is_not_empty is_not_map is_not_null is_null is_numeric is_present is_string
joink joinkv joinv json_parse json_stringify latin1_to_utf8 leafcount leftpad
length localtime2gmt localtime2sec log log10 log1p logifit lstrip madd mapdiff
mapexcept mapselect mapsum max md5 mexp min mmul msub os pow qnorm reduce
regextract regextract_or_else rightpad round roundm rstrip sec2dhms sec2gmt
sec2gmtdate sec2hms sec2localdate sec2localtime select sgn sha1 sha256 sha512
sin sinh sort splita splitax splitkv splitkvx splitnv splitnvx sqrt ssub
strftime strftime_local string strip strlen strptime strptime_local sub substr
substr0 substr1 system systime systimeint tan tanh tolower toupper truncate
typeof unflatten unformat unformatx uptime urand urand32 urandelement urandint
urandrange utf8_to_latin1 version ! != !=~ % & && * ** + - . .* .+ .- ./ / //
< << <= <=> == =~ > >= >> >>> ?: ?? ??? ^ ^^ | || ~
gmt2localtime gmt2nsec gmt2sec gssub gsub haskey hexfmt hms2fsec hms2sec
hostname index int invqnorm is_absent is_array is_bool is_boolean is_empty
is_empty_map is_error is_float is_int is_map is_nan is_nonempty_map
is_not_array is_not_empty is_not_map is_not_null is_null is_numeric is_present
is_string joink joinkv joinv json_parse json_stringify latin1_to_utf8
leafcount leftpad length localtime2gmt localtime2nsec localtime2sec log log10
log1p logifit lstrip madd mapdiff mapexcept mapselect mapsum max md5 mexp min
mmul msub nsec2gmt nsec2gmtdate nsec2localdate nsec2localtime os pow qnorm
reduce regextract regextract_or_else rightpad round roundm rstrip sec2dhms
sec2gmt sec2gmtdate sec2hms sec2localdate sec2localtime select sgn sha1 sha256
sha512 sin sinh sort splita splitax splitkv splitkvx splitnv splitnvx sqrt
ssub strfntime strfntime_local strftime strftime_local string strip strlen
strpntime strpntime_local strptime strptime_local sub substr substr0 substr1
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
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.
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
OFS "," and OPS "=", and matching the resulting line against the regex specified
here. In particular, the regex is not applied to the input stream: if you have
CSV with header line "x,y,z" and data line "1,2,3" then the regex will be
matched, not against either of these lines, but against the DKVP line
"x=1,y=2,z=3". Furthermore, not all the options to system grep are supported,
and this command is intended to be merely a keystroke-saver. To get all the
features of system grep, you can do
command-line-specified ORS/OFS/OPS, and matching the resulting line against the
regex specified here. In particular, the regex is not applied to the input
stream: if you have CSV with header line "x,y,z" and data line "1,2,3" then the
regex will be matched, not against either of these lines, but against the DKVP
line "x=1,y=2,z=3". Furthermore, not all the options to system grep are
supported, and this command is intended to be merely a keystroke-saver. To get
all the features of system grep, you can do
"mlr --odkvp ... | grep ... | mlr --idkvp ..."
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", "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
(class=time #args=1) Parses GMT timestamp as integer seconds since the epoch.
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", "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
(class=time #args=1,2) Parses local timestamp as integer seconds since the epoch. Consults $TZ environment variable, unless second argument is supplied.
Examples:
@ -2551,6 +2564,32 @@ MILLER(1) MILLER(1)
1mmsub0m
(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
(class=system #args=0) Returns the operating-system name as a string.
@ -2704,6 +2743,21 @@ MILLER(1) MILLER(1)
Example:
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
(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:
@ -2726,16 +2780,32 @@ MILLER(1) MILLER(1)
1mstrlen0m
(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
(class=time #args=2) strptime: Parses timestamp as floating-point seconds since the epoch. See also strptime_local.
Examples:
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 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
(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:
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"
@ -2760,6 +2830,9 @@ MILLER(1) MILLER(1)
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.
1msysntime0m
(class=time #args=0) Returns the system time in 64-bit nanoseconds since the epoch.
1msystem0m
(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"].
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
(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
.\" Author: [see the "AUTHOR" section]
.\" Generator: ./mkman.rb
.\" Date: 2023-06-06
.\" Date: 2023-06-24
.\" Manual: \ \&
.\" Source: \ \&
.\" Language: English
.\"
.TH "MILLER" "1" "2023-06-06" "\ \&" "\ \&"
.TH "MILLER" "1" "2023-06-24" "\ \&" "\ \&"
.\" -----------------------------------------------------------------
.\" * 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
depth dhms2fsec dhms2sec erf erfc every exec exp expm1 flatten float floor
fmtifnum fmtnum fold format fsec2dhms fsec2hms get_keys get_values
gmt2localtime gmt2sec gssub gsub haskey hexfmt hms2fsec hms2sec hostname index
int invqnorm is_absent is_array is_bool is_boolean is_empty is_empty_map
is_error is_float is_int is_map is_nan is_nonempty_map is_not_array
is_not_empty is_not_map is_not_null is_null is_numeric is_present is_string
joink joinkv joinv json_parse json_stringify latin1_to_utf8 leafcount leftpad
length localtime2gmt localtime2sec log log10 log1p logifit lstrip madd mapdiff
mapexcept mapselect mapsum max md5 mexp min mmul msub os pow qnorm reduce
regextract regextract_or_else rightpad round roundm rstrip sec2dhms sec2gmt
sec2gmtdate sec2hms sec2localdate sec2localtime select sgn sha1 sha256 sha512
sin sinh sort splita splitax splitkv splitkvx splitnv splitnvx sqrt ssub
strftime strftime_local string strip strlen strptime strptime_local sub substr
substr0 substr1 system systime systimeint tan tanh tolower toupper truncate
typeof unflatten unformat unformatx uptime urand urand32 urandelement urandint
urandrange utf8_to_latin1 version ! != !=~ % & && * ** + - . .* .+ .- ./ / //
< << <= <=> == =~ > >= >> >>> ?: ?? ??? ^ ^^ | || ~
gmt2localtime gmt2nsec gmt2sec gssub gsub haskey hexfmt hms2fsec hms2sec
hostname index int invqnorm is_absent is_array is_bool is_boolean is_empty
is_empty_map is_error is_float is_int is_map is_nan is_nonempty_map
is_not_array is_not_empty is_not_map is_not_null is_null is_numeric is_present
is_string joink joinkv joinv json_parse json_stringify latin1_to_utf8
leafcount leftpad length localtime2gmt localtime2nsec localtime2sec log log10
log1p logifit lstrip madd mapdiff mapexcept mapselect mapsum max md5 mexp min
mmul msub nsec2gmt nsec2gmtdate nsec2localdate nsec2localtime os pow qnorm
reduce regextract regextract_or_else rightpad round roundm rstrip sec2dhms
sec2gmt sec2gmtdate sec2hms sec2localdate sec2localtime select sgn sha1 sha256
sha512 sin sinh sort splita splitax splitkv splitkvx splitnv splitnvx sqrt
ssub strfntime strfntime_local strftime strftime_local string strip strlen
strpntime strpntime_local strptime strptime_local sub substr substr0 substr1
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
.if n \{\
.RE
@ -1480,13 +1482,13 @@ Options:
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 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
here. In particular, the regex is not applied to the input stream: if you have
CSV with header line "x,y,z" and data line "1,2,3" then the regex will be
matched, not against either of these lines, but against the DKVP line
"x=1,y=2,z=3". Furthermore, not all the options to system grep are supported,
and this command is intended to be merely a keystroke-saver. To get all the
features of system grep, you can do
command-line-specified ORS/OFS/OPS, and matching the resulting line against the
regex specified here. In particular, the regex is not applied to the input
stream: if you have CSV with header line "x,y,z" and data line "1,2,3" then the
regex will be matched, not against either of these lines, but against the DKVP
line "x=1,y=2,z=3". Furthermore, not all the options to system grep are
supported, and this command is intended to be merely a keystroke-saver. To get
all the features of system grep, you can do
"mlr --odkvp ... | grep ... | mlr --idkvp ..."
.fi
.if n \{\
@ -3269,6 +3271,17 @@ gmt2localtime("1999-12-31T22:00:00Z", "Asia/Istanbul") = "2000-01-01 00:00:00"
.fi
.if n \{\
.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"
.if n \{\
.RS 0
@ -3680,6 +3693,18 @@ localtime2gmt("2000-01-01 00:00:00", "Asia/Istanbul") = "1999-12-31T22:00:00Z"
.fi
.if n \{\
.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"
.if n \{\
.RS 0
@ -3836,6 +3861,56 @@ localtime2sec("2001-02-03 04:05:06", "Asia/Istanbul") = 981165906"
.fi
.if n \{\
.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"
.if n \{\
.RS 0
@ -4181,6 +4256,33 @@ ssub("abc.def", ".", "X") gives "abcXdef"
.fi
.if n \{\
.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"
.if n \{\
.RS 0
@ -4233,6 +4335,34 @@ strftime_local(1440768801.7, "%Y-%m-%d %H:%M:%3S %z", "Asia/Istanbul") = "2015-0
.fi
.if n \{\
.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"
.if n \{\
.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: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 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
.if n \{\
.RE
@ -4252,7 +4382,7 @@ strptime("1970-01-01 00:00:00 EET", "%Y-%m-%d %H:%M:%S %Z") = -7200
.RS 0
.\}
.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:
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"
@ -4303,6 +4433,15 @@ sub("prefix4529:suffix8567", "suffix([0-9]+)", "name\e1") gives "prefix4529:name
.fi
.if n \{\
.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"
.if n \{\
.RS 0
@ -4421,6 +4560,15 @@ is_error(unformatx("{}h{}m{}s", "3:47:22")) gives true.
.fi
.if n \{\
.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"
.if n \{\
.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