perch.time — always granted
Pure, no scope needed. Backed by the platform’s full IANA time-zone database.
perch.time.now(zone?)
local t = perch.time.now() -- system local time
local tk = perch.time.now("Asia/Tokyo") -- any IANA zone
Returns a table:
| Field | Meaning |
|---|---|
hour min sec | 24-hour clock fields |
year mon day | calendar date (mon 1–12) |
dow | day of week, 0 = Sunday |
off | UTC offset in minutes, DST-correct |
An unknown zone returns { error = "unknown zone" } — check before
trusting fields when the zone string is user input.
perch.time.format(fmt, zone?)
perch.time.format("%H:%M") -- "17:42"
perch.time.format("%A, %B %e", "Europe/Paris")
Formats now in the given zone with a
std::format chrono spec
(%H %M %S %A %B %d %p…). Returns "?" on a bad spec or zone.
perch.json — always granted
local tbl = perch.json.decode(body) -- string → table, nil-ish on bad JSON
local str = perch.json.encode(tbl) -- table → string
The bridge between perch.http.get bodies and Lua
tables. decode of invalid JSON returns nothing — guard it:
local data = perch.json.decode(body)
if not data then return end
perch.storage — scope storage
perch.storage.set("history", { 3, 4, 6, 9 })
local hist = perch.storage.get("history") -- nil if never set
- Per-mod, persisted across restarts, invisible to other mods.
- Values are JSON-shaped: tables, strings, numbers, booleans.
- 64 KB total cap — a write that would exceed it is discarded, so keep it for state, not caches of fetched data.
The wider guidance on what belongs in storage vs settings vs pushes: Settings & storage.