time::date+x86_64 +linux

The time::date module implements the common international Gregorian chronology, based on the astronomically numbered proleptic Gregorian calendar and the ISO week-numbering calendar, as per the ISO 8601 standard, and the common 24 hour clock. It provides date, a representation of civil date/time and a optimized extension of the time::chrono::moment type. The time::chrono:: module has many useful functions which interoperate with dates. Any time::chrono:: function which accepts *moment also accepts *date.

Dates are created using new, now, localnow, or a "from_" function. Alternatively, the virtual/realize interface can handle uncertain or invalid date/time information, and construct new dates incrementally and safely. The observer functions (year, hour, etc.) evaluate a date's observed chronological values, adjusted for its associated time::chrono::locality. Use in to localize a date to another locality; consult time::chrono::tz. See parse and format for working with date/time strings.

Date arithmetic operations are categorized into "timescalar" or "chronological". Timescalar uses time::duration; see add, time::chrono::diff. Chronological uses period; see reckon, pdiff, unitdiff, truncate. Note that calendrical arithmetic is highly irregular due to field overflows and timezone discontinuities, so think carefully about what you want.

Index

Types

type date = struct {
	chrono::moment,
	era: (void | int),
	year: (void | int),
	month: (void | int),
	day: (void | int),
	yearday: (void | int),
	isoweekyear: (void | int),
	isoweek: (void | int),
	week: (void | int),
	sundayweek: (void | int),
	weekday: (void | int),
	hour: (void | int),
	minute: (void | int),
	second: (void | int),
	nanosecond: (void | int),
};
type period = struct {
	years: i64,
	months: i64,
	weeks: i64,
	days: i64,
	hours: i64,
	minutes: i64,
	seconds: i64,
	nanoseconds: i64,
};
type rflag = enum uint {
	DEFAULT = 0, // The default behaviour. Equivalent to CEIL.
	REVSIG = 1 << 0, // Apply units in reverse order, from least to most significant.
	// When a sub-significant overflow occurs, the unresolved field is set
	// to its minimum valid value.
	//
	//     Feb 31 -> Feb 01
	//     Aug 64 -> Aug 01
	FLOOR = 1 << 1,
	// When a sub-significant overflow occurs, the unresolved field is set
	// to its maximum valid value.
	//
	//     Feb 31 -> Feb 28 / Feb 29   (leap year dependent)
	//     Aug 64 -> Aug 31
	CEIL = 1 << 2,
	// When a sub-significant overflow occurs, the unresolved field is set
	// to its new minimum valid value after the next super-significant field
	// increments by one.
	//
	//     Feb 31 -> Mar 01
	//     Aug 64 -> Sep 01
	HOP = 1 << 3,
	// When a sub-significant overflow occurs, the unresolved field's
	// maximum valid value is subtracted from it's current value, and the
	// next super-significant field increments by one. This process repeats
	// until the unresolved field's value becomes valid (falls in range).
	//
	//     Feb 31 -> Mar 03 / Mar 02   (leap year dependent)
	//     Aug 64 -> Sep 33 -> Oct 03
	FOLD = 1 << 4,
};
type unit = enum {
	ERA,
	YEAR,
	MONTH,
	WEEK,
	DAY,
	HOUR,
	MINUTE,
	SECOND,
	NANOSECOND,
};
type virtual = struct {
	date,
	// virtual's timescalar second
	vsec: (void | i64),
	// virtual's nanosecond of timescalar second
	vnsec: (void | i64),
	// virtual's locality
	vloc: (void | chrono::locality),
	// locality name
	locname: (void | str),
	// zone offset
	zoff: (void | time::duration | zflag),
	// zone abbreviation
	zabbr: (void | str),
	// all but the last two digits of the year
	century: (void | int),
	// the last two digits of the year
	year100: (void | int),
	// hour of 12 hour clock
	hour12: (void | int),
	// AM/PM (false/true)
	ampm: (void | bool),
};
type zflag = enum u8 {
	// Assume a contiguous chronology with no observed gaps or overlaps.
	// Upon encountering an observed gap or overlap, fail with [[invalid]].
	// In other words, accept one and only one zone-offset.
	CONTIG = 0,
	// Upon encountering an observed overlap, select the earliest possible
	// date (Fig A "f") using the most positive (eastmost) zone-offset.
	LAP_EARLY = 1,
	// Upon encountering an observed overlap, select the latest possible
	// date (Fig A "g") using the most negative (westmost) zone-offset.
	LAP_LATE = 2,
	// Upon encountering an observed gap, disregard the specified date and
	// select the date at the start boundary of the observed gap (Fig B
	// "gp"), corresponding to the contiguous time just before the
	// transition (Fig B "tx").
	GAP_START = 4,
	// Upon encountering an observed gap, disregard the specified date and
	// select the date at the end boundary of the observed gap (Fig B "gq"),
	// corresponding to the contiguous time at the transition (Fig B "tx").
	GAP_END = 8,
};

// Undocumented types:
type lack = enum u8 {
	LOCALITY = 1 << 0, // could not deduce locality
	DAYDATE = 1 << 1, // could not deduce daydate
	DAYTIME = 1 << 2, // could not deduce time-of-day
	ZOFF = 1 << 3, // could not deduce zone offset
};

Errors

type error = !(insufficient | invalid | zfunresolved | parsefail);
type insufficient = !lack;
type invalid = !chrono::invalid;
type parsefail = !(size, rune);
type zfunresolved = !bool;

Constants

def APRIL: int = 4;
def AUGUST: int = 8;
def DECEMBER: int = 12;
def EMAIL: str = "%a, %d %b %Y %H:%M:%S %z";
def EMAILZONE: str = "%a, %d %b %Y %H:%M:%S %z %Z";
def EPOCHDAY_GREGORIAN: i64 = -719164;
def EPOCHDAY_JULIAN: i64 = -2440588;
def FEBRUARY: int = 2;
def FRIDAY: int = 4;
def ISOWKSTAMP: str = "%G-W%V-%u %H:%M:%S";
def JANUARY: int = 1;
def JOURNAL: str = "%Y %b %d, %a %H:%M:%S %z %Z %L";
def JULY: int = 7;
def JUNE: int = 6;
def MARCH: int = 3;
def MAY: int = 5;
def MONDAY: int = 0;
def NOVEMBER: int = 11;
def OCTOBER: int = 10;
def POSIX: str = "%a %b %e %H:%M:%S %Y";
def QUARTZ: str = "%s.%N";
def QUARTZLOC: str = "%s.%N:%L";
def QUARTZZOFF: str = "%s.%N%z";
def RFC3339: str = "%Y-%m-%dT%H:%M:%S%z";
def SATURDAY: int = 5;
def SEPTEMBER: int = 9;
def STAMP: str = "%Y-%m-%d %H:%M:%S";
def STAMPLOC: str = "%Y-%m-%d %H:%M:%S.%N %z %Z %L";
def STAMPNANO: str = "%Y-%m-%d %H:%M:%S.%N";
def STAMPZOFF: str = "%Y-%m-%d %H:%M:%S.%N %z";
def STAMPZONE: str = "%Y-%m-%d %H:%M:%S.%N %z %Z";
def SUNDAY: int = 6;
def THURSDAY: int = 3;
def TUESDAY: int = 1;
def WEDNESDAY: int = 2;
def WRIST: str = "%b-%d %a %H:%M %Z";

Functions

fn abs(p: period) period;
fn add(d: date, x: time::duration) date;
fn asformat(layout: str, d: *date) (str | io::error);
fn bsformat(buf: []u8, layout: str, d: *date) (str | io::error);
fn day(d: *date) int;
fn era(d: *date) int;
fn format(h: io::handle, layout: str, d: *date) (size | io::error);
fn from_instant(loc: chrono::locality, i: time::instant) date;
fn from_moment(m: chrono::moment) date;
fn from_str(layout: str, s: str, locs: chrono::locality...) (date | parsefail | insufficient | invalid);
fn hour(d: *date) int;
fn in(loc: chrono::locality, d: date) (date | chrono::discontinuity);
fn isleapyear(y: int) bool;
fn isoweek(d: *date) int;
fn isoweekyear(d: *date) int;
fn localnow() date;
fn minute(d: *date) int;
fn month(d: *date) int;
fn nanosecond(d: *date) int;
fn neg(p: period) period;
fn new(loc: chrono::locality, zoff: (time::duration | zflag), fields: int...) (date | invalid | zfunresolved);
fn newvirtual() virtual;
fn now() date;
fn parse(v: *virtual, layout: str, s: str) (void | parsefail);
fn pdiff(a: date, b: date) period;
fn peq(pa: period, pb: period) bool;
fn realize(v: virtual, locs: chrono::locality...) (date | insufficient | invalid | zfunresolved);
fn reckon(d: date, zoff: (time::duration | zflag), rf: rflag, ps: period...) (date | invalid | zfunresolved);
fn second(d: *date) int;
fn strerror(err: error) const str;
fn sum(ps: period...) period;
fn sundayweek(d: *date) int;
fn truncate(d: date, zf: zflag, u: unit) (date | invalid | zfunresolved);
fn unitdiff(a: date, b: date, u: unit) i64;
fn week(d: *date) int;
fn weekday(d: *date) int;
fn year(d: *date) int;
fn yearday(d: *date) int;

Types

type date[link]

type date = struct {
	chrono::moment,
	era: (void | int),
	year: (void | int),
	month: (void | int),
	day: (void | int),
	yearday: (void | int),
	isoweekyear: (void | int),
	isoweek: (void | int),
	week: (void | int),
	sundayweek: (void | int),
	weekday: (void | int),
	hour: (void | int),
	minute: (void | int),
	second: (void | int),
	nanosecond: (void | int),
};

A date/time object; a time::chrono::moment wrapper optimized for the Gregorian chronology, and by extension a time::instant wrapper.

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

A date observes various chronological values, cached in its fields. To evaluate and obtain these values, use the various observer functions (year, hour, etc.). These values are derived from the embedded moment information, and thus are guaranteed to be valid.

See virtual for an public, mutable, intermediary representation of a date, which waives guarantees of validity.

type period[link]

type period = struct {
	years: i64,
	months: i64,
	weeks: i64,
	days: i64,
	hours: i64,
	minutes: i64,
	seconds: i64,
	nanoseconds: i64,
};

Represents a span of time in the Gregorian chronology, using nominal units of time. Used for chronological arithmetic.

type rflag[link]

type rflag = enum uint {
	DEFAULT = 0, // The default behaviour. Equivalent to CEIL.
	REVSIG = 1 << 0, // Apply units in reverse order, from least to most significant.
	// When a sub-significant overflow occurs, the unresolved field is set
	// to its minimum valid value.
	//
	//     Feb 31 -> Feb 01
	//     Aug 64 -> Aug 01
	FLOOR = 1 << 1,
	// When a sub-significant overflow occurs, the unresolved field is set
	// to its maximum valid value.
	//
	//     Feb 31 -> Feb 28 / Feb 29   (leap year dependent)
	//     Aug 64 -> Aug 31
	CEIL = 1 << 2,
	// When a sub-significant overflow occurs, the unresolved field is set
	// to its new minimum valid value after the next super-significant field
	// increments by one.
	//
	//     Feb 31 -> Mar 01
	//     Aug 64 -> Sep 01
	HOP = 1 << 3,
	// When a sub-significant overflow occurs, the unresolved field's
	// maximum valid value is subtracted from it's current value, and the
	// next super-significant field increments by one. This process repeats
	// until the unresolved field's value becomes valid (falls in range).
	//
	//     Feb 31 -> Mar 03 / Mar 02   (leap year dependent)
	//     Aug 64 -> Sep 33 -> Oct 03
	FOLD = 1 << 4,
};

Specifies the behaviour of reckon when doing chronological arithmetic.

The FLOOR, CEIL, HOP, and FOLD specifies how to resolve sub-significant overflows -- when a field's change in value causes any sub-significant field's range to shrink below its current value and become invalid. For example, adding 1 month to January 31st results in February 31st, a date with an unresolved day field, since February permits only 28 or 29 days.

type unit[link]

type unit = enum {
	ERA,
	YEAR,
	MONTH,
	WEEK,
	DAY,
	HOUR,
	MINUTE,
	SECOND,
	NANOSECOND,
};

The nominal units of the Gregorian chronology. Used for chronological arithmetic.

type virtual[link]

type virtual = struct {
	date,
	// virtual's timescalar second
	vsec: (void | i64),
	// virtual's nanosecond of timescalar second
	vnsec: (void | i64),
	// virtual's locality
	vloc: (void | chrono::locality),
	// locality name
	locname: (void | str),
	// zone offset
	zoff: (void | time::duration | zflag),
	// zone abbreviation
	zabbr: (void | str),
	// all but the last two digits of the year
	century: (void | int),
	// the last two digits of the year
	year100: (void | int),
	// hour of 12 hour clock
	hour12: (void | int),
	// AM/PM (false/true)
	ampm: (void | bool),
};

A virtual date; a date wrapper interface, which represents a date of uncertain validity. Its fields need not be valid observed chronological values. It is meant as an intermediary container for date information to be resolved with the realize function.

Unlike date, a virtual date's fields are meant to be treated as public and mutable. The embedded time::instant and time::chrono::locality fields (.sec .nsec .loc) are considered meaningless. Behaviour with the observer functions is undefined.

This can be used to safely construct a new date piece-by-piece. Start with newvirtual, then collect enough date/time information incrementally by direct field assignments and/or with parse. Finish with realize.

let v = date::newvirtual();
v.vloc = chrono::tz("Europe/Amsterdam")!;
v.zoff = date::zflag::LAP_EARLY | date::zflag::GAP_END;
date::parse(&v, "Date: %Y-%m-%d", "Date: 2000-01-02")!;
v.hour = 15;
v.minute = 4;
v.second = 5;
v.nanosecond = 600000000;
let d = date::realize(v)!;

type zflag[link]

type zflag = enum u8 {
	// Assume a contiguous chronology with no observed gaps or overlaps.
	// Upon encountering an observed gap or overlap, fail with [[invalid]].
	// In other words, accept one and only one zone-offset.
	CONTIG = 0,
	// Upon encountering an observed overlap, select the earliest possible
	// date (Fig A "f") using the most positive (eastmost) zone-offset.
	LAP_EARLY = 1,
	// Upon encountering an observed overlap, select the latest possible
	// date (Fig A "g") using the most negative (westmost) zone-offset.
	LAP_LATE = 2,
	// Upon encountering an observed gap, disregard the specified date and
	// select the date at the start boundary of the observed gap (Fig B
	// "gp"), corresponding to the contiguous time just before the
	// transition (Fig B "tx").
	GAP_START = 4,
	// Upon encountering an observed gap, disregard the specified date and
	// select the date at the end boundary of the observed gap (Fig B "gq"),
	// corresponding to the contiguous time at the transition (Fig B "tx").
	GAP_END = 8,
};

Flags for resolving an absent zone-offset. Handles timezone transitions.

The realize function, as well as other date creation functions (like new, truncate, reckon...) accept zflags. If zflags are provided, these functions normally calculate an intermediate date with a best-guess numerical zone-offset. This intermediate date can be invalid if it falls within the observed overlap or gap of a timezone transition, where such dates are ambiguous or nonexistent. In this case, the provided zflags are consulted, and a final calculation takes place before the final resultant date (or zfunresolved) is returned.

Timezone transitions create gaps and overlaps, the two causes of invalid intermediate dates. Passing one "GAP_" and one "LAP_" flag covers both cases.

let zf = date::zflag::LAP_EARLY | date::zflag::GAP_END;
date::new(loc, zf, fields...)!; // will never return [[zfunresolved]]

Note that usage of "GAP_" flags will cause the resultant date to be different to what is originally specified if the intermediate date falls within a gap. Flags with greater value take precedent.

The following figures exist to help understand the effect of these flags.

Fig A                    2000 October 29th
                              -1 hour

                                 f=02:30+0200
                                 g=02:30+0100
                             lp  | lq
                 +0200        |  |  |       +0100
  Observed time: 00    01    02  | 03    04    05
      Amsterdam:  |-----|-----|==*==|-----|-----|
                  .     .     .\ :: |.     .
                  .     .     . \: :| .     .
                  .     .     .  :  :  .     .
                  .     .     .  :\ |:  .     .
                  .     .     .  : \| :  .     .
            UTC:  |-----|-----|--*--|--*--|-----|
Contiguous time: 22    23    00  | 01  | 02    03
                                 |  |  |
                                 a tx  b

Fig A -- A backjump timezone transition in the Europe/Amsterdam locality. The transition is marked by "tx". There is an overlap in the chronology, marked by "lp" and "lq". The specified local time 02:30 falls within the observed overlap, and so has two valid zone-offsets and can be observed twice, as dates "f" and "g". When localized to UTC, these two observations correspond to UTC dates "a" and "b" respectively.

Fig B                     2000 March 26th
                              +1 hour

                                 f~02:30+!!!!
                             gp  | gq
                 +0100        |  |  |       +0200
  Observed time: 00    01    02  | 03    04    05
      Amsterdam:  |-----|-----|  *  |-----|-----|
                  .     .     |    /     .     .
                  .     .     |   /     .     .
                  .     .     |  /     .     .
                  .     .     | /     .     .
                  .     .     |/     .     .
            UTC:  |-----|-----|-----|-----|-----|
Contiguous time: 23    00    01    02    03    04
                              |
                             tx

Fig B -- A forejump timezone transition in the Europe/Amsterdam locality. The transition is marked by "tx". There is a gap in the chronology, marked by "gp" and "gq". The specified local time 02:30 falls within the observed gap, and so cannot be observed and is invalid.

type lack[link]

Show undocumented member
type lack = enum u8 {
	LOCALITY = 1 << 0, // could not deduce locality
	DAYDATE = 1 << 1, // could not deduce daydate
	DAYTIME = 1 << 2, // could not deduce time-of-day
	ZOFF = 1 << 3, // could not deduce zone offset
};

Errors

type error[link]

type error = !(insufficient | invalid | zfunresolved | parsefail);

All possible errors returned from date.

type insufficient[link]

type insufficient = !lack;

A virtual date does not have enough information from which to create a valid date.

type invalid[link]

type invalid = !chrono::invalid;

Invalid date.

type parsefail[link]

type parsefail = !(size, rune);

A parsing error occurred. This shall contain a byteindex of and rune from the layout at the position where the parsing failure occured.

type zfunresolved[link]

type zfunresolved = !bool;

Failed to resolve an absent zone-offset. The provided zflags failed to account for some timezone effect and could not produce a valid zone-offset. A false value signifies the occurence of a timezone transition gap. A true value signifies the occurence of a timezone transition overlap.

Constants

def APRIL[link]

def APRIL: int = 4;

Ordinal for the month of April.

def AUGUST[link]

def AUGUST: int = 8;

Ordinal for the month of August.

def DECEMBER[link]

def DECEMBER: int = 12;

Ordinal for the month of December.

def EMAIL[link]

def EMAIL: str = "%a, %d %b %Y %H:%M:%S %z";

format layout for the email date format.

def EMAILZONE[link]

def EMAILZONE: str = "%a, %d %b %Y %H:%M:%S %z %Z";

format layout for the email date format, with zone offset and zone abbreviation.

def EPOCHDAY_GREGORIAN[link]

def EPOCHDAY_GREGORIAN: i64 = -719164;

The Hare epochal day of the Gregorian Common Era.

def EPOCHDAY_JULIAN[link]

def EPOCHDAY_JULIAN: i64 = -2440588;

The Hare epochal day of the Julian Day Number.

def FEBRUARY[link]

def FEBRUARY: int = 2;

Ordinal for the month of February.

def FRIDAY[link]

def FRIDAY: int = 4;

Ordinal for the weekday Friday.

def ISOWKSTAMP[link]

def ISOWKSTAMP: str = "%G-W%V-%u %H:%M:%S";

format layout for an ISO week-numbering timestamp.

def JANUARY[link]

def JANUARY: int = 1;

Ordinal for the month of January.

def JOURNAL[link]

def JOURNAL: str = "%Y %b %d, %a %H:%M:%S %z %Z %L";

format layout for a friendly, comprehensive datetime.

def JULY[link]

def JULY: int = 7;

Ordinal for the month of July.

def JUNE[link]

def JUNE: int = 6;

Ordinal for the month of June.

def MARCH[link]

def MARCH: int = 3;

Ordinal for the month of March.

def MAY[link]

def MAY: int = 5;

Ordinal for the month of May.

def MONDAY[link]

def MONDAY: int = 0;

Ordinal for the weekday Monday.

def NOVEMBER[link]

def NOVEMBER: int = 11;

Ordinal for the month of November.

def OCTOBER[link]

def OCTOBER: int = 10;

Ordinal for the month of October.

def POSIX[link]

def POSIX: str = "%a %b %e %H:%M:%S %Y";

format layout for the POSIX locale's default date & time representation.

def QUARTZ[link]

def QUARTZ: str = "%s.%N";

format layout for a precise timescalar second and nanosecond.

def QUARTZLOC[link]

def QUARTZLOC: str = "%s.%N:%L";

format layout for a precise timescalar second, nanosecond, and locality.

def QUARTZZOFF[link]

def QUARTZZOFF: str = "%s.%N%z";

format layout for a precise timescalar second, nanosecond, and zone offset.

def RFC3339[link]

def RFC3339: str = "%Y-%m-%dT%H:%M:%S%z";

format layout compatible with RFC 3339.

def SATURDAY[link]

def SATURDAY: int = 5;

Ordinal for the weekday Saturday.

def SEPTEMBER[link]

def SEPTEMBER: int = 9;

Ordinal for the month of September.

def STAMP[link]

def STAMP: str = "%Y-%m-%d %H:%M:%S";

format layout for a standard, collatable timestamp.

def STAMPLOC[link]

def STAMPLOC: str = "%Y-%m-%d %H:%M:%S.%N %z %Z %L";

format layout for a standard, collatable timestamp with nanoseconds, zone offset, zone abbreviation, and locality.

def STAMPNANO[link]

def STAMPNANO: str = "%Y-%m-%d %H:%M:%S.%N";

format layout for a standard, collatable timestamp with nanoseconds.

def STAMPZOFF[link]

def STAMPZOFF: str = "%Y-%m-%d %H:%M:%S.%N %z";

format layout for a standard, collatable timestamp with nanoseconds and zone offset.

def STAMPZONE[link]

def STAMPZONE: str = "%Y-%m-%d %H:%M:%S.%N %z %Z";

format layout for a standard, collatable timestamp with nanoseconds, zone offset, and zone abbreviation.

def SUNDAY[link]

def SUNDAY: int = 6;

Ordinal for the weekday Sunday.

def THURSDAY[link]

def THURSDAY: int = 3;

Ordinal for the weekday Thursday.

def TUESDAY[link]

def TUESDAY: int = 1;

Ordinal for the weekday Tuesday.

def WEDNESDAY[link]

def WEDNESDAY: int = 2;

Ordinal for the weekday Wednesday.

def WRIST[link]

def WRIST: str = "%b-%d %a %H:%M %Z";

format layout for a friendly, terse datetime.

Functions

fn abs[link]

fn abs(p: period) period;

Returns a period with its fields made absolute and positive.

fn add[link]

fn add(d: date, x: time::duration) date;

Adds a time::duration to a date with time::add. This is a timescalar aritmetic operation.

See reckon.

fn asformat[link]

fn asformat(layout: str, d: *date) (str | io::error);

Formats a date and writes it into a heap-allocated string. The caller must free the return value.

fn bsformat[link]

fn bsformat(buf: []u8, layout: str, d: *date) (str | io::error);

Formats a date and writes it into a caller supplied buffer. The returned string is borrowed from this buffer.

fn day[link]

fn day(d: *date) int;

Observes a date's day of the month. Range 1 to 31.

fn era[link]

fn era(d: *date) int;

Observes a date's era.

fn format[link]

fn format(h: io::handle, layout: str, d: *date) (size | io::error);

Formats a date according to a layout and writes to an io::handle.

The layout may contain any of the following format specifiers listed below. These specifiers emit 2 digit zero-padded decimals unless stated otherwise. Use of unimplemented specifiers or an invalid layout will cause an abort.

fn from_instant[link]

fn from_instant(loc: chrono::locality, i: time::instant) date;

Creates a date from a time::instant in a time::chrono::locality.

fn from_moment[link]

fn from_moment(m: chrono::moment) date;

Creates a date from a time::chrono::moment.

fn from_str[link]

fn from_str(layout: str, s: str, locs: chrono::locality...) (date | parsefail | insufficient | invalid);

Creates a date from a string, parsed according to a layout format. See parse and format. Example:

let new = date::from_str(
	date::STAMPLOC,
	"2000-01-02 15:04:05.600000000 +0100 CET Europe/Amsterdam",
	chrono::tz("Europe/Amsterdam")!
)!;

At least a complete calendar date has to be provided. If the hour, minute, second, or nanosecond values are not provided, they default to 0. If the zone-offset or zone-abbreviation are not provided, the zflagss LAP_EARLY and GAP_END are used.

The date's time::chrono::locality will be selected from the provided locality arguments. The 'name' field of these localities will be matched against the parsed result of the %L specifier. If %L is not specified, or if no locality is provided, time::chrono::UTC is used.

fn hour[link]

fn hour(d: *date) int;

Observes a date's hour of the day.

fn in[link]

fn in(loc: chrono::locality, d: date) (date | chrono::discontinuity);

Creates an equivalent date with a different time::chrono::locality.

The time::chrono::discontinuity rules from time::chrono::in apply here.

fn isleapyear[link]

fn isleapyear(y: int) bool;

Calculates whether a year is a leap year.

fn isoweek[link]

fn isoweek(d: *date) int;

Observes a date's ISO week-numbering week. Range 0 to 53.

fn isoweekyear[link]

fn isoweekyear(d: *date) int;

Observes a date's ISO week-numbering year.

fn localnow[link]

fn localnow() date;

Returns a date of the current system time using time::clock::REALTIME, in the time::chrono::LOCAL locality.

fn minute[link]

fn minute(d: *date) int;

Observes a date's minute of the hour.

fn month[link]

fn month(d: *date) int;

Observes a date's month of the year. Range January=1 to December=12.

fn nanosecond[link]

fn nanosecond(d: *date) int;

Observes a date's nanosecond of the second.

fn neg[link]

fn neg(p: period) period;

Returns a period with its fields negated.

fn new[link]

fn new(loc: chrono::locality, zoff: (time::duration | zflag), fields: int...) (date | invalid | zfunresolved);

Creates a new date. Accepts a time::chrono::locality, a zone-offset, and up to seven nominal fields applied in the following order:

8 or more fields causes an abort. If omitted, the month and day default to 1, and the rest default to 0.

If the desired zone-offset is known, it can be given as a time::duration. Otherwise, use a zflag. See zflag on its effects to the result.

An invalid combination of provided date/time/zoff values returns invalid.

Examples:

// 0000-01-01 00:00:00.000000000 +0000 UTC UTC
date::new(time::chrono::UTC, date::zflag::CONTIG);

// 2000-01-02 15:04:05.600000000 +0000 UTC UTC
date::new(time::chrono::UTC, 0,
	2000,  1,  2,  15,  4,  5, 600000000);

// 2000-01-02 15:00:00.000000000 +0100 CET Europe/Amsterdam
date::new(time::chrono::tz("Europe/Amsterdam")!,
	1 * time::HOUR, // standard time in January
	2000,  1,  2,  15);

// Could return [[zfunresolved]] by encountering a timezone transition.
date::new(time::chrono::tz("Europe/Amsterdam")!,
	date::zflag::CONTIG,
	fields...);

// Will never return [[zfunresolved]].
date::new(time::chrono::tz("Europe/Amsterdam")!,
	date::zflag::LAP_EARLY | date::zflag::GAP_END,
	fields...);

// On this day in Amsterdam, the clock jumped +1 hour at 02:00.
// 02:30 is never observed. Note the difference in zone-offset.
//
// 2000-03-26 01:59:59.999999999 +0100 CET Europe/Amsterdam
date::new(time::chrono::tz("Europe/Amsterdam")!,
	date::zflag::GAP_START,
	2000,  3, 26,   2, 30);
//
// 2000-03-26 03:00:00.000000000 +0200 CET Europe/Amsterdam
date::new(time::chrono::tz("Europe/Amsterdam")!,
	date::zflag::GAP_END,
	2000,  3, 26,   2, 30);

// On this day in Amsterdam, the clock jumped -1 hour at 03:00.
// 02:30 is observed twice. Note the difference in zone-offset.
//
// 2000-10-29 02:30:00.000000000 +0200 CET Europe/Amsterdam
date::new(time::chrono::tz("Europe/Amsterdam")!,
	date::zflag::LAP_EARLY,
	2000, 10, 29,   2, 30);
//
// 2000-10-29 02:30:00.000000000 +0100 CET Europe/Amsterdam
date::new(time::chrono::tz("Europe/Amsterdam")!,
	date::zflag::LAP_LATE,
	2000, 10, 29,   2, 30);

fn newvirtual[link]

fn newvirtual() virtual;

Creates a new virtual date. All its fields are voided or nulled.

fn now[link]

fn now() date;

Returns a date of the current system time using time::clock::REALTIME, in the time::chrono::UTC locality.

fn parse[link]

fn parse(v: *virtual, layout: str, s: str) (void | parsefail);

Parses a datetime string into a virtual date, according to a layout format string with specifiers as documented under format. Partial, sequential, aggregative parsing is possible.

date::parse(&v, "%Y-%m-%d",    "2019-12-27");
date::parse(&v, "%H:%M:%S.%N", "22:07:08.000000000");
date::parse(&v, "%z %Z %L",    "+0100 CET Europe/Amsterdam");

Parse will return parsefail if an invalid format specifier is encountered or if given string 's' does not match the layout.

fn pdiff[link]

fn pdiff(a: date, b: date) period;

Calculates the period between two dates, from A to B. The returned period, provided to reckon along with A, will produce B, regardless of the calculus used. All the period's non-zero fields will have the same sign.

fn peq[link]

fn peq(pa: period, pb: period) bool;

Returns true if two periods are numerically equal, false otherwise.

fn realize[link]

fn realize(v: virtual, locs: chrono::locality...) (date | insufficient | invalid | zfunresolved);

Realizes a valid date from a virtual date, or fails appropriately.

The virtual date must hold enough valid date information to be able to calculate values for the resulting date. A valid combination of its fields must be "filled-in" (hold numerical, non-void values). For example:

let v = date::newvirtual();
v.locname = "Europe/Amsterdam";
v.zoff = date::zflag::LAP_EARLY | date::zflag::GAP_END;
date::parse(&v, // fills-in .year .month .day
	"Date: %Y-%m-%d", "Date: 2038-01-19")!;
v.hour = 4;
v.minute = 14;
v.second = 7;
v.nanosecond = 0;
let d = date::realize(v, time::chrono::tz("Europe/Amsterdam")!)!;

This function consults the fields of the given virtual date using a predictable procedure, attempting the simplest and most common field combinations first. Fields marked below with an asterisk (*), when empty, depend on other filled-in field-sets to calculate a new value for itself. The order in which these "dependency" field-sets are tried is described below.

The resultant date depends on a locality value and instant value.

The locality (time::chrono::locality) value depends on:

The instant (time::instant) value depends on:

An empty .daydate depends on:

An empty .daytime depends on:

An empty .year depends on:

An empty .hour depends on:

If not enough information was provided, insufficient is returned. If invalid information was provided, invalid is returned. Any zflags assigned to the .zoff field affect the final result.

fn reckon[link]

fn reckon(d: date, zoff: (time::duration | zflag), rf: rflag, ps: period...) (date | invalid | zfunresolved);

Reckons from a given date to a new one, via a given set of periods. This is a chronological arithmetic operation. Each period is reckoned independently in succession, applying (adding) their units from most to least significant.

The rflag parameter handles field overflows and other behaviours. The zflag parameter affects the final result. Example:

// 2000-02-29 00:00:00.000000000 -1100 -11 Pacific/Apia
let a = date::new(chrono::tz("Pacific/Apia")!, -11 * time::HOUR,
	2000,  2, 29)!;

let b = date::reckon(a,    // starts as: 2000-Feb-29 00:00 -1100
	date::zflag::GAP_END,
	date::rflag::DEFAULT,
	date::period {
		years  = 11, // becomes: 2011-Feb-28 00:00 -1100
		months = 10, // becomes: 2011-Dec-28 00:00 -1100
		days   =  1, // becomes: 2011-Dec-29 00:00 -1100
		hours  = 36, // becomes: 2011-Dec-30 12:00 -1100
	},
	// In Samoa, Apia, the day 2011-Dec-30 was skipped entirely.
	// Thus, after applying date::zflag::GAP_END for adjustment,
	// we arrive at the final date, time, and zone-offset:
	// 2011-12-31 00:00:00.000000000 +1400 +14 Pacific/Apia
);

See add.

fn second[link]

fn second(d: *date) int;

Observes a date's second of the minute.

fn strerror[link]

fn strerror(err: error) const str;

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

fn sum[link]

fn sum(ps: period...) period;

Returns the sum period of a set of periods.

fn sundayweek[link]

fn sundayweek(d: *date) int;

Observes a date's Gregorian week starting Sunday. Range 0 to 53. All days in a year before the year's first Sunday belong to week 0.

fn truncate[link]

fn truncate(d: date, zf: zflag, u: unit) (date | invalid | zfunresolved);

Truncates the given date at the provided nominal unit. The zflag parameter affects the final result. Example:

// On this day in Sao Paulo, a +1 hour jump occurs at 00:00.
// The time range 00:00..00:59 is never observed.
//
// 2000-10-08 12:00:00.000000000 -0200 -02 America/Sao_Paulo
let a = date::new(chrono::tz("America/Sao_Paulo")!, -2 * time::HOUR,
	2000, 10,  8, 12)!
//
// 2000-10-08 01:00:00.000000000 -0200 -02 America/Sao_Paulo
let b = date::truncate(a, date::zflag::GAP_END, date::unit::DAY)!;

fn unitdiff[link]

fn unitdiff(a: date, b: date, u: unit) i64;

Calculates the nominal unit difference between two dates.

fn week[link]

fn week(d: *date) int;

Observes a date's Gregorian week starting Monday. Range 0 to 53. All days in a year before the year's first Monday belong to week 0.

fn weekday[link]

fn weekday(d: *date) int;

Observes a date's day of the week. Range Monday=0 to Sunday=6.

fn year[link]

fn year(d: *date) int;

Observes a date's year.

fn yearday[link]

fn yearday(d: *date) int;

Observes a date's ordinal day of the year. Range 1 to 366.