diff --git a/docs/src/manpage.md b/docs/src/manpage.md index 3b15b2493..2f884002f 100644 --- a/docs/src/manpage.md +++ b/docs/src/manpage.md @@ -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) diff --git a/docs/src/manpage.txt b/docs/src/manpage.txt index 8db971e79..abb828010 100644 --- a/docs/src/manpage.txt +++ b/docs/src/manpage.txt @@ -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) diff --git a/docs/src/online-help.md b/docs/src/online-help.md index fc6cda292..8318c4f0a 100644 --- a/docs/src/online-help.md +++ b/docs/src/online-help.md @@ -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" diff --git a/docs/src/reference-dsl-builtin-functions.md b/docs/src/reference-dsl-builtin-functions.md index ae8f5d517..7bdb1d5bf 100644 --- a/docs/src/reference-dsl-builtin-functions.md +++ b/docs/src/reference-dsl-builtin-functions.md @@ -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" +### gmt2nsec +
+gmt2nsec  (class=time #args=1) Parses GMT timestamp as integer nanoseconds since the epoch.
+Example:
+gmt2nsec("2001-02-03T04:05:06Z") = 981173106000000000
+
+ + ### gmt2sec
 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"
 
+### localtime2nsec +
+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"
+
+ + ### localtime2sec
 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"
 
+### nsec2gmt +
+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 +
+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".
+
+ + +### nsec2localdate +
+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"
+
+ + +### nsec2localtime +
+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"
+
+ + ### sec2dhms
 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
 
+### strfntime +
+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"
+
+ + +### strfntime_local +
+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"
+
+ + ### strftime
 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
 
+### strpntime +
+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
+
+ + +### strpntime_local +
+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
+
+ + ### strptime
 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
 
### strptime_local
-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")
 
+### sysntime +
+sysntime  (class=time #args=0) Returns the system time in 64-bit nanoseconds since the epoch.
+
+ + ### systime
 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
 
+### upntime +
+upntime  (class=time #args=0) Returns the time in 64-bit nanoseconds since the current Miller program was started.
+
+ + ### uptime
 uptime  (class=time #args=0) Returns the time in floating-point seconds since the current Miller program was started.
diff --git a/docs/src/reference-verbs.md b/docs/src/reference-verbs.md
index 27463e333..be11f8903 100644
--- a/docs/src/reference-verbs.md
+++ b/docs/src/reference-verbs.md
@@ -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 ..."
 
diff --git a/internal/pkg/bifs/datetime.go b/internal/pkg/bifs/datetime.go index d389556ee..47e908b16 100644 --- a/internal/pkg/bifs/datetime.go +++ b/internal/pkg/bifs/datetime.go @@ -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) + } } diff --git a/internal/pkg/dsl/cst/builtin_function_manager.go b/internal/pkg/dsl/cst/builtin_function_manager.go index 6f616baa4..876fcdb29 100644 --- a/internal/pkg/dsl/cst/builtin_function_manager.go +++ b/internal/pkg/dsl/cst/builtin_function_manager.go @@ -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 diff --git a/internal/pkg/lib/time.go b/internal/pkg/lib/time.go index 94c31c327..4fa6818c5 100644 --- a/internal/pkg/lib/time.go +++ b/internal/pkg/lib/time.go @@ -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() + } +} diff --git a/internal/pkg/lib/time_test.go b/internal/pkg/lib/time_test.go new file mode 100644 index 000000000..f2f2c6690 --- /dev/null +++ b/internal/pkg/lib/time_test.go @@ -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)) + } +} diff --git a/man/manpage.txt b/man/manpage.txt index 8db971e79..abb828010 100644 --- a/man/manpage.txt +++ b/man/manpage.txt @@ -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) diff --git a/man/mlr.1 b/man/mlr.1 index 0fa01052d..63f502b2a 100644 --- a/man/mlr.1 +++ b/man/mlr.1 @@ -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 diff --git a/test/cases/dsl-gmt-date-time-functions/0005n/cmd b/test/cases/dsl-gmt-date-time-functions/0005n/cmd new file mode 100644 index 000000000..6d58b7d24 --- /dev/null +++ b/test/cases/dsl-gmt-date-time-functions/0005n/cmd @@ -0,0 +1 @@ +mlr --csvlite put -f ${CASEDIR}/mlr test/input/gmt2nsec diff --git a/test/cases/dsl-gmt-date-time-functions/0005n/experr b/test/cases/dsl-gmt-date-time-functions/0005n/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/dsl-gmt-date-time-functions/0005n/expout b/test/cases/dsl-gmt-date-time-functions/0005n/expout new file mode 100644 index 000000000..c523dc29e --- /dev/null +++ b/test/cases/dsl-gmt-date-time-functions/0005n/expout @@ -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 diff --git a/test/cases/dsl-gmt-date-time-functions/0005n/mlr b/test/cases/dsl-gmt-date-time-functions/0005n/mlr new file mode 100644 index 000000000..797ae3bd1 --- /dev/null +++ b/test/cases/dsl-gmt-date-time-functions/0005n/mlr @@ -0,0 +1 @@ +$sec = gmt2nsec($gmt) diff --git a/test/cases/dsl-gmt-date-time-functions/0011n/cmd b/test/cases/dsl-gmt-date-time-functions/0011n/cmd new file mode 100644 index 000000000..f8d98687e --- /dev/null +++ b/test/cases/dsl-gmt-date-time-functions/0011n/cmd @@ -0,0 +1 @@ +mlr --icsv --opprint put -f ${CASEDIR}/mlr test/input/gmt2nsec diff --git a/test/cases/dsl-gmt-date-time-functions/0011n/experr b/test/cases/dsl-gmt-date-time-functions/0011n/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/dsl-gmt-date-time-functions/0011n/expout b/test/cases/dsl-gmt-date-time-functions/0011n/expout new file mode 100644 index 000000000..6318a0f2f --- /dev/null +++ b/test/cases/dsl-gmt-date-time-functions/0011n/expout @@ -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 diff --git a/test/cases/dsl-gmt-date-time-functions/0011n/mlr b/test/cases/dsl-gmt-date-time-functions/0011n/mlr new file mode 100644 index 000000000..c35ad3dd3 --- /dev/null +++ b/test/cases/dsl-gmt-date-time-functions/0011n/mlr @@ -0,0 +1 @@ +$sec = strpntime($gmt, "%Y-%m-%dT%H:%M:%SZ") diff --git a/test/cases/dsl-gmt-date-time-functions/0019n/0019/cmd b/test/cases/dsl-gmt-date-time-functions/0019n/0019/cmd new file mode 100644 index 000000000..a5997d665 --- /dev/null +++ b/test/cases/dsl-gmt-date-time-functions/0019n/0019/cmd @@ -0,0 +1 @@ +mlr --icsv --opprint put -f ${CASEDIR}/mlr test/input/gmt2sec diff --git a/test/cases/dsl-gmt-date-time-functions/0019n/0019/experr b/test/cases/dsl-gmt-date-time-functions/0019n/0019/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/dsl-gmt-date-time-functions/0019n/0019/expout b/test/cases/dsl-gmt-date-time-functions/0019n/0019/expout new file mode 100644 index 000000000..2f4f196c0 --- /dev/null +++ b/test/cases/dsl-gmt-date-time-functions/0019n/0019/expout @@ -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 diff --git a/test/cases/dsl-gmt-date-time-functions/0019n/0019/mlr b/test/cases/dsl-gmt-date-time-functions/0019n/0019/mlr new file mode 100644 index 000000000..6391a7e85 --- /dev/null +++ b/test/cases/dsl-gmt-date-time-functions/0019n/0019/mlr @@ -0,0 +1 @@ +$sec = strptime($gmt, "%FT%TZ") diff --git a/test/cases/dsl-gmt-date-time-functions/0019n/cmd b/test/cases/dsl-gmt-date-time-functions/0019n/cmd new file mode 100644 index 000000000..f8d98687e --- /dev/null +++ b/test/cases/dsl-gmt-date-time-functions/0019n/cmd @@ -0,0 +1 @@ +mlr --icsv --opprint put -f ${CASEDIR}/mlr test/input/gmt2nsec diff --git a/test/cases/dsl-gmt-date-time-functions/0019n/experr b/test/cases/dsl-gmt-date-time-functions/0019n/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/dsl-gmt-date-time-functions/0019n/expout b/test/cases/dsl-gmt-date-time-functions/0019n/expout new file mode 100644 index 000000000..6318a0f2f --- /dev/null +++ b/test/cases/dsl-gmt-date-time-functions/0019n/expout @@ -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 diff --git a/test/cases/dsl-gmt-date-time-functions/0019n/mlr b/test/cases/dsl-gmt-date-time-functions/0019n/mlr new file mode 100644 index 000000000..26e34300a --- /dev/null +++ b/test/cases/dsl-gmt-date-time-functions/0019n/mlr @@ -0,0 +1 @@ +$sec = strpntime($gmt, "%FT%TZ") diff --git a/test/cases/dsl-gmt-date-time-functions/0020n/cmd b/test/cases/dsl-gmt-date-time-functions/0020n/cmd new file mode 100644 index 000000000..6add080d4 --- /dev/null +++ b/test/cases/dsl-gmt-date-time-functions/0020n/cmd @@ -0,0 +1 @@ +mlr -n put -f ${CASEDIR}/mlr diff --git a/test/cases/dsl-gmt-date-time-functions/0020n/experr b/test/cases/dsl-gmt-date-time-functions/0020n/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/dsl-gmt-date-time-functions/0020n/expout b/test/cases/dsl-gmt-date-time-functions/0020n/expout new file mode 100644 index 000000000..ce9d672ee --- /dev/null +++ b/test/cases/dsl-gmt-date-time-functions/0020n/expout @@ -0,0 +1,10 @@ +0 +0 +14400000000000 +0 +0 +31276800000000000 +80430000000000 +138000000000000 +(error) +31536000123456000.00000000 diff --git a/test/cases/dsl-gmt-date-time-functions/0020n/mlr b/test/cases/dsl-gmt-date-time-functions/0020n/mlr new file mode 100644 index 000000000..a59a0f29f --- /dev/null +++ b/test/cases/dsl-gmt-date-time-functions/0020n/mlr @@ -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"); +} diff --git a/test/cases/dsl-local-date-time-functions/0003n/cmd b/test/cases/dsl-local-date-time-functions/0003n/cmd new file mode 100644 index 000000000..11d677b75 --- /dev/null +++ b/test/cases/dsl-local-date-time-functions/0003n/cmd @@ -0,0 +1 @@ +mlr --opprint --from ${CASEDIR}/input put -f ${CASEDIR}/mlr diff --git a/test/cases/dsl-local-date-time-functions/0003n/env b/test/cases/dsl-local-date-time-functions/0003n/env new file mode 100644 index 000000000..416a800e9 --- /dev/null +++ b/test/cases/dsl-local-date-time-functions/0003n/env @@ -0,0 +1 @@ +TZ=America/Sao_Paulo diff --git a/test/cases/dsl-local-date-time-functions/0003n/experr b/test/cases/dsl-local-date-time-functions/0003n/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/dsl-local-date-time-functions/0003n/expout b/test/cases/dsl-local-date-time-functions/0003n/expout new file mode 100644 index 000000000..9c75c2640 --- /dev/null +++ b/test/cases/dsl-local-date-time-functions/0003n/expout @@ -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 diff --git a/test/cases/dsl-local-date-time-functions/0003n/input b/test/cases/dsl-local-date-time-functions/0003n/input new file mode 100644 index 000000000..da8ccab3e --- /dev/null +++ b/test/cases/dsl-local-date-time-functions/0003n/input @@ -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 diff --git a/test/cases/dsl-local-date-time-functions/0003n/mlr b/test/cases/dsl-local-date-time-functions/0003n/mlr new file mode 100644 index 000000000..182e8b915 --- /dev/null +++ b/test/cases/dsl-local-date-time-functions/0003n/mlr @@ -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"]; diff --git a/test/cases/dsl-local-date-time-functions/0004n/cmd b/test/cases/dsl-local-date-time-functions/0004n/cmd new file mode 100644 index 000000000..11d677b75 --- /dev/null +++ b/test/cases/dsl-local-date-time-functions/0004n/cmd @@ -0,0 +1 @@ +mlr --opprint --from ${CASEDIR}/input put -f ${CASEDIR}/mlr diff --git a/test/cases/dsl-local-date-time-functions/0004n/env b/test/cases/dsl-local-date-time-functions/0004n/env new file mode 100644 index 000000000..416a800e9 --- /dev/null +++ b/test/cases/dsl-local-date-time-functions/0004n/env @@ -0,0 +1 @@ +TZ=America/Sao_Paulo diff --git a/test/cases/dsl-local-date-time-functions/0004n/experr b/test/cases/dsl-local-date-time-functions/0004n/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/dsl-local-date-time-functions/0004n/expout b/test/cases/dsl-local-date-time-functions/0004n/expout new file mode 100644 index 000000000..9c75c2640 --- /dev/null +++ b/test/cases/dsl-local-date-time-functions/0004n/expout @@ -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 diff --git a/test/cases/dsl-local-date-time-functions/0004n/input b/test/cases/dsl-local-date-time-functions/0004n/input new file mode 100644 index 000000000..da8ccab3e --- /dev/null +++ b/test/cases/dsl-local-date-time-functions/0004n/input @@ -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 diff --git a/test/cases/dsl-local-date-time-functions/0004n/mlr b/test/cases/dsl-local-date-time-functions/0004n/mlr new file mode 100644 index 000000000..182e8b915 --- /dev/null +++ b/test/cases/dsl-local-date-time-functions/0004n/mlr @@ -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"]; diff --git a/test/cases/dsl-local-date-time-functions/local-with-tzs-nsec/cmd b/test/cases/dsl-local-date-time-functions/local-with-tzs-nsec/cmd new file mode 100644 index 000000000..6add080d4 --- /dev/null +++ b/test/cases/dsl-local-date-time-functions/local-with-tzs-nsec/cmd @@ -0,0 +1 @@ +mlr -n put -f ${CASEDIR}/mlr diff --git a/test/cases/dsl-local-date-time-functions/local-with-tzs-nsec/experr b/test/cases/dsl-local-date-time-functions/local-with-tzs-nsec/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/dsl-local-date-time-functions/local-with-tzs-nsec/expout b/test/cases/dsl-local-date-time-functions/local-with-tzs-nsec/expout new file mode 100644 index 000000000..5825285ff --- /dev/null +++ b/test/cases/dsl-local-date-time-functions/local-with-tzs-nsec/expout @@ -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 diff --git a/test/cases/dsl-local-date-time-functions/local-with-tzs-nsec/mlr b/test/cases/dsl-local-date-time-functions/local-with-tzs-nsec/mlr new file mode 100644 index 000000000..67a5bdde3 --- /dev/null +++ b/test/cases/dsl-local-date-time-functions/local-with-tzs-nsec/mlr @@ -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)); +} diff --git a/test/cases/dsl-local-date-time-functions/strfntime-istanbul/cmd b/test/cases/dsl-local-date-time-functions/strfntime-istanbul/cmd new file mode 100644 index 000000000..65600b063 --- /dev/null +++ b/test/cases/dsl-local-date-time-functions/strfntime-istanbul/cmd @@ -0,0 +1 @@ +mlr --tz Asia/Istanbul -n put -f test/input/strfntime-tz.mlr diff --git a/test/cases/dsl-local-date-time-functions/strfntime-istanbul/experr b/test/cases/dsl-local-date-time-functions/strfntime-istanbul/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/dsl-local-date-time-functions/strfntime-istanbul/expout b/test/cases/dsl-local-date-time-functions/strfntime-istanbul/expout new file mode 100644 index 000000000..057ff69bd --- /dev/null +++ b/test/cases/dsl-local-date-time-functions/strfntime-istanbul/expout @@ -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 diff --git a/test/cases/dsl-local-date-time-functions/strfntime-sao_paulo/cmd b/test/cases/dsl-local-date-time-functions/strfntime-sao_paulo/cmd new file mode 100644 index 000000000..d7c102c1d --- /dev/null +++ b/test/cases/dsl-local-date-time-functions/strfntime-sao_paulo/cmd @@ -0,0 +1 @@ +mlr --tz America/Sao_Paulo -n put -f test/input/strfntime-tz.mlr diff --git a/test/cases/dsl-local-date-time-functions/strfntime-sao_paulo/experr b/test/cases/dsl-local-date-time-functions/strfntime-sao_paulo/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/dsl-local-date-time-functions/strfntime-sao_paulo/expout b/test/cases/dsl-local-date-time-functions/strfntime-sao_paulo/expout new file mode 100644 index 000000000..36a591e67 --- /dev/null +++ b/test/cases/dsl-local-date-time-functions/strfntime-sao_paulo/expout @@ -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 diff --git a/test/cases/dsl-local-date-time-functions/strfntime-utc/cmd b/test/cases/dsl-local-date-time-functions/strfntime-utc/cmd new file mode 100644 index 000000000..8518d6688 --- /dev/null +++ b/test/cases/dsl-local-date-time-functions/strfntime-utc/cmd @@ -0,0 +1 @@ +mlr --tz UTC -n put -f test/input/strfntime-tz.mlr diff --git a/test/cases/dsl-local-date-time-functions/strfntime-utc/experr b/test/cases/dsl-local-date-time-functions/strfntime-utc/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/dsl-local-date-time-functions/strfntime-utc/expout b/test/cases/dsl-local-date-time-functions/strfntime-utc/expout new file mode 100644 index 000000000..62b9c1fe6 --- /dev/null +++ b/test/cases/dsl-local-date-time-functions/strfntime-utc/expout @@ -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 diff --git a/test/cases/dsl-local-date-time-functions/strfntime_local-istanbul/cmd b/test/cases/dsl-local-date-time-functions/strfntime_local-istanbul/cmd new file mode 100644 index 000000000..565748aea --- /dev/null +++ b/test/cases/dsl-local-date-time-functions/strfntime_local-istanbul/cmd @@ -0,0 +1 @@ +mlr --tz Asia/Istanbul -n put -f test/input/strfntime_local-tz.mlr diff --git a/test/cases/dsl-local-date-time-functions/strfntime_local-istanbul/experr b/test/cases/dsl-local-date-time-functions/strfntime_local-istanbul/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/dsl-local-date-time-functions/strfntime_local-istanbul/expout b/test/cases/dsl-local-date-time-functions/strfntime_local-istanbul/expout new file mode 100644 index 000000000..a8147319e --- /dev/null +++ b/test/cases/dsl-local-date-time-functions/strfntime_local-istanbul/expout @@ -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 diff --git a/test/cases/dsl-local-date-time-functions/strfntime_local-sao_paulo/cmd b/test/cases/dsl-local-date-time-functions/strfntime_local-sao_paulo/cmd new file mode 100644 index 000000000..73b3d5155 --- /dev/null +++ b/test/cases/dsl-local-date-time-functions/strfntime_local-sao_paulo/cmd @@ -0,0 +1 @@ +mlr --tz America/Sao_Paulo -n put -f test/input/strfntime_local-tz.mlr diff --git a/test/cases/dsl-local-date-time-functions/strfntime_local-sao_paulo/experr b/test/cases/dsl-local-date-time-functions/strfntime_local-sao_paulo/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/dsl-local-date-time-functions/strfntime_local-sao_paulo/expout b/test/cases/dsl-local-date-time-functions/strfntime_local-sao_paulo/expout new file mode 100644 index 000000000..6df103333 --- /dev/null +++ b/test/cases/dsl-local-date-time-functions/strfntime_local-sao_paulo/expout @@ -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 diff --git a/test/cases/dsl-local-date-time-functions/strfntime_local-utc/cmd b/test/cases/dsl-local-date-time-functions/strfntime_local-utc/cmd new file mode 100644 index 000000000..ec9ec60a8 --- /dev/null +++ b/test/cases/dsl-local-date-time-functions/strfntime_local-utc/cmd @@ -0,0 +1 @@ +mlr --tz UTC -n put -f test/input/strfntime_local-tz.mlr diff --git a/test/cases/dsl-local-date-time-functions/strfntime_local-utc/experr b/test/cases/dsl-local-date-time-functions/strfntime_local-utc/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/dsl-local-date-time-functions/strfntime_local-utc/expout b/test/cases/dsl-local-date-time-functions/strfntime_local-utc/expout new file mode 100644 index 000000000..675ea2587 --- /dev/null +++ b/test/cases/dsl-local-date-time-functions/strfntime_local-utc/expout @@ -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 diff --git a/test/cases/dsl-local-date-time-functions/strpntime-istanbul/cmd b/test/cases/dsl-local-date-time-functions/strpntime-istanbul/cmd new file mode 100644 index 000000000..fc3ffbdd2 --- /dev/null +++ b/test/cases/dsl-local-date-time-functions/strpntime-istanbul/cmd @@ -0,0 +1 @@ +mlr --tz Asia/Istanbul -n put -f test/input/strpntime-tz.mlr diff --git a/test/cases/dsl-local-date-time-functions/strpntime-istanbul/experr b/test/cases/dsl-local-date-time-functions/strpntime-istanbul/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/dsl-local-date-time-functions/strpntime-istanbul/expout b/test/cases/dsl-local-date-time-functions/strpntime-istanbul/expout new file mode 100644 index 000000000..5291615b8 --- /dev/null +++ b/test/cases/dsl-local-date-time-functions/strpntime-istanbul/expout @@ -0,0 +1,9 @@ +---------------------------------------------------------------- TIMEZONE +TZ is Asia/Istanbul +---------------------------------------------------------------- STRPNTIME +0 +345000000 +345000000 +345000000 +14400345000000 +-14399655000000 diff --git a/test/cases/dsl-local-date-time-functions/strpntime-j/cmd b/test/cases/dsl-local-date-time-functions/strpntime-j/cmd new file mode 100644 index 000000000..e281b3385 --- /dev/null +++ b/test/cases/dsl-local-date-time-functions/strpntime-j/cmd @@ -0,0 +1 @@ +mlr --tz UTC -n put -f ${CASEDIR}/mlr diff --git a/test/cases/dsl-local-date-time-functions/strpntime-j/experr b/test/cases/dsl-local-date-time-functions/strpntime-j/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/dsl-local-date-time-functions/strpntime-j/expout b/test/cases/dsl-local-date-time-functions/strpntime-j/expout new file mode 100644 index 000000000..7d7dd945c --- /dev/null +++ b/test/cases/dsl-local-date-time-functions/strpntime-j/expout @@ -0,0 +1,2 @@ +2021-01-01 +2021-12-29 diff --git a/test/cases/dsl-local-date-time-functions/strpntime-j/mlr b/test/cases/dsl-local-date-time-functions/strpntime-j/mlr new file mode 100644 index 000000000..3551856d9 --- /dev/null +++ b/test/cases/dsl-local-date-time-functions/strpntime-j/mlr @@ -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"); +} diff --git a/test/cases/dsl-local-date-time-functions/strpntime-sao_paulo/cmd b/test/cases/dsl-local-date-time-functions/strpntime-sao_paulo/cmd new file mode 100644 index 000000000..d6e2caf95 --- /dev/null +++ b/test/cases/dsl-local-date-time-functions/strpntime-sao_paulo/cmd @@ -0,0 +1 @@ +mlr --tz America/Sao_Paulo -n put -f test/input/strpntime-tz.mlr diff --git a/test/cases/dsl-local-date-time-functions/strpntime-sao_paulo/experr b/test/cases/dsl-local-date-time-functions/strpntime-sao_paulo/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/dsl-local-date-time-functions/strpntime-sao_paulo/expout b/test/cases/dsl-local-date-time-functions/strpntime-sao_paulo/expout new file mode 100644 index 000000000..80fd08f7b --- /dev/null +++ b/test/cases/dsl-local-date-time-functions/strpntime-sao_paulo/expout @@ -0,0 +1,9 @@ +---------------------------------------------------------------- TIMEZONE +TZ is America/Sao_Paulo +---------------------------------------------------------------- STRPNTIME +0 +345000000 +345000000 +345000000 +14400345000000 +-14399655000000 diff --git a/test/cases/dsl-local-date-time-functions/strpntime-utc/cmd b/test/cases/dsl-local-date-time-functions/strpntime-utc/cmd new file mode 100644 index 000000000..28e7f9deb --- /dev/null +++ b/test/cases/dsl-local-date-time-functions/strpntime-utc/cmd @@ -0,0 +1 @@ +mlr --tz UTC -n put -f test/input/strpntime-tz.mlr diff --git a/test/cases/dsl-local-date-time-functions/strpntime-utc/experr b/test/cases/dsl-local-date-time-functions/strpntime-utc/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/dsl-local-date-time-functions/strpntime-utc/expout b/test/cases/dsl-local-date-time-functions/strpntime-utc/expout new file mode 100644 index 000000000..c83b55187 --- /dev/null +++ b/test/cases/dsl-local-date-time-functions/strpntime-utc/expout @@ -0,0 +1,9 @@ +---------------------------------------------------------------- TIMEZONE +TZ is UTC +---------------------------------------------------------------- STRPNTIME +0 +345000000 +345000000 +345000000 +14400345000000 +-14399655000000 diff --git a/test/cases/dsl-local-date-time-functions/strpntime-z/cmd b/test/cases/dsl-local-date-time-functions/strpntime-z/cmd new file mode 100644 index 000000000..6add080d4 --- /dev/null +++ b/test/cases/dsl-local-date-time-functions/strpntime-z/cmd @@ -0,0 +1 @@ +mlr -n put -f ${CASEDIR}/mlr diff --git a/test/cases/dsl-local-date-time-functions/strpntime-z/experr b/test/cases/dsl-local-date-time-functions/strpntime-z/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/dsl-local-date-time-functions/strpntime-z/expout b/test/cases/dsl-local-date-time-functions/strpntime-z/expout new file mode 100644 index 000000000..29d23fe0d --- /dev/null +++ b/test/cases/dsl-local-date-time-functions/strpntime-z/expout @@ -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 diff --git a/test/cases/dsl-local-date-time-functions/strpntime-z/mlr b/test/cases/dsl-local-date-time-functions/strpntime-z/mlr new file mode 100644 index 000000000..d14ed4c39 --- /dev/null +++ b/test/cases/dsl-local-date-time-functions/strpntime-z/mlr @@ -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; + } +} diff --git a/test/cases/dsl-local-date-time-functions/strpntime_local-istanbul/cmd b/test/cases/dsl-local-date-time-functions/strpntime_local-istanbul/cmd new file mode 100644 index 000000000..972b0d54a --- /dev/null +++ b/test/cases/dsl-local-date-time-functions/strpntime_local-istanbul/cmd @@ -0,0 +1 @@ +mlr --tz Asia/Istanbul -n put -f test/input/strpntime_local-tz.mlr diff --git a/test/cases/dsl-local-date-time-functions/strpntime_local-istanbul/experr b/test/cases/dsl-local-date-time-functions/strpntime_local-istanbul/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/dsl-local-date-time-functions/strpntime_local-istanbul/expout b/test/cases/dsl-local-date-time-functions/strpntime_local-istanbul/expout new file mode 100644 index 000000000..2e34ce4ae --- /dev/null +++ b/test/cases/dsl-local-date-time-functions/strpntime_local-istanbul/expout @@ -0,0 +1,4 @@ +---------------------------------------------------------------- TIMEZONE +TZ is Asia/Istanbul +---------------------------------------------------------------- STRPNTIME_LOCAL +-7200000000000 diff --git a/test/cases/dsl-local-date-time-functions/strpntime_local-sao_paulo/cmd b/test/cases/dsl-local-date-time-functions/strpntime_local-sao_paulo/cmd new file mode 100644 index 000000000..25733cc0d --- /dev/null +++ b/test/cases/dsl-local-date-time-functions/strpntime_local-sao_paulo/cmd @@ -0,0 +1 @@ +mlr --tz America/Sao_Paulo -n put -f test/input/strpntime_local-tz.mlr diff --git a/test/cases/dsl-local-date-time-functions/strpntime_local-sao_paulo/experr b/test/cases/dsl-local-date-time-functions/strpntime_local-sao_paulo/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/dsl-local-date-time-functions/strpntime_local-sao_paulo/expout b/test/cases/dsl-local-date-time-functions/strpntime_local-sao_paulo/expout new file mode 100644 index 000000000..53115b27f --- /dev/null +++ b/test/cases/dsl-local-date-time-functions/strpntime_local-sao_paulo/expout @@ -0,0 +1,4 @@ +---------------------------------------------------------------- TIMEZONE +TZ is America/Sao_Paulo +---------------------------------------------------------------- STRPNTIME_LOCAL +10800000000000 diff --git a/test/cases/dsl-local-date-time-functions/strpntime_local-utc/cmd b/test/cases/dsl-local-date-time-functions/strpntime_local-utc/cmd new file mode 100644 index 000000000..bbd8e93e8 --- /dev/null +++ b/test/cases/dsl-local-date-time-functions/strpntime_local-utc/cmd @@ -0,0 +1 @@ +mlr --tz UTC -n put -f test/input/strpntime_local-tz.mlr diff --git a/test/cases/dsl-local-date-time-functions/strpntime_local-utc/experr b/test/cases/dsl-local-date-time-functions/strpntime_local-utc/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/dsl-local-date-time-functions/strpntime_local-utc/expout b/test/cases/dsl-local-date-time-functions/strpntime_local-utc/expout new file mode 100644 index 000000000..2db059d0b --- /dev/null +++ b/test/cases/dsl-local-date-time-functions/strpntime_local-utc/expout @@ -0,0 +1,4 @@ +---------------------------------------------------------------- TIMEZONE +TZ is UTC +---------------------------------------------------------------- STRPNTIME_LOCAL +0 diff --git a/test/cases/dsl-sec2gmt/0001n/cmd b/test/cases/dsl-sec2gmt/0001n/cmd new file mode 100644 index 000000000..566159173 --- /dev/null +++ b/test/cases/dsl-sec2gmt/0001n/cmd @@ -0,0 +1 @@ +mlr --from test/input/ten.dkvp --opprint put '$z=nsec2gmt($i)' diff --git a/test/cases/dsl-sec2gmt/0001n/experr b/test/cases/dsl-sec2gmt/0001n/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/dsl-sec2gmt/0001n/expout b/test/cases/dsl-sec2gmt/0001n/expout new file mode 100644 index 000000000..148459888 --- /dev/null +++ b/test/cases/dsl-sec2gmt/0001n/expout @@ -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 diff --git a/test/cases/dsl-sec2gmt/0002n/cmd b/test/cases/dsl-sec2gmt/0002n/cmd new file mode 100644 index 000000000..c2c143a72 --- /dev/null +++ b/test/cases/dsl-sec2gmt/0002n/cmd @@ -0,0 +1 @@ +mlr --from test/input/ten.dkvp --opprint put '$z=nsec2gmt($i, $i-1)' diff --git a/test/cases/dsl-sec2gmt/0002n/experr b/test/cases/dsl-sec2gmt/0002n/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/dsl-sec2gmt/0002n/expout b/test/cases/dsl-sec2gmt/0002n/expout new file mode 100644 index 000000000..ea79cc3e3 --- /dev/null +++ b/test/cases/dsl-sec2gmt/0002n/expout @@ -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 diff --git a/test/cases/dsl-sec2gmt/0003n/cmd b/test/cases/dsl-sec2gmt/0003n/cmd new file mode 100644 index 000000000..7b1b46e13 --- /dev/null +++ b/test/cases/dsl-sec2gmt/0003n/cmd @@ -0,0 +1 @@ +mlr --from test/input/ten.dkvp --opprint put '$z=nsec2gmt($i * 1000000000 * 123456789)' diff --git a/test/cases/dsl-sec2gmt/0003n/experr b/test/cases/dsl-sec2gmt/0003n/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/dsl-sec2gmt/0003n/expout b/test/cases/dsl-sec2gmt/0003n/expout new file mode 100644 index 000000000..ce09f20de --- /dev/null +++ b/test/cases/dsl-sec2gmt/0003n/expout @@ -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 diff --git a/test/cases/dsl-sec2gmt/0004n/cmd b/test/cases/dsl-sec2gmt/0004n/cmd new file mode 100644 index 000000000..6d9a0cf22 --- /dev/null +++ b/test/cases/dsl-sec2gmt/0004n/cmd @@ -0,0 +1 @@ +mlr --from test/input/ten.dkvp --opprint put '$z=nsec2gmt($i * 1000000000 + 123456789,$i-1)' diff --git a/test/cases/dsl-sec2gmt/0004n/experr b/test/cases/dsl-sec2gmt/0004n/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/dsl-sec2gmt/0004n/expout b/test/cases/dsl-sec2gmt/0004n/expout new file mode 100644 index 000000000..bbfcc0f89 --- /dev/null +++ b/test/cases/dsl-sec2gmt/0004n/expout @@ -0,0 +1,11 @@ +a b i x y z +pan pan 1 0.34679014 0.72680286 1970-01-01T00:00:01Z +eks pan 2 0.75867996 -0.52215111 1970-01-01T00:00:02.1Z +wye wye 3 0.20460331 0.33831853 1970-01-01T00:00:03.12Z +eks wye 4 0.38139939 -0.13418874 1970-01-01T00:00:04.123Z +wye pan 5 0.57328892 0.86362447 1970-01-01T00:00:05.1234Z +zee pan 6 0.52712616 -0.49322129 1970-01-01T00:00:06.12345Z +eks zee 7 0.61178406 0.18788492 1970-01-01T00:00:07.123456Z +zee wye 8 0.59855401 0.97618139 1970-01-01T00:00:08.1234567Z +hat wye 9 0.03144188 -0.74955076 1970-01-01T00:00:09.12345678Z +pan wye 10 0.50262601 0.95261836 1970-01-01T00:00:10.123456789Z diff --git a/test/cases/help/0014/expout b/test/cases/help/0014/expout index 97977a3db..c0f1a0c10 100644 --- a/test/cases/help/0014/expout +++ b/test/cases/help/0014/expout @@ -22,6 +22,24 @@ Options: -h|--help Show this message. fsec2dhms (class=time #args=1) Formats floating-point seconds as in fsec2dhms(500000.25) = "5d18h53m20.250000s" fsec2hms (class=time #args=1) Formats floating-point seconds as in fsec2hms(5000.25) = "01:23:20.250000" +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". +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" +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" sec2dhms (class=time #args=1) Formats integer seconds as in sec2dhms(500000) = "5d18h53m20s" 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: diff --git a/test/cases/help/0016/expout b/test/cases/help/0016/expout index 87aa76721..eb9d95c77 100644 --- a/test/cases/help/0016/expout +++ b/test/cases/help/0016/expout @@ -20,6 +20,14 @@ Options: --micros Input numbers are treated as microseconds since the epoch. --nanos Input numbers are treated as nanoseconds since the epoch. -h|--help Show this message. +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" diff --git a/test/cases/repl-help/0014/expout b/test/cases/repl-help/0014/expout index a710a4f26..8e1c88ce0 100644 --- a/test/cases/repl-help/0014/expout +++ b/test/cases/repl-help/0014/expout @@ -1,5 +1,23 @@ fsec2dhms (class=time #args=1) Formats floating-point seconds as in fsec2dhms(500000.25) = "5d18h53m20.250000s" fsec2hms (class=time #args=1) Formats floating-point seconds as in fsec2hms(5000.25) = "01:23:20.250000" +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". +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" +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" sec2dhms (class=time #args=1) Formats integer seconds as in sec2dhms(500000) = "5d18h53m20s" 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: diff --git a/test/cases/repl-help/0016/expout b/test/cases/repl-help/0016/expout index ad1e26c87..ca42bd62d 100644 --- a/test/cases/repl-help/0016/expout +++ b/test/cases/repl-help/0016/expout @@ -1,3 +1,11 @@ +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" diff --git a/test/input/gmt2nsec b/test/input/gmt2nsec new file mode 100644 index 000000000..f63c71714 --- /dev/null +++ b/test/input/gmt2nsec @@ -0,0 +1,29 @@ +gmt +1970-01-01T00:00:00Z +1970-01-01T00:00:00.Z +1970-01-01T00:00:01Z +1970-01-01T00:00:01.0Z +1970-01-01T00:00:10Z +1970-01-01T00:00:10.00Z +1970-01-01T00:01:40Z +1970-01-01T00:01:40.1Z +1970-01-01T00:16:40Z +1970-01-01T00:16:40.12Z +1970-01-01T02:46:40Z +1970-01-01T02:46:40.123Z +1970-01-02T03:46:40Z +1970-01-02T03:46:40.1234Z +1970-01-12T13:46:40Z +1970-01-12T13:46:40.12345Z +1970-04-26T17:46:40Z +1970-04-26T17:46:40.123456Z +1973-03-03T09:46:40Z +1973-03-03T09:46:40.1234567Z +2001-09-09T01:46:40Z +2001-09-09T01:46:40.12345678Z +2015-05-19T11:49:40Z +2015-05-19T11:49:40.123456789Z +2017-07-14T02:40:00Z +2017-07-14T02:40:00.999Z +2033-05-18T03:33:20Z +2033-05-18T03:33:20.999999Z diff --git a/test/input/strfntime-tz.mlr b/test/input/strfntime-tz.mlr new file mode 100644 index 000000000..45f507617 --- /dev/null +++ b/test/input/strfntime-tz.mlr @@ -0,0 +1,17 @@ +end { + + print "---------------------------------------------------------------- TIMEZONE"; + print "TZ is", ENV["TZ"]; + + print "---------------------------------------------------------------- STRFNTIME"; + print strfntime(123456, "%Y-%m-%dT%H:%M:%SZ"); + print strfntime(0, "%Y-%m-%d %H:%M:%S"); + print strfntime(0, "%Y-%m-%d %H:%M:%3S"); + print strfntime(0, "%Y-%m-%d %H:%M:%S %Z"); + print strfntime(0, "%Y-%m-%d %H:%M:%S %z"); + print strfntime(123456, "%Y-%m-%d %H:%M:%S %Z"); + print strfntime(123456, "%Y-%m-%d %H:%M:%S %z"); + print strfntime(0, "%Y-%m-%d %H:%M:%S %Z"); + print strfntime(0, "%Y-%m-%d %H:%M:%S %z"); + +} diff --git a/test/input/strfntime_local-tz.mlr b/test/input/strfntime_local-tz.mlr new file mode 100644 index 000000000..2e903b163 --- /dev/null +++ b/test/input/strfntime_local-tz.mlr @@ -0,0 +1,17 @@ +end { + + print "---------------------------------------------------------------- TIMEZONE"; + print "TZ is", ENV["TZ"]; + + print "---------------------------------------------------------------- STRFNTIME_LOCAL"; + print strfntime_local(0, "%Y-%m-%d %H:%M:%S"); + print strfntime_local(0, "%Y-%m-%d %H:%M:%3S"); + + print strfntime_local(0, "%Y-%m-%d %H:%M:%S %Z"); + print strfntime_local(0, "%Y-%m-%d %H:%M:%S %z"); + print strfntime_local(123456, "%Y-%m-%d %H:%M:%S %Z"); + print strfntime_local(123456, "%Y-%m-%d %H:%M:%S %z"); + print strfntime_local(0, "%Y-%m-%d %H:%M:%S %Z"); + print strfntime_local(0, "%Y-%m-%d %H:%M:%S %z"); + +} diff --git a/test/input/strpntime-tz.mlr b/test/input/strpntime-tz.mlr new file mode 100644 index 000000000..a4d7ea7b4 --- /dev/null +++ b/test/input/strpntime-tz.mlr @@ -0,0 +1,14 @@ +end { + + print "---------------------------------------------------------------- TIMEZONE"; + print "TZ is", ENV["TZ"]; + + print "---------------------------------------------------------------- STRPNTIME"; + print strpntime("1970-01-01T00:00:00Z", "%Y-%m-%dT%H:%M:%SZ"); + print strpntime("1970-01-01T00:00:00.345Z", "%Y-%m-%dT%H:%M:%SZ"); + print strpntime("1970-01-01T00:00:00.345 UTC", "%Y-%m-%dT%H:%M:%S %Z"); + print strpntime("1970-01-01T00:00:00.345 EST", "%Y-%m-%dT%H:%M:%S %Z"); + print strpntime("1970-01-01T00:00:00.345 -0400", "%Y-%m-%dT%H:%M:%S %z"); + print strpntime("1970-01-01T00:00:00.345 +0400", "%Y-%m-%dT%H:%M:%S %z"); + +} diff --git a/test/input/strpntime_local-tz.mlr b/test/input/strpntime_local-tz.mlr new file mode 100644 index 000000000..c34636bb3 --- /dev/null +++ b/test/input/strpntime_local-tz.mlr @@ -0,0 +1,9 @@ +end { + + print "---------------------------------------------------------------- TIMEZONE"; + print "TZ is", ENV["TZ"]; + + print "---------------------------------------------------------------- STRPNTIME_LOCAL"; + print strpntime_local("1970-01-01 00:00:00", "%Y-%m-%d %H:%M:%S"); + +}