time::chrono+x86_64 +linux

The time::chrono module provides timescale utilities, and the foundations for chronology with the moment type, an abstract, extendable date/time object. For the Gregorian chronology, see the time::date:: module.

Hare defines a chronology as a system for naming and ordering moments in time. In practice, it is the combination of a calendar and wall clock. This module implements a simple date & time chronology with moment, which observes certain chronological values according to its locality. The observer functions daydate, daytime, and mzone obtain these values. Use in to localize a moment to another locality; consult tz.

The timescale interface facilitates leap-second aware convertion of time::instants. The tai timescale is the default intermediary timescale.

Index

Types

type locality = *timezone;
type moment = struct {
	// The embedded [[time::instant]].
	time::instant,
	// The [[locality]] with which to interpret this moment.
	loc: locality,
	// The observed [[zone]].
	zone: nullable *zone,
	// The observed daydate (scalar day number)
	// since an abitrary epoch (e.g. the Unix epoch 1970-01-01).
	daydate: (void | i64),
	// The observed time-of-day (amount of daytime progressed in a day)
	// as nanoseconds.
	daytime: (void | i64),
};
type timescale = struct {
	name: str,
	abbr: str,
	convto: *tsconverter,
	convfrom: *tsconverter,
};
type timezone = struct {
	// The textual identifier ("Europe/Amsterdam")
	name: str,
	// The base timescale (time::chrono::utc)
	timescale: *timescale,
	// The duration of a day in this timezone (24 * time::HOUR)
	daylength: time::duration,
	// The possible temporal zones a locality with this timezone can observe
	// (CET, CEST, ...)
	zones: []zone,
	// The transitions between this timezone's zones
	transitions: []transition,
	// A timezone specifier in the POSIX "expanded" TZ format.
	// See https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html
	//
	// Used for extending calculations beyond the last known transition.
	posix_extend: str,
};
type transition = struct {
	when: time::instant,
	zoneindex: int,
};
type zone = struct {
	// The offset from the normal timezone (2 * time::HOUR)
	zoff: time::duration,
	// The full descriptive name ("Central European Summer Time")
	name: str,
	// The abbreviated name ("CEST")
	abbr: str,
	// Indicator of Daylight Saving Time
	dst: bool,
};

// Undocumented types:
type tsconverter = fn(ts: *timescale, i: time::instant) ([]time::instant | void);

Errors

type analytical = ![]time::instant;
type discontinuity = !void;
type error = !(invalid | invalidtzif | tzdberror | discontinuity | analytical);
type invalid = !void;
type invalidtzif = !void;
type tzdberror = !(invalidtzif | fs::error | io::error);

Constants

def EARTH_DAY: time::duration = 86400 * time::SECOND;
def MARS_SOL_MARTIAN: time::duration = 86400 * time::SECOND;
def MARS_SOL_TERRESTRIAL: time::duration = 88775244147000 * time::NANOSECOND;
def SECS_1900_1970: i64 = 2208988800;
def UTC_LEAPSECS_PATH: str = "/usr/share/zoneinfo/leap-seconds.list";

Globals

const GPS: locality;
const LOCAL: locality;
const MTC: locality;
const TAI: locality;
const TT: locality;
const UTC: locality;
const gps: timescale;
const mtc: timescale;
const tai: timescale;
const tt: timescale;
const utc: timescale;

Functions

fn add(m: *moment, x: time::duration) moment;
fn coincident(a: *moment, b: *moment) bool;
fn compare(a: *moment, b: *moment) (i8 | discontinuity);
fn convert(i: time::instant, tscs: *timescale...) (time::instant | analytical);
fn daydate(m: *moment) i64;
fn daytime(m: *moment) i64;
fn diff(a: *moment, b: *moment) (time::duration | discontinuity);
fn fixedzone(ts: *timescale, daylen: time::duration, z: zone) timezone;
fn from_datetime(loc: locality, zo: time::duration, dd: i64, dt: i64) moment;
fn in(loc: locality, m: moment) (moment | discontinuity);
fn new(loc: locality, i: time::instant) moment;
fn ozone(m: *moment) zone;
fn simultaneous(a: *moment, b: *moment) (bool | discontinuity);
fn strerror(err: error) const str;
fn timezone_free(tz: *timezone) void;
fn tz(name: str) (locality | tzdberror);
fn zone_finish(z: *zone) void;

Types

type locality[link]

type locality = *timezone;

The locality of a moment. Contains information about how to calculate a moment's observed chronological values.

type moment[link]

type moment = struct {
	// The embedded [[time::instant]].
	time::instant,
	// The [[locality]] with which to interpret this moment.
	loc: locality,
	// The observed [[zone]].
	zone: nullable *zone,
	// The observed daydate (scalar day number)
	// since an abitrary epoch (e.g. the Unix epoch 1970-01-01).
	daydate: (void | i64),
	// The observed time-of-day (amount of daytime progressed in a day)
	// as nanoseconds.
	daytime: (void | i64),
};

A moment in time within a locality. Create one with new. This type extends the time::instant type and couples it with a timescale via its locality field.

This object should be treated as private and immutable. Directly mutating its fields causes undefined behavour when used with module functions. Likewise, interrogating the fields' type and value (e.g. using match statements) is also improper.

Moments observe a daydate, time-of-day, and zone, which are evaluated, cached and obtained with the observer functions daydate, daytime, and ozone. These values are derived from the embedded instant and locality information, and thus are guaranteed to be valid.

type timescale[link]

type timescale = struct {
	name: str,
	abbr: str,
	convto: *tsconverter,
	convfrom: *tsconverter,
};

Represents a scale of time; a time standard. See convert.

type timezone[link]

type timezone = struct {
	// The textual identifier ("Europe/Amsterdam")
	name: str,
	// The base timescale (time::chrono::utc)
	timescale: *timescale,
	// The duration of a day in this timezone (24 * time::HOUR)
	daylength: time::duration,
	// The possible temporal zones a locality with this timezone can observe
	// (CET, CEST, ...)
	zones: []zone,
	// The transitions between this timezone's zones
	transitions: []transition,
	// A timezone specifier in the POSIX "expanded" TZ format.
	// See https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html
	//
	// Used for extending calculations beyond the last known transition.
	posix_extend: str,
};

A timezone; a political or otherwise theoretical region with a ruleset regarding offsets for calculating localized date/time.

type transition[link]

type transition = struct {
	when: time::instant,
	zoneindex: int,
};

A timezone transition between two zones.

type zone[link]

type zone = struct {
	// The offset from the normal timezone (2 * time::HOUR)
	zoff: time::duration,
	// The full descriptive name ("Central European Summer Time")
	name: str,
	// The abbreviated name ("CEST")
	abbr: str,
	// Indicator of Daylight Saving Time
	dst: bool,
};

A timezone state, with an offset for calculating localized date/time.

type tsconverter[link]

Show undocumented member
type tsconverter = fn(ts: *timescale, i: time::instant) ([]time::instant | void);

Errors

type analytical[link]

type analytical = ![]time::instant;

The analytical result of a time::instant conversion between two timescales at a point of discontinuity.

An empty slice represents a nonexistent conversion result. A populated (>1) slice represents an ambiguous conversion result.

type discontinuity[link]

type discontinuity = !void;

A discontinuity between two timescales caused a one-to-one time::instant conversion to fail.

type error[link]

type error = !(invalid | invalidtzif | tzdberror | discontinuity | analytical);

All possible errors returned from this module.

type invalid[link]

type invalid = !void;

Invalid moment.

type invalidtzif[link]

type invalidtzif = !void;

Invalid TZif data.

type tzdberror[link]

type tzdberror = !(invalidtzif | fs::error | io::error);

Error concerning the Timezone database.

Constants

def EARTH_DAY[link]

def EARTH_DAY: time::duration = 86400 * time::SECOND;

The duration of a day on Earth, in terrestrial (SI) seconds.

def MARS_SOL_MARTIAN[link]

def MARS_SOL_MARTIAN: time::duration = 86400 * time::SECOND;

The duration of a solar day on Mars, in Martian seconds.

def MARS_SOL_TERRESTRIAL[link]

def MARS_SOL_TERRESTRIAL: time::duration = 88775244147000 * time::NANOSECOND;

The duration of a solar day on Mars, in terrestrial (SI) seconds.

def SECS_1900_1970[link]

def SECS_1900_1970: i64 = 2208988800;

The number of seconds between the years 1900 and 1970.

This number is hypothetical since timekeeping before atomic clocks was not accurate enough to account for small changes in time.

def UTC_LEAPSECS_PATH[link]

def UTC_LEAPSECS_PATH: str = "/usr/share/zoneinfo/leap-seconds.list";

The filepath of the system's "leap-seconds.list" file, which contains UTC/TAI leap second data.

Globals

let GPS[link]

const GPS: locality;

The GPS (Global Positioning System) "Zulu" timezone as a locality.

let LOCAL[link]

const LOCAL: locality;

The local locality; the system or environment configured timezone.

This is set during the program's initialization. In order of preference, the TZ environment variable is used, if set; the file at LOCALTIME_PATH, if present; or, as a last resort, UTC is used as a default.

let MTC[link]

const MTC: locality;

The MTC (Coordinated Mars Time) "Zulu" timezone as a locality.

let TAI[link]

const TAI: locality;

The TAI (International Atomic Time) "Zulu" timezone as a locality.

let TT[link]

const TT: locality;

The TT (Terrestrial Time) "Zulu" timezone as a locality.

let UTC[link]

const UTC: locality;

The UTC (Coordinated Universal Time) "Zulu" timezone as a locality.

let gps[link]

const gps: timescale;

Global Positioning System Time

Used for GPS coordination. Based on TAI; constant -19 second offset. Continuous (no leap seconds).

let mtc[link]

const mtc: timescale;

Coordinated Mars Time

Used for timekeeping on Mars. Based on TT; constant factor. Continuous (no leap seconds).

let tai[link]

const tai: timescale;

International Atomic Time

The realisation of proper time on Earth's geoid. Continuous (no leap seconds).

let tt[link]

const tt: timescale;

Terrestrial Time

Used for astronomical timekeeping. Based on TAI; constant +32.184 offset. Continuous (no leap seconds).

let utc[link]

const utc: timescale;

Coordinated Universal Time

Used as the basis of civil timekeeping. Based on TAI; time-dependent offset. Discontinuous (has leap seconds).

During a program's initialization, this timescale initializes by loading its UTC/TAI leap second data from UTC_LEAPSECS_PATH; otherwise, fails silently. If failed, any attempt to consult UTC leapsec data (e.g. calling convert on UTC) causes an abort. This includes in.

Functions

fn add[link]

fn add(m: *moment, x: time::duration) moment;

Adds a time::duration to a moment with time::add.

fn coincident[link]

fn coincident(a: *moment, b: *moment) bool;

Returns true if two moments represent the same time in the same locality, which is to say that their locality and time::instant are both equal. Their observed values and representations in a chronology should be the same in all cases.

See simultaneous to determine if two moments represent the same moment in time regardless of locality.

fn compare[link]

fn compare(a: *moment, b: *moment) (i8 | discontinuity);

Compares two moments. Returns -1 if a precedes b, 0 if a and b are simultaneous, or +1 if b precedes a.

The moments are compared as time::instants; their observed chronological values are ignored.

If the moments' associated timescales are different, they will be converted to tai instants first. Any discontinuity occurence will be returned. If a discontinuity against TAI amongst the two timescales exist, consider converting such instants manually.

fn convert[link]

fn convert(i: time::instant, tscs: *timescale...) (time::instant | analytical);

Converts a time::instant from one timescale to the next exhaustively. The final conversion result is returned. For each active pair of timescales, if neither implements conversion from the first to the second, a two-step intermediary TAI conversion will occur. If given zero or one timescales, the given instant is returned.

fn daydate[link]

fn daydate(m: *moment) i64;

Observes a moment's observed daydate (day number since epoch).

For moments with localitys based on the utc, tai, gps, and similar timescales, their epoch date should be interpreted as the Unix epoch (1970 Janurary 1st). Other timescales may suggest their own interpretations applicable to other chronologies.

fn daytime[link]

fn daytime(m: *moment) i64;

Observes a moment's observed time-of-day (amount of daytime progressed in a day) as nanoseconds.

fn diff[link]

fn diff(a: *moment, b: *moment) (time::duration | discontinuity);

Returns the time::duration between two moments, from a to b.

The moments are compared as time::instants; their observed chronological values are ignored.

If the moments' associated timescales are different, they will be converted to tai instants first. Any discontinuity occurence will be returned. If a discontinuity against TAI amongst the two timescales exist, consider converting such instants manually.

fn fixedzone[link]

fn fixedzone(ts: *timescale, daylen: time::duration, z: zone) timezone;

Creates a timezone with a single zone. Useful for fixed offsets. For example, replicate the civil time Hawaii timezone on Earth:

let hawaii = chrono::fixedzone(&chrono::utc, chrono::EARTH_DAY,
	chrono::zone {
		zoff = -10 * time::HOUR,
		name = "Hawaiian Reef",
		abbr = "HARE",
		dst = false,
	},
);

fn from_datetime[link]

fn from_datetime(loc: locality, zo: time::duration, dd: i64, dt: i64) moment;

Creates a moment from a given locality, zone offset, daydate, and time-of-day.

fn in[link]

fn in(loc: locality, m: moment) (moment | discontinuity);

Creates an equivalent moment with a different locality.

If the moment's associated timescale and the target locality's timescale are different, a conversion from one to the other via the TAI timescale will be attempted. Any discontinuity occurrence will be returned. If a discontinuity against TAI amongst the two timescales exist, consider converting such instants manually.

fn new[link]

fn new(loc: locality, i: time::instant) moment;

Creates a new moment. Uses a given time::instant with a timescale associated with a given locality.

fn ozone[link]

fn ozone(m: *moment) zone;

Observes a moment's observed zone.

fn simultaneous[link]

fn simultaneous(a: *moment, b: *moment) (bool | discontinuity);

Returns true if two moments represent the same moment in time, regardless of locality.

The moments are compared as time::instants; their observed chronological values and representations are ignored.

If the moments' associated timescales are different, they will be converted to tai instants first. Any discontinuity occurence will be returned. If a discontinuity against TAI amongst the two timescales exist, consider converting such instants manually.

See coincident to determine if two moments are equal with respect to both time and locality.

fn strerror[link]

fn strerror(err: error) const str;

Converts an error into a human-friendly string. The result may be statically allocated.

fn timezone_free[link]

fn timezone_free(tz: *timezone) void;

Frees a timezone. A locality argument can be passed.

fn tz[link]

fn tz(name: str) (locality | tzdberror);

Finds, loads, and allocates a timezone from the system's Timezone database (TZDB), and returns it as a locality. Each call returns a new instance. The caller must free the return value; see timezone_free.

The system TZDB is normally located at TZDB_PATH. The timezone filepath is resolved by appending the name argument to this prefix path. If [name] is a full filepath (begins with '/'), it is used directly instead.

All localities returned default to the utc timescale and EARTH_DAY day-length.

fn zone_finish[link]

fn zone_finish(z: *zone) void;

Frees resources associated with a zone.