now() and today()

now() is the current time as a datetime in UTC; today() is its date, and today(zone) the date in a zone (an IANA name or an offset).

type_of(now())   // "datetime"
now() == now()   // true
type_of(today("Europe/Berlin"))   // "date"
g.add_v("event").property("at", now()).values("at").count().next()   // 1

The start of the evaluation

Like PostgreSQL's now() (CURRENT_TIMESTAMP), now() is the time the script evaluation started, the same value for every call in it: a script that stamps a thousand elements stamps them all with one instant, and now() == now() holds. In the playground a whole script is one unit, so now() is the start of that unit. A saved query called from a script sees its caller's now().

now() and today() are script functions, evaluated before the traversal runs: the traversal gets the resulting value as a constant (inject(now()), property("at", now()), has("at", P.lt(now()))). The journal of a Store and a change set record that value, never the call, so a replay or a recovery writes the same instant, not the time of the replay.

today() is the date of now() in UTC, PostgreSQL's current_date in a UTC session. For the date in another zone pass the zone, or convert the instant yourself:

today("UTC") == today()   // true
g.inject(now()).as_local("America/Los_Angeles").as_date(GType.DATE).next() == today("America/Los_Angeles")   // true

Pinning the clock (hosts)

A host that needs a deterministic clock (tests, a replay of a recorded session) pins it on its engine with graphersal::script::pin_now; every evaluation on that engine then returns the pinned instant, until it is unpinned with None:

use graphersal::script::{engine_with_options, pin_now};
use graphersal::temporal::DateTime;

let mut engine = engine_with_options(&limits, authorizer, &presets);
pin_now(&mut engine, Some("2023-08-02T23:30:00-07:00".parse::<DateTime>()?));
// now() is 2023-08-02T23:30:00-07:00, today() is 2023-08-03 (the UTC date)
pin_now(&mut engine, None); // the system clock again

The system clock is read through web_time, so now() works the same in the WebAssembly playground.