Moonshark/runner/lua/timestamp.lua

94 lines
2.9 KiB
Lua

-- timestamp.lua
local timestamp = {}
-- Standard format presets using Lua format codes
local FORMATS = {
iso = "%Y-%m-%dT%H:%M:%SZ",
datetime = "%Y-%m-%d %H:%M:%S",
us_date = "%m/%d/%Y",
us_datetime = "%m/%d/%Y %I:%M:%S %p",
date = "%Y-%m-%d",
time = "%H:%M:%S",
time12 = "%I:%M:%S %p",
readable = "%B %d, %Y %I:%M:%S %p",
compact = "%Y%m%d_%H%M%S"
}
-- Parse input to unix timestamp and microseconds
local function parse_input(input)
local unix_time, micros = 0, 0
if type(input) == "string" then
local frac, secs = input:match("^(0%.%d+)%s+(%d+)$")
if frac and secs then
unix_time = tonumber(secs)
micros = math.floor((tonumber(frac) * 1000000) + 0.5)
else
unix_time = tonumber(input) or 0
end
elseif type(input) == "number" then
unix_time = math.floor(input)
micros = math.floor(((input - unix_time) * 1000000) + 0.5)
end
return unix_time, micros
end
-- Remove leading zeros from number string
local function no_leading_zero(s)
return s:gsub("^0+", "") or "0"
end
-- Main format function
function timestamp.format(input, fmt)
fmt = fmt or "datetime"
local format_str = FORMATS[fmt] or fmt
local unix_time, micros = parse_input(input)
local result = os.date(format_str, unix_time)
-- Handle microseconds if format contains dot
if format_str:find("%.") then
result = result .. string.format(".%06d", micros)
end
return result
end
-- US date/time with no leading zeros
function timestamp.us_datetime_no_zero(input)
local unix_time, micros = parse_input(input)
local month = no_leading_zero(os.date("%m", unix_time))
local day = no_leading_zero(os.date("%d", unix_time))
local year = os.date("%Y", unix_time)
local hour = no_leading_zero(os.date("%I", unix_time))
local min = os.date("%M", unix_time)
local sec = os.date("%S", unix_time)
local ampm = os.date("%p", unix_time)
return string.format("%s/%s/%s %s:%s:%s %s", month, day, year, hour, min, sec, ampm)
end
-- Quick preset functions
function timestamp.iso(input) return timestamp.format(input, "iso") end
function timestamp.datetime(input) return timestamp.format(input, "datetime") end
function timestamp.us_date(input) return timestamp.format(input, "us_date") end
function timestamp.us_datetime(input) return timestamp.us_datetime_no_zero(input) end
function timestamp.date(input) return timestamp.format(input, "date") end
function timestamp.time(input) return timestamp.format(input, "time") end
function timestamp.time12(input) return timestamp.format(input, "time12") end
function timestamp.readable(input) return timestamp.format(input, "readable") end
-- Microsecond precision variants
function timestamp.datetime_micro(input)
return timestamp.format(input, "%Y-%m-%d %H:%M:%S.") .. string.format("%06d", select(2, parse_input(input)))
end
function timestamp.iso_micro(input)
return timestamp.format(input, "%Y-%m-%dT%H:%M:%S.") .. string.format("%06dZ", select(2, parse_input(input)))
end
-- Register global convenience function
_G.format_time = timestamp.format
return timestamp