-- 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