LEVIATHAN v962456e · 962456eee1

Standard Library

struct DateTime

A point in time, held as milliseconds since 1970-01-01T00:00:00Z.

since 0.1.0-alpha.1linuxwindows

Overview

DateTime is a UTC-only value type; it has no time zone and ignores leap seconds. Create one with DateTime::ofEpochMs from a timestamp, DateTime::now for the current time, or one of the datetime::parse... functions for text. Read calendar fields with year, month, day, hour, minute, second, milli and weekday, move in time with plus, measure with minus, and format with httpDate or iso8601.

Description

DateTime is a small value struct with one field, epochMs: the number of milliseconds since 1970-01-01T00:00:00 UTC. Every DateTime is in UTC; there are no time zones, and leap seconds are ignored (the Unix convention). The calendar conversion uses an integer algorithm with no lookup tables and is correct for dates before 1970 as well as after.

There are two labeled constructors:

  • DateTime::ofEpochMs(ms) builds the instant from a millisecond count. It is the constructor to use whenever the instant must be reproducible.
  • DateTime::now() reads the system clock. A program that calls it prints a different value on every run, so the examples on this page never do.

To build an instant from calendar fields, pass them to datetime::epochFromCivil(year, month, day, hour, minute, second, milli) and wrap the result in DateTime::ofEpochMs.

The accessors year(), month() (1 to 12), day(), hour(), minute(), second() and milli() read the calendar fields; weekday() returns 0 for Sunday through 6 for Saturday. plus(Duration) moves the instant and minus(DateTime) returns the Duration between two instants (negative when the argument is later).

httpDate() formats the instant as an RFC 7231 date (Sun, 06 Nov 1994 08:49:37 GMT), and iso8601() formats it as an ISO 8601 UTC timestamp with second precision, adding a .mmm fraction only when the milliseconds are non-zero. The matching fallible parsers are the free functions datetime::parseHttpDate and datetime::parseIso8601, which return None for malformed text.

Fields and formatting of a fixed instant

DateTime u = DateTime::ofEpochMs(784111777000);
console.writeln("${u.year()}-${u.month()}-${u.day()} ${u.hour()}:${u.minute()}:${u.second()}");
console.writeln("weekday ${u.weekday()}");
console.writeln(u.httpDate());
console.writeln(u.iso8601());
DateTime v = DateTime::ofEpochMs(datetime::epochFromCivil(2024, 2, 29, 23, 59, 58, 250));
console.writeln(v.iso8601());
console.writeln(v.httpDate());
1994-11-6 8:49:37
weekday 0
Sun, 06 Nov 1994 08:49:37 GMT
1994-11-06T08:49:37Z
2024-02-29T23:59:58.250Z
Thu, 29 Feb 2024 23:59:58 GMT

Rules

  • A DateTime is a value: plus and minus return new values and never change the receiver.
  • epochMs may be negative. DateTime::ofEpochMs(0 - 1).iso8601() is 1969-12-31T23:59:59.999Z, and the time-of-day accessors always report a value inside the day.
  • httpDate() always uses English day and month abbreviations and the literal zone GMT.
  • iso8601() always ends in Z.

Examples

Arithmetic across a leap day

DateTime a = DateTime::ofEpochMs(datetime::epochFromCivil(2024, 2, 28, 12, 0, 0, 0));
DateTime b = a.plus(Duration::ofDays(2));
console.writeln(b.iso8601());
Duration gap = b.minus(a);
console.writeln(gap.toString());
console.writeln(gap.toMillis());
console.writeln(a.minus(b).toString());
2024-03-01T12:00:00Z
48h00m00s
172800000
-48h00m00s

Instants before 1970

DateTime t = DateTime::ofEpochMs(0 - 1);
console.writeln(t.iso8601());
console.writeln(t.weekday());
console.writeln(DateTime::ofEpochMs(0).iso8601());
1969-12-31T23:59:59.999Z
3
1970-01-01T00:00:00Z

Examples

Building, reading, and formatting an instant

DateTime t = DateTime::ofEpochMs(784111777000);
console.writeln(t.iso8601());
console.writeln("${t.year()}/${t.month()}/${t.day()}");
DateTime next = t.plus(Duration::ofHours(24));
console.writeln(next.httpDate());
console.writeln(next.minus(t).toString());
1994-11-06T08:49:37Z
1994/11/6
Mon, 07 Nov 1994 08:49:37 GMT
24h00m00s

Constructors

now

DateTime::now()

Create a date-time holding the current wall-clock time.

Two calls give different values, so the result depends on when the program runs.

Examples

DateTime start = DateTime::now();
// ... do some work ...
DateTime end = DateTime::now();
Duration elapsed = end.minus(start);
console.writeln(elapsed.toString());
not run — reads the system clock

ofEpochMs

DateTime::ofEpochMs(int e)

Create a date-time from a count of milliseconds since the Unix epoch.

Parameters

e
Milliseconds since 1970-01-01T00:00:00Z; negative for earlier instants.

Examples

DateTime epoch = DateTime::ofEpochMs(0);
console.writeln(epoch.iso8601());
DateTime before = DateTime::ofEpochMs(0 - 1);
console.writeln(before.iso8601());
1970-01-01T00:00:00Z
1969-12-31T23:59:59.999Z

Fields

epochMs

int epochMs

The instant as milliseconds since 1970-01-01T00:00:00Z. It is negative for instants before 1970.

Methods

day

day() -> int

Get the day of the month.

Returns

The day from 1 to 31.

Examples

DateTime t = DateTime::ofEpochMs(784111777000);
console.writeln(t.day());
6

See also: month

hour

hour() -> int

Get the hour of the day in UTC.

Returns

The hour from 0 to 23.

Examples

DateTime t = DateTime::ofEpochMs(784111777000);
console.writeln(t.hour());
8

See also: minute

httpDate

httpDate() -> string

Format as an HTTP date.

The result is the fixed-length form used in HTTP headers, for example Sun, 06 Nov 1994 08:49:37 GMT. Milliseconds are dropped.

Returns

The formatted text.

Examples

DateTime t = DateTime::ofEpochMs(784111777000);
console.writeln(t.httpDate());
console.writeln(DateTime::ofEpochMs(0).httpDate());
Sun, 06 Nov 1994 08:49:37 GMT
Thu, 01 Jan 1970 00:00:00 GMT

See also: parseHttpDate

iso8601

iso8601() -> string

Format as an ISO 8601 UTC timestamp.

The result looks like 1994-11-06T08:49:37Z. A dot and three digits of milliseconds are added only when the milliseconds are not zero.

Returns

The formatted text.

Examples

console.writeln(DateTime::ofEpochMs(784111777000).iso8601());
console.writeln(DateTime::ofEpochMs(784111777123).iso8601());
1994-11-06T08:49:37Z
1994-11-06T08:49:37.123Z

See also: parseIso8601

milli

milli() -> int

Get the millisecond within the second.

Returns

The millisecond from 0 to 999.

Examples

DateTime t = DateTime::ofEpochMs(784111777123);
console.writeln(t.milli());
123

See also: second

minus

minus(DateTime o) -> Duration

Measure the time elapsed since another date-time.

The result is negative when o is later than this one.

Parameters

o
The earlier instant to measure from.

Returns

The length of time from o to this date-time.

Examples

DateTime a = DateTime::ofEpochMs(784111777000);
DateTime b = a.plus(Duration::ofSeconds(90));
console.writeln(b.minus(a).toString());
console.writeln(a.minus(b).toString());
1m30s
-1m30s

See also: plus

minute

minute() -> int

Get the minute of the hour.

Returns

The minute from 0 to 59.

Examples

DateTime t = DateTime::ofEpochMs(784111777000);
console.writeln(t.minute());
49

See also: second

month

month() -> int

Get the month of the year.

Returns

The month from 1 (January) to 12 (December).

Examples

DateTime t = DateTime::ofEpochMs(784111777000);
console.writeln(t.month());
11

See also: year

plus

plus(Duration d) -> DateTime

Move forward in time by a duration.

A negative duration moves backward.

Parameters

d
The amount of time to add.

Returns

A new date-time; this one does not change.

Examples

DateTime t = DateTime::ofEpochMs(784111777000);
console.writeln(t.plus(Duration::ofHours(24)).iso8601());
console.writeln(t.plus(Duration::ofMinutes(0 - 30)).iso8601());
1994-11-07T08:49:37Z
1994-11-06T08:19:37Z

See also: minus

second

second() -> int

Get the second of the minute.

Returns

The second from 0 to 59.

Examples

DateTime t = DateTime::ofEpochMs(784111777000);
console.writeln(t.second());
37

See also: milli

weekday

weekday() -> int

Get the day of the week.

Returns

0 for Sunday through 6 for Saturday.

Examples

DateTime t = DateTime::ofEpochMs(784111777000);
console.writeln(t.weekday());
console.writeln(datetime::weekdayName(t.weekday()));
0
Sun

See also: weekdayName

year

year() -> int

Get the calendar year.

Returns

The year, for example 1994.

Examples

DateTime t = DateTime::ofEpochMs(784111777000);
console.writeln(t.year());
1994

See also: month

See also

  • Duration — A length of time, stored as a whole number of milliseconds.
  • datetime — Calendar arithmetic and date parsing for UTC timestamps.