time::chrono
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 {
time::instant,
loc: locality,
zone: nullable *zone,
daydate: (void | i64),
daytime: (void | i64),
};
type timescale = struct {
name: str,
abbr: str,
convto: *tsconverter,
convfrom: *tsconverter,
};
type timezone = struct {
name: str,
timescale: *timescale,
daylength: time::duration,
zones: []zone,
transitions: []transition,
posix_extend: str,
};
type transition = struct {
when: time::instant,
zoneindex: size,
};
type zone = struct {
zoff: time::duration,
name: str,
abbr: str,
dst: bool,
};
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
type locality = *timezone;
The locality of a moment. Contains information about how to calculate a moment's observed chronological values.
type moment
type moment = struct {
time::instant,
loc: locality,
zone: nullable *zone,
daydate: (void | i64),
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
type timescale = struct {
name: str,
abbr: str,
convto: *tsconverter,
convfrom: *tsconverter,
};
Represents a scale of time; a time standard. See convert.
type timezone
type timezone = struct {
name: str,
timescale: *timescale,
daylength: time::duration,
zones: []zone,
transitions: []transition,
posix_extend: str,
};
A timezone; a political or otherwise theoretical region with a ruleset regarding offsets for calculating localized date/time.
type transition
type transition = struct {
when: time::instant,
zoneindex: size,
};
A timezone transition between two zones.
type zone
type zone = struct {
zoff: time::duration,
name: str,
abbr: str,
dst: bool,
};
A timezone state, with an offset for calculating localized date/time.
type tsconverter
Show undocumented member
type tsconverter = fn(ts: *timescale, i: time::instant) ([]time::instant | void);
Errors
type analytical
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
type discontinuity = !void;
A discontinuity between two timescales caused a one-to-one time::instant conversion to fail.
type error
type error = !(invalid | invalidtzif | tzdberror | discontinuity | analytical);
All possible errors returned from this module.
type invalid
type invalid = !void;
Invalid moment.
type invalidtzif
type invalidtzif = !void;
Invalid TZif data.
type tzdberror
type tzdberror = !(invalidtzif | fs::error | io::error);
Error concerning the Timezone database.
Constants
def EARTH_DAY
def EARTH_DAY: time::duration = 86400 * time::SECOND;
The duration of a day on Earth, in terrestrial (SI) seconds.
def MARS_SOL_MARTIAN
def MARS_SOL_MARTIAN: time::duration = 86400 * time::SECOND;
The duration of a solar day on Mars, in Martian seconds.
def MARS_SOL_TERRESTRIAL
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
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
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
const GPS: locality;
The GPS (Global Positioning System) "Zulu" timezone as a locality.
let LOCAL
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
const MTC: locality;
The MTC (Coordinated Mars Time) "Zulu" timezone as a locality.
let TAI
const TAI: locality;
The TAI (International Atomic Time) "Zulu" timezone as a locality.
let TT
const TT: locality;
The TT (Terrestrial Time) "Zulu" timezone as a locality.
let UTC
const UTC: locality;
The UTC (Coordinated Universal Time) "Zulu" timezone as a locality.
let gps
const gps: timescale;
Global Positioning System Time
Used for GPS coordination. Based on TAI; constant -19 second offset. Continuous (no leap seconds).
let mtc
const mtc: timescale;
Coordinated Mars Time
Used for timekeeping on Mars. Based on TT; constant factor. Continuous (no leap seconds).
let tai
const tai: timescale;
International Atomic Time
The realisation of proper time on Earth's geoid. Continuous (no leap seconds).
let tt
const tt: timescale;
Terrestrial Time
Used for astronomical timekeeping. Based on TAI; constant +32.184 offset. Continuous (no leap seconds).
let utc
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 coincident
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
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
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
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
fn daytime(m: *moment) i64;
Observes a moment's observed time-of-day (amount of daytime progressed in a day) as nanoseconds.
fn diff
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
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
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
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 ozone
fn ozone(m: *moment) zone;
Observes a moment's observed zone.
fn simultaneous
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
fn strerror(err: error) const str;
Converts an error into a human-friendly string. The result may be statically allocated.
fn timezone_free
fn timezone_free(tz: *timezone) void;
Frees a timezone. A locality argument can be passed.
fn tz
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
fn zone_finish(z: *zone) void;
Frees resources associated with a zone.