14

How would you convert a timestamp to an ISO 8601 format (such as 2009-01-28T21:49:59.000Z) in Lua?

I'm specifically trying to do it by using the HttpLuaModule in Nginx.

Mark
  • 67,098
  • 47
  • 117
  • 162

3 Answers3

26

Try os.date("!%Y-%m-%dT%TZ") or os.date("!%Y-%m-%dT%TZ",t) if t has the date in seconds since the epoch.

Mark
  • 67,098
  • 47
  • 117
  • 162
lhf
  • 70,581
  • 9
  • 108
  • 149
  • 3
    This works except that `%M` should be lowercase: `%m`. Answer updated. – Mark Nov 21 '13 at 21:25
  • 5
    FWIW, this does not work on Windows on Lua 5.3.4, producing: `bad argument #1 to 'date' (invalid conversion specifier '%TZ')`. Fixed version: `os.date("!%Y-%m-%dT%H:%M:%SZ")` – Phrogz Nov 02 '18 at 15:03
1

You asked to include milliseconds, so there is a little gymnastics involved because the os.date format doesn't permit milliseconds.
This works when running in Nginx (which was the context of your question)

-- Return a ISO 8061 formatted timestamp in UTC (Z)
-- @return e.g. 2021-09-21T15:20:44.323Z
local function iso_8061_timestamp()
    local now = ngx.now()                               -- 1632237644.324
    local ms = math.floor((now % 1) * 1000)             -- 323 or 324 (rounding)
    local epochSeconds = math.floor(now)
    return os.date("!%Y-%m-%dT%T", epochSeconds) .. "." .. ms .. "Z"  -- 2021-09-21T15:20:44.323Z
end

Note the useful date format reference here: https://developpaper.com/lua-os-date-notes/

Paul Hilliar
  • 579
  • 6
  • 8
-1

Or you can use:

local now_date_time = os.date("!%Y%m%dT%H%M%S") --> For date_time: 20191015T042028Z

local now_date = os.date("!%Y%m%d") --> For only date: 20191015
dalmate
  • 462
  • 5
  • 13