time::date+x86_64 +linux

The time::date module implements the common international Gregorian chronology, based on the astronomically numbered proleptic Gregorian calendar, as per ISO 8601, 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, nowutc, 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 calculus = 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 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 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),
	// zone abbreviation
	zabbr: (void | str),
	// hour of 12 hour clock
	halfhour: (void | int),
	// AM/PM (false/true)
	ampm: (void | bool),
};

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

Errors

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

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 EPOCHAL_GREGORIAN: i64 = -719164;
def EPOCHAL_JULIAN: i64 = -2440588;
def FEBRUARY: int = 2;
def FRIDAY: int = 4;
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 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, fields: int...) (date | invalid);
fn newvirtual() virtual;
fn now() date;
fn nowutc() 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);
fn reckon(d: date, calc: calculus, ps: period...) date;
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, u: unit) date;
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 calculus[link]

type calculus = 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 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 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),
	// zone abbreviation
	zabbr: (void | str),
	// hour of 12 hour clock
	halfhour: (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'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 = time::chrono::UTC;
v.zoff = 0;
date::parse(&v, "Date: %Y-%m-%d", "Date: 2038-01-19")!;
v.hour = 03;
v.minute = 14;
v.second = 07;
v.nanosecond = 0;
let d = date::realize(v)!;

type lack[link]

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

Errors

type error[link]

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

All possible errors returned from date.

type insufficient[link]

type insufficient = !lack;

A virtual does not have enough information 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.

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 EPOCHAL_GREGORIAN[link]

def EPOCHAL_GREGORIAN: i64 = -719164;

The Hare epoch of the Gregorian Common Era.

def EPOCHAL_JULIAN[link]

def EPOCHAL_JULIAN: i64 = -2440588;

The Hare epoch 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 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, serializable 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, glanceable 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.

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. Implemented are a subset of the POSIX strftime(3) format specifiers, as well as some others. Use of unimplemented specifiers or an otherwise invalid layout will cause an abort.

%% -- A literal '%' character.
%a -- The abbreviated name of the day of the week.
%A -- The full name of the day of the week.
%b -- The abbreviated name of the month.
%B -- The full name of the month.
%d -- The day of the month (decimal, range 01 to 31).
%e -- The day of the month (decimal, range  1 to 31), left-padded space.
%F -- The full date, equivalent to %Y-%m-%d
%H -- The hour of the day as from a 24-hour clock (range 00 to 23).
%I -- The hour of the day as from a 12-hour clock (range 01 to 12).
%j -- The ordinal day of the year (range 001 to 366).
%L -- The locality's name (the timezone's identifier).
%m -- The month (decimal, range 01 to 12).
%M -- The minute (decimal, range 00 to 59).
%N -- The nanosecond of the second (range 000000000 to 999999999).
%p -- Either "AM" or "PM" according to the current time.
      "AM" includes midnight, and "PM" includes noon.
%s -- Number of seconds since 1970-01-01 00:00:00, the Unix epoch
%S -- The second of the minute (range 00 to 60).
%T -- The full time, equivalent to %H:%M:%S
%u -- The day of the week (decimal, range 1 to 7). 1 represents Monday.
%U -- The week number of the current year (range 00 to 53),
      starting with the first Sunday as the first day of week 01.
%w -- The day of the week (decimal, range 0 to 6). 0 represents Sunday.
%W -- The week number of the current year (range 00 to 53),
      starting with the first Monday as the first day of week 01.
%y -- The year without the century digits (range 00 to 99).
%Y -- The year.
%z -- The observed zone offset.
%Z -- The observed zone abbreviation.

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. At least a complete calendar date has to be provided. The if hour, minute, second, nanosecond, or zone offset are not provided, they default to 0.

let new = date::from_str(
	date::STAMPLOC,
	"2019-12-27 22:07:08.000000000 +0100 CET Europe/Amsterdam",
	locs...
)!;

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 for 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.

fn isoweekyear[link]

fn isoweekyear(d: *date) int;

Observes a date's ISO week-numbering year.

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.

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, fields: int...) (date | invalid);

Creates a new date. Upto seven field arguments can be given: year, month, day, hour, minute, second, nanosecond. 8 or more causes an abort. If omitted, the month and day default to 1, and the rest default to 0.

Accepts a time::chrono::locality, and a 'zoff' zone offset parameter which is used to discern the desired observed time::chrono::zone in the given locality. See time::chrono::fixedzone for custom timezones.

An invalid zoff or field argument combination returns invalid.

Example:

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

// 2019-12-27 20:07:08.000031415 +0000 UTC UTC
date::new(time::chrono::UTC, 0,
	2019, 12, 27,  20,  7,  8, 31415);

// 2019-12-27 21:00:00.000000000 +0100 CET Europe/Amsterdam
date::new(time::chrono::tz("Europe/Amsterdam")!, 1 * time::HOUR,
	2019, 12, 27,  21);

// 2019-12-27 10:00:00.000000000 -1000 HST Pacific/Honolulu
date::new(time::chrono::tz("Pacific/Honolulu")!, -10 * time::HOUR,
	2019, 12, 27,  10);

// Invalid month, day, hour, and minute
date::new(time::chrono::UTC, 0,
	2019,  0,  0,  99, -30);

// Invalid zoff
date::new(time::chrono::UTC,       -7 * time::HOUR,  2019);
date::new(time::chrono::tz("Europe/Amsterdam")!, 0,  2019);

Example: Two dates, 30 physical minutes before and after a DST timezone transition, observing the same date/time, but different zone offsets:

// 2019-04-07 02:30:00.000000000 +1100 AUDT Australia/Sydney
date::new(time::chrono::tz("Australia/Sydney")!, 11 * time::HOUR,
	2019,  4,  7,   2, 30);

// 2019-04-07 02:30:00.000000000 +1000 AUST Australia/Sydney
date::new(time::chrono::tz("Australia/Sydney")!, 10 * time::HOUR,
	2019,  4,  7,   2, 30);

fn newvirtual[link]

fn newvirtual() virtual;

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

fn now[link]

fn now() date;

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

fn nowutc[link]

fn nowutc() 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 date/time string into a virtual, 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);

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

The virtual 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 = 1 * time::HOUR;
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 using a predictable procedure. In calculating a date, it attempts to calculate values for empty fields using sets of other filled-in fields (dependencies), in a order described below.

The resultant date depends on a locality and instant.

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

The instant (time::instant) depends on:

An empty .daydate depends on:

An empty .daytime depends on:

If none of the possible combinations of fields were filled-in, insufficient is returned. If after calculation the resultant date is invalid, invalid is returned.

fn reckon[link]

fn reckon(d: date, calc: calculus, ps: period...) date;

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 calculus parameter determines certain behaviours, like for when encountering invalid date states (e.g. field overflows).

let dest = date::reckon(
	start, // 2000-02-29 09:00:00
	0,     // calculus::DEFAULT
	date::period {
		years  =  1, // becomes: 2001-02-28 09:00:00
		months = -2, // becomes: 2000-12-28 09:00:00
		days   =  4, // becomes: 2001-01-01 09:00:00
	},
);

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.

fn truncate[link]

fn truncate(d: date, u: unit) date;

Truncates the given date at the provided nominal unit.

For example, truncating to the nearest unit::MONTH will set the 'day', 'hour', 'minute', 'second', and 'nanosecond' fields to their minimum values.

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.

fn weekday[link]

fn weekday(d: *date) int;

Observes a date's day of the week; 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.