diff options
author | Kim Alvefur <zash@zash.se> | 2022-08-14 16:57:31 +0200 |
---|---|---|
committer | Kim Alvefur <zash@zash.se> | 2022-08-14 16:57:31 +0200 |
commit | c85c18b03ab627ee81273d4c0f0009e1a5cc2d03 (patch) | |
tree | 9add9e2fed946e270cc3fe1736c4e78e5d31e8b3 /util | |
parent | d79609ddc922ef12032c738fdb8e602818f244e0 (diff) | |
download | prosody-c85c18b03ab627ee81273d4c0f0009e1a5cc2d03.tar.gz prosody-c85c18b03ab627ee81273d4c0f0009e1a5cc2d03.zip |
util.datetime: Add support for sub-second precision timestamps
Lua since 5.3 raises a fuss when time functions are handed a number with
a fractional part and the underlying C functions are all based on
integer seconds without support for more precision.
Diffstat (limited to 'util')
-rw-r--r-- | util/datetime.lua | 26 |
1 files changed, 19 insertions, 7 deletions
diff --git a/util/datetime.lua b/util/datetime.lua index 2d27ece4..8fa1a778 100644 --- a/util/datetime.lua +++ b/util/datetime.lua @@ -12,31 +12,42 @@ local os_date = os.date; local os_time = os.time; local os_difftime = os.difftime; +local floor = math.floor; local tonumber = tonumber; local _ENV = nil; -- luacheck: std none local function date(t) - return os_date("!%Y-%m-%d", t); + return os_date("!%Y-%m-%d", t and floor(t) or nil); end local function datetime(t) - return os_date("!%Y-%m-%dT%H:%M:%SZ", t); + if t == nil or t % 1 == 0 then + return os_date("!%Y-%m-%dT%H:%M:%SZ", t); + end + local m = t % 1; + local s = floor(t); + return os_date("!%Y-%m-%dT%H:%M:%S.%%06dZ", s):format(floor(m * 1000000)); end local function time(t) - return os_date("!%H:%M:%S", t); + if t == nil or t % 1 == 0 then + return os_date("!%H:%M:%S", t); + end + local m = t % 1; + local s = floor(t); + return os_date("!%H:%M:%S.%%06d", s):format(floor(m * 1000000)); end local function legacy(t) - return os_date("!%Y%m%dT%H:%M:%S", t); + return os_date("!%Y%m%dT%H:%M:%S", t and floor(t) or nil); end local function parse(s) if s then local year, month, day, hour, min, sec, tzd; - year, month, day, hour, min, sec, tzd = s:match("^(%d%d%d%d)%-?(%d%d)%-?(%d%d)T(%d%d):(%d%d):(%d%d)%.?%d*([Z+%-]?.*)$"); + year, month, day, hour, min, sec, tzd = s:match("^(%d%d%d%d)%-?(%d%d)%-?(%d%d)T(%d%d):(%d%d):(%d%d%.?%d*)([Z+%-]?.*)$"); if year then local now = os_time(); local time_offset = os_difftime(os_time(os_date("*t", now)), os_time(os_date("!*t", now))); -- to deal with local timezone @@ -49,8 +60,9 @@ local function parse(s) tzd_offset = h * 60 * 60 + m * 60; if sign == "-" then tzd_offset = -tzd_offset; end end - sec = (sec + time_offset) - tzd_offset; - return os_time({year=year, month=month, day=day, hour=hour, min=min, sec=sec, isdst=false}); + local prec = sec%1; + sec = floor(sec + time_offset) - tzd_offset; + return os_time({year=year, month=month, day=day, hour=hour, min=min, sec=sec, isdst=false})+prec; end end end |