@ARGS: --lib tests/fixtures/libs
The time library represents a point in time as a plain integer (i64) holding milliseconds since the Unix epoch — the same unit now() returns. All calendar math is UTC and uses the proleptic Gregorian calendar, so results are identical on the interpreter, --native, and WebAssembly. Import it with use time; and call its free functions with the time:: prefix.
Timezone model: field accessors and formatters are UTC. For local-day bucketing pass a fixed UTC offset in minutes (to_local / local_day / today). There is no timezone database and no daylight-saving handling — a fixed offset only.
use time;
Parsing and field access
parse reads an ISO date "YYYY-MM-DD", optionally followed by a time. The accessors return UTC calendar fields; weekday is 0=Mon..6=Sun.
fn show_fields() {
d = time::parse("2026-05-25");
assert(time::year(d) == 2026, "year");
assert(time::month(d) == 5, "month");
assert(time::day(d) == 25, "day");
assert(time::weekday(d) == 0, "2026-05-25 is a Monday");
assert(time::weekday_name(d) == "Mon", "weekday name");
assert(time::month_name(d) == "May", "month name");
t = time::parse("2026-05-25 14:30:07");
assert(time::hour(t) == 14, "hour");
assert(time::minute(t) == 30, "minute");
assert(time::second(t) == 7, "second");
The "T...Z" ISO form parses to the same instant as the space form.
assert(time::parse("2026-05-25T14:30:07Z") == t, "ISO T/Z form");
Malformed input parses to null — test with !.
bad = time::parse("not-a-date");
assert(!bad, "garbage is null");
}
Formatting
fn show_formatting() {
t = time::parse("2026-05-25 14:30:07");
assert(time::format_date(t) == "2026-05-25", "format_date");
assert(time::format_time(t) == "14:30", "format_time");
assert(time::format_seconds(t) == "14:30:07", "format_seconds");
assert(time::format_datetime(t) == "2026-05-25 14:30", "format_datetime");
assert(time::format_iso(t) == "2026-05-25T14:30:07Z", "format_iso");
}
Arithmetic and differences
Stepping never desynchronises across leap years — the math is exact.
fn show_arithmetic() {
jan1 = time::parse("2026-01-01");
assert(time::format_date(time::add_weeks(jan1, 1)) == "2026-01-08", "add_weeks");
assert(time::format_date(time::add_days(jan1, 365)) == "2027-01-01", "add_days");
Leap-day boundary.
feb28 = time::parse("2024-02-28");
assert(time::format_date(time::add_days(feb28, 1)) == "2024-02-29", "leap day");
dec31 = time::parse("2026-12-31");
assert(time::days_between(jan1, dec31) == 364, "days_between");
hourly = time::seconds_between(time::parse("2026-01-01 00:00:00"),
time::parse("2026-01-01 01:00:00"));
assert(hourly == 3600, "seconds_between");
}
Week boundaries and ISO week numbering
fn show_weeks() {
start_of_week snaps back to Monday 00:00.
wed = time::parse("2026-05-27");
assert(time::format_date(time::start_of_week(wed)) == "2026-05-25", "Monday of week");
2026-01-01 is a Thursday -> ISO week 1 of 2026.
assert(time::iso_year(time::parse("2026-01-01")) == 2026, "iso_year");
assert(time::iso_week(time::parse("2026-01-01")) == 1, "iso_week");
2021-01-01 is a Friday -> still ISO week 53 of 2020.
jan1_2021 = time::parse("2021-01-01");
assert(time::iso_year(jan1_2021) == 2020, "iso_year rollback");
assert(time::iso_week(jan1_2021) == 53, "iso_week 53");
}
Local day at a fixed offset
23:30 UTC at +120 minutes is 01:30 the next local day.
fn show_local() {
t = time::parse("2026-05-25 23:30:00");
assert(time::format_datetime(time::to_local(t, 120)) == "2026-05-26 01:30", "to_local");
assert(time::format_date(time::local_day(t, 120)) == "2026-05-26", "local_day");
}
fn main() {
show_fields();
show_formatting();
show_arithmetic();
show_weeks();
show_local();
println("time library: all checks passed");
}