Skip to main content

Time Library

The Time builtin library is AdeshLang's production-grade date, time, and duration system. It provides monotonic Instant and wall-clock SystemTime measurements, ISO-style Duration math, naive Date / TimeOfDay / DateTime, timezone-aware UTC, Offset, and Zoned date-times, parsing and formatting, plus Period, Stopwatch, Timer, and interval helpers.

The API is written in AdeshLang itself (src/stdlib/Time.adesh) on top of native time.* primitives (system clock, monotonic clock, sleep, format/parse, and timezone lookup), so it works consistently across every backend.

Classes

ClassWhat it represents
DurationA length of time measured in nanoseconds
InstantA monotonic point in time (stopwatch-friendly)
SystemTimeA wall-clock point relative to the Unix epoch
DateA calendar date (year, month, day)
TimeOfDayA time within the day (hour … nanosecond)
DateTimeA naive local date + time (no timezone)
UtcDateTimeAn exact moment in UTC
UtcOffsetA fixed UTC offset (+05:30, Z, …)
OffsetDateTimeA UTC moment with a fixed offset
TimeZone / ZonedDateTimeA named zone (e.g. "America/New_York") and a moment in it
Weekday / MonthDay-of-week and month abstractions
PeriodA calendar-based span (years, months, days)
Stopwatch / Timer / IntervalElapsed-time and scheduling utilities
MeasurementA value plus the duration it took to produce
TimeError / ParseTimeErrorErrors with message(), kind() / position()

Importing the library

import Time; // or import time;

Access classes through the namespace: Time.dateYmd(2024, 6, 21), Duration.seconds(5), new Time.Date(...). Factory functions avoid new for the most common cases.


Duration — lengths of time

Internally stored as a bigint count of nanoseconds.

Construction — static factories and free functions:

FactoryUnit
Duration.fromNanos(n) / Duration.nanoseconds(n)nanoseconds
Duration.microseconds(n)microseconds
Duration.milliseconds(n)milliseconds
Duration.seconds(n)seconds
Duration.minutes(n)minutes
Duration.hours(n)hours
Duration.days(n)days
Time.durationZero()0
Time.durationMilliseconds(n) / Time.durationSeconds(n) / …free-function forms

Accessorsnanoseconds()weeks() return the component within the next larger unit (like Rust's std::time::Duration); wholeSeconds() / wholeMilliseconds() / wholeDays() etc. return the total count in that unit; asSecondsF64() / asMillisecondsF64() give float totals.

Arithmetic & comparisoncheckedAdd, checkedSub, checkedMul, checkedDiv, negated(), abs(), min, max, clamp(min, max), and lt / gt / eq / lte / gte.

import Time;

let timeout = Duration.seconds(5);
let tiny = Duration.milliseconds(250);

print(tiny.wholeMilliseconds()); // 250
print(timeout.asSecondsF64()); // 5.0
print(tiny.lt(timeout)); // true
print(timeout.toString()); // 5s
print(Duration.seconds(3725).toString()); // 1h 2m 5s

// Timeout from the process library takes any Duration:
let result = Process.builder("git")
.args(["status"])
.runTimeout(Duration.seconds(5))
.run();

Instant & SystemTime — "now"

FactoryReturnsMeaning
Time.instantNow()InstantMonotonic clock — only useful for measuring elapsed time
Time.systemTimeNow()SystemTimeWall-clock time since the Unix epoch
Time.systemTimeEpoch()SystemTime1970-01-01T00:00:00Z
Time.systemTimeFromUnixSeconds(sec) / …Milliseconds / …Microseconds / …NanosecondsSystemTimeBuild from a Unix timestamp
  • Instant: .elapsed()Duration, .add/.sub/.checkedAdd/.checkedSub, .nanoseconds(), comparisons, toString().
  • SystemTime: .durationSinceEpoch(), .epochSeconds()/.epochMilliseconds(), .toUnixSeconds()/…Milliseconds/…Microseconds/…Nanoseconds, .add/.sub, comparisons, .toUtcDateTime().
import Time;

let start = Time.instantNow();
// ... do work ...
let elapsed = start.elapsed();
print("Took", elapsed.toString());

let now = Time.systemTimeNow();
print(now.toUnixSeconds()); // seconds since the epoch

Date — calendar dates

Construct with Time.dateYmd(year, month, day) (validated; invalid dates throw TimeError). Also Time.dateToday() and Time.dateTodayUtc().

GroupMethods
Accessorsyear(), month(), day(), weekday(), dayOfYear(), weekOfYear(), isLeapYear(), daysInMonth(), daysInYear()
ArithmeticaddDays(n), addWeeks(n), addMonths(n), addYears(n), subDays(n), nextDay(), previousDay()
Weekday-basednext(Weekday), previous(Weekday)
Month edgesfirstDayOfMonth(), lastDayOfMonth()
Copy-withwithYear(y), withMonth(m), withDay(d)
CombineatStartOfDay(), at(TimeOfDay)DateTime
MathdaysSince(other), toEpochDays()
Comparelt, gt, eq
Outputformat(pattern), toIsoString() (yyyy-MM-dd)
import Time;

let d = Time.dateYmd(2024, 2, 29); // leap day — valid
print(d.weekday()); // Thursday
print(d.isLeapYear()); // true
print(d.addMonths(1).toIsoString()); // 2024-03-29
print(d.daysSince(Time.dateYmd(2024, 1, 1))); // 59
print(d.next(Time.weekdayFromInt(1))); // next Monday
tip

addMonths/addYears clamp the day to the target month's length (e.g. Jan 31 + 1 month → Feb 29/28).


TimeOfDay — time within a day

Construct with Time.timeOfDay(hour, minute, second, nanosecond) or Time.timeNow() / Time.timeNowUtc().

GroupMethods
Accessorshour(), minute(), second(), nanosecond(), millisecond(), microsecond(), secondsSinceMidnight()
ArithmeticaddHours(h), subHours(h), addMinutes(m), subMinutes(m) (wraps around midnight)
Comparelt, gt, eq
OutputtoIsoString() (HH:mm:ss[.fffffffff])
import Time;

let t = Time.timeOfDay(23, 59, 30, 0);
print(t.addMinutes(45).toIsoString()); // 00:44:30 (wraps)
print(t.secondsSinceMidnight()); // 86370

DateTime — naive local date-time

Construct with Time.dateTime(date, timeOfDay) or Time.dateTimeCreate(y, m, d, h, mi, s, ns); get "now" with Time.dateTimeNow().

GroupMethods
Accessorsdate(), time(), year(), month(), day(), hour(), minute(), second(), nanosecond(), weekday(), dayOfYear()
Copy-withwithYear, withMonth, withDay, withHour, withMinute, withSecond, withNanosecond
TruncatetruncateToSecond(), truncateToMinute()
ArithmeticaddDays, subDays, addHours, subHours, addMonths, addYears
DifferencedurationUntil(other), durationSince(other)
Comparelt, gt, eq
Outputformat(pattern), toIsoString() (yyyy-MM-ddTHH:mm:ss[.n])
import Time;

let dt = Time.dateTime(Time.dateYmd(2024, 6, 21), Time.timeOfDay(10, 30, 0, 0));
let nextWeek = dt.addDays(7);

print(dt.toIsoString()); // 2024-06-21T10:30:00
print(dt.durationUntil(nextWeek)); // 7d
print(dt.lt(nextWeek)); // true
print(dt.format("dd/MM/yyyy HH:mm:ss")); // 21/06/2024 10:30:00

UTC, Offsets & Timezones

UtcDateTime — exact moment in UTC

Factories: Time.utcDateTimeNow(), Time.utcDateTimeFromUnixSeconds(sec), Time.utcDateTimeFromNanos(ns).

GroupMethods
Unix accessorsunixSeconds(), unixMilliseconds(), unixNanoseconds()
Calendar accessorsyear()second() (computed in UTC)
ConverttoOffset(offset)OffsetDateTime, toZone(tz)ZonedDateTime
Arithmeticadd(d), sub(d), durationSince(other)
Comparelt, gt, eq
Outputformat(pattern), toIsoString() (…Z), toRfc3339()

UtcOffset — fixed offset

Factories: Time.utcOffsetHours(h), Time.utcOffsetHoursMinutes(h, m), Time.utcOffsetParse("+05:30"), Time.utcOffsetZero().

Methods: totalSeconds(), hours(), minutes()/minutesPart(), secondsPart(), isUtc(), isPositive(), isNegative(), lt/gt/eq, toString() (Z, +05:30, -07:00).

OffsetDateTime — UTC moment + fixed offset

Factories: Time.offsetDateTimeNow(offset), Time.offsetDateTimeParse("2024-06-15T08:00:00+05:30").

Methods: offset(), toUtc(), toOffset(newOffset)/withOffset(newOffset), unixSeconds(), calendar accessors (date(), time(), year()second() in local terms), add/sub, comparisons, format, toIsoString(), toRfc3339().

TimeZone & ZonedDateTime — named zones

Factories: Time.timeZoneUtc(), Time.timeZoneLocal(), Time.timeZoneOf("America/New_York"), Time.zonedDateTimeNow(tz).

  • TimeZone: name(), offsetAt(instant)UtcOffset (resolves DST for the given instant).
  • ZonedDateTime: zone(), timeZoneName(), offset() (at that instant), toUtc(), toZone(other)/withTimeZone(other), calendar accessors, unixSeconds(), format, toIsoString() (includes XXX offset).
import Time;

let utc = Time.utcDateTimeParse("2024-06-15T08:00:00Z");

// Fixed offset
let ist = utc.toOffset(Time.utcOffsetHoursMinutes(5, 30));
print(ist.toIsoString()); // 2024-06-15T13:30:00.000000+05:30

// Named zone (DST-aware)
let ny = utc.toZone(Time.timeZoneOf("America/New_York"));
print(ny.toIsoString()); // ...-04:00 (EDT in June)

// RFC 3339 round-trip
let odt = Time.offsetDateTimeParse("2024-06-15T08:00:00-07:00");
print(odt.toUtc().toIsoString()); // 2024-06-15T15:00:00.000000Z

Weekday & Month

Construct via Time.weekdayFromInt(n) (0=Monday…6=Sunday) or Time.monthFromInt(m) (1–12).

  • Weekday: numberFromMonday() (0=Mon), numberFromSunday() (0=Sun), isWeekend(), next(), previous(), name(), shortName().
  • Month: number(), days() (non-leap), daysInYear(y), daysIn(year), next(), previous(), name(), shortName().

Period — calendar spans

A span of (years, months, days) that respects calendar rules when applied to a Date.

Factories: Time.period(y, m, d), Time.periodYears(y), Time.periodMonths(m), Time.periodDays(d), Time.periodBetween(start, end).

GroupMethods
Accessorsyears(), months(), days()
Arithmeticadd(other), sub(other), negated(), abs()
Apply to dateaddToDate(date), subFromDate(date)
OutputtoString() (ISO PnYnMnD, P0D for zero)
import Time;

let age = Time.period(1, 6, 10); // 1y 6m 10d
print(age.addToDate(Time.dateYmd(2024, 1, 31)).toIsoString()); // 2025-08-10
print(age.toString()); // P1Y6M10D
print(Time.periodBetween(
Time.dateYmd(2023, 6, 1),
Time.dateYmd(2024, 6, 1)
).toString());

Stopwatch, Timer, Interval, Measurement

Class / fnPurposeKey methods
Time.stopwatch() / Time.stopwatchStartNew()Elapsed-time measurementstart(), stop() (pause), reset(), restart(), lap()Duration, elapsed(), isRunning()
Time.timerAfter(duration) / Time.timerAt(instant)A future instantwait() (block until due), cancel(), isCancelled(), isFinished()
Time.timeInterval(duration)Repeating tick schedulenext() (blocks until the next tick)
Time.timeMeasure(callback)Time a callablereturns Measurement: .value(), .duration()
import Time;

// Stopwatch with laps:
let sw = Time.stopwatchStartNew();
// ... work ...
print("lap:", sw.lap());
// ... more work ...
print("total:", sw.elapsed().toString());

// Time a function call:
let m = Time.timeMeasure(fn() {
return 40 + 2;
});
print(m.value()); // 42
print(m.duration().toString());

// Block for a fixed amount:
Time.timeSleep(Duration.milliseconds(100));

Parsing & Formatting

Formatting — every date/time class has .format(pattern). Common tokens (used throughout the examples):

TokenMeaningExample
yyyy4-digit year2024
MMzero-padded month06
MMM / MMMMshort / full month nameJun / June
ddzero-padded day05
HHzero-padded hour (24 h)15
mmzero-padded minute08
sszero-padded second03
f…fractional seconds (ffffff = 6 digits)750000
XXXoffset (Z, +05:30)+05:30
'T'literal textT

Parsing — factory functions return null (not a throw) on failure:

FunctionInput format
Time.dateParse("2024-06-21")yyyy-MM-dd
Time.timeOfDayParse("10:30:00.5")HH:mm:ss[.f]
Time.dateTimeParse(text, pattern)any pattern, e.g. "dd/MM/yyyy HH:mm:ss"
Time.utcDateTimeParse("2024-06-15T08:00:00Z")RFC 3339
Time.offsetDateTimeParse("2024-06-15T08:00:00+05:30")RFC 3339
Time.utcOffsetParse("+05:30")offset string
import Time;

let dt = Time.dateTimeParse("25/12/2023 23:59:59", "dd/MM/yyyy HH:mm:ss");
print(dt.year()); // 2023

let utc = Time.utcDateTimeParse("2024-01-01T00:00:00Z");
print(utc.unixSeconds()); // 1704067200

// Round-trip: format then parse with the same pattern
let now = Time.dateTimeNow();
let s = now.format("yyyy-MM-dd HH:mm:ss");
let back = Time.dateTimeParse(s, "yyyy-MM-dd HH:mm:ss");
print(now.eq(back)); // true

Complete example

A small utility that prints the current date/time in a few timezones and measures how long it took.

import Time;

print("--- Time zone report ---");

let start = Time.instantNow();

let utc = Time.utcDateTimeNow();
print("UTC :", utc.toRfc3339());

let ist = utc.toOffset(Time.utcOffsetHoursMinutes(5, 30));
print("IST :", ist.toIsoString());

let ny = utc.toZone(Time.timeZoneOf("America/New_York"));
print("New York :", ny.format("yyyy-MM-dd HH:mm:ss XXX"));

let local = Time.dateTimeNow();
print("Local :", local.format("MMMM d, yyyy"));

let elapsed = start.elapsed();
print("Report took:", elapsed.toString());

Notes & edge cases

  • Nanosecond precision: Duration and all "moment" classes store a bigint nanosecond count. Use wholeSeconds() / asSecondsF64() for coarser units.
  • Instant is monotonic (safe for elapsed measurement); SystemTime is wall-clock (can jump with NTP/DST adjustments). Prefer Instant for stopwatch-style timing.
  • Validation: new Date(...) / TimeOfDay validate ranges and throw TimeError (kind() = "InvalidDate" / "InvalidTimeOfDay"). Time.dateYmd and friends are thin aliases — invalid input still throws.
  • addMonths/addYears clamp the day to the target month's last day.
  • Parsers return null on malformed input instead of throwing; dateTimeParse returns null when the pattern doesn't match.
  • Named timezones resolve the DST offset for the specific instant (TimeZone.offsetAt); unknown zone names fall back to UtcOffset(0).
  • Time.sleep/Process.runTimeout accept any Duration (Duration.seconds(n), Duration.milliseconds(n), …).
  • Weekdays are Monday-based internally (0=Monday…6=Sunday); Weekday.numberFromSunday() gives the JS/POSIX-style numbering.
  • Formatting uses the shared time.format engine, so the same tokens work for Date, DateTime, UtcDateTime, OffsetDateTime, and ZonedDateTime.

Source & examples

  • Implementation: src/stdlib/Time.adesh (native backing: time.* builtins)
  • Runnable examples: examples/Libraries/time/ (01_duration20_real_world — duration, instant, date, time-of-day, datetime, utc/offset/zoned datetime, formatting, parsing, period, stopwatch, benchmarking, timezone conversion, real-world)