datumhue.time.now
functiondatumhue.time.now() -> numberMonotonic seconds elapsed since the app started.
In the guide: Pixel art and sprites 3D scenes
namespaceTimers10 functions
Monotonic time measurement and scheduled callbacks.
datumhue.time.now() -> numberMonotonic seconds elapsed since the app started.
In the guide: Pixel art and sprites 3D scenes
datumhue.time.unix_micros() -> integerWall-clock microseconds since the Unix epoch.
datumhue.time.calendar(at_micros: integer) -> CalendarBreak a Unix-microseconds timestamp (as from time.unix_micros) into its UTC calendar fields. Pair with the fields and time.unix_micros to build relative or formatted time in the app's own locale. Raises if the timestamp is out of the representable range.
local epoch = datumhue.time.calendar(0)
print(epoch) --> 1970-01-01T00:00:00Z
-- Months and days count from 1; weekday 1 is Monday.
print(epoch.month, epoch.day, epoch.weekday) --> 1 1 4
-- The date and time now, in UTC.
local now = datumhue.time.calendar(datumhue.time.unix_micros())datumhue.time.from_calendar(opts: time.FromCalendarOptions) -> integerBuild a Unix-microseconds timestamp (UTC) from calendar fields — the inverse of time.calendar. Raises on an invalid date or time (e.g. month 13, Feb 30, hour 24).
-- Fields left out start their range: day 1, midnight, UTC.
local start = datumhue.time.from_calendar({ year = 2026, month = 10 })
print(start) --> 1790812800000000
print(datumhue.time.calendar(start)) --> 2026-10-01T00:00:00Zopts time.FromCalendarOptions options 6 keys
| Key | Type | Default | Description |
|---|---|---|---|
| year required | integer | no default | Full year (e.g. 2026). |
| month | integer | 1 | Month, 1-12. |
| day | integer | 1 | Day of the month, 1-31. |
| hour | integer | 0 | Hour, 0-23. |
| minute | integer | 0 | Minute, 0-59. |
| second | integer | 0 | Second, 0-59. |
datumhue.time.day_index(micros: integer) -> integerWhole days since 1970-01-01 UTC for a unix-microseconds instant (as returned by unix_micros). Floor division: a day boundary is midnight UTC, and instants before the epoch give negative indices.
local day = 24 * 60 * 60 * 1000000
print(datumhue.time.day_index(day)) --> 1
-- Days start at midnight UTC; the instant before 1970 is day -1.
print(datumhue.time.day_index(-1)) --> -1
-- The same all day long: a seed for a daily puzzle.
local today = datumhue.time.day_index(datumhue.time.unix_micros())datumhue.time.after(secs: number, callback: fun(dt: number)) -> TimerSchedule a one-shot callback to fire after secs seconds, on the first frame tick that reaches them. dt is the seconds the timer ran before it fired, leaving out any time it was paused. 0 fires on the next frame tick — the way to defer work out of the current callback. Returns a timer; call :unsubscribe() to cancel it before it fires, or pause/resume and query it.
datumhue.time.after(0.2, function(dt)
print("a fifth of a second later")
end)
-- 0 waits for the next frame.
datumhue.time.after(0, function(dt)
print("next frame")
end)In the guide: Make music Keyboard and gamepad Theme and density
datumhue.time.every(secs: number, callback: fun(dt: number)) -> TimerSchedule a repeating callback to fire every secs seconds, on frame ticks. dt is the seconds the timer ran since its last fire, or since it was created for the first, leaving out any time it was paused. Fires that come due while the last one still waits to run, behind a callback that runs long or waits for a result, run as one, whose dt covers them all. An interval of 0 fires once every frame — the frame hook for a library, leaving the app's single datumhue.on_update slot free. Returns a timer; call :unsubscribe() to stop it, or pause/resume and query it.
-- Every 0.05 seconds, until it stops itself after the third.
local count = 0
local timer
timer = datumhue.time.every(0.05, function(dt)
count = count + 1
if count == 3 then
timer:unsubscribe()
end
end)In the guide: Play sound Make music Messages, events and shared state
datumhue.time.tween(opts: time.TweenOptions) -> TimerAnimate a value from from to to over duration seconds, delivering the eased in-between value to on_update on each frame tick. Like a timer's fires, deliveries that come due while the last one still waits to run come as one, with the latest value. The final delivery is exactly to, then on_finish runs. from and to must be the same type. Returns a timer: :unsubscribe() cancels it (no further deliveries, on_finish never runs), and pause/resume/elapsed/remaining work as on any timer. Colors blend perceptually (Oklab, like Color:lerp).
local canvas = datumhue.draw.new({ width = 320, height = 240 })
canvas:mount({ width = 320, height = 240 })
local dot = canvas:circle({ color = datumhue.color("#a7c080") })
datumhue.time.tween({
from = datumhue.math.vec2(-120, 0),
to = datumhue.math.vec2(120, 0),
duration = 0.5,
easing = "cubic_out",
on_update = function(pos)
dot.pos = pos
end,
})opts time.TweenOptions options 6 keys
| Key | Type | Default | Description |
|---|---|---|---|
| from required | number | Vec2 | Vec3 | Color | no default | Start value. Same type as to. |
| to required | number | Vec2 | Vec3 | Color | no default | End value. Same type as from. |
| duration required | number | no default | Tween duration in seconds. |
| easing | Easing | "linear" | Easing curve. |
| on_update required | fun(value: number | Vec2 | Vec3 | Color) | no default | Receives the in-between value each frame while the tween runs; a delivery due while the last one still waits to run replaces its value. The final delivery is exactly to. |
| on_finish | fun() | no default | Runs once, after the final on_update delivery. Skipped when the tween is unsubscribed before it finishes. |
datumhue.time.sleep(secs: number)Pause the calling code for secs seconds on the per-frame clock that drives timers, then continue. The wait resolves on frame ticks, so the actual pause rounds up to the frame. 0 returns at once.
print("on your marks")
-- A quarter second, rounded up to whole frames.
datumhue.time.sleep(0.25)
print("go")In the guide: Waiting: suspending calls and handles
datumhue.time.wait_frames(frames: integer)Pause the calling code for frames frame ticks, then continue. 1 resumes on the next frame; 0 returns at once.
In the guide: Launch other apps