datetime +linux +x86_64

The datetime 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 datetime, a representation of civil date/time and an extension of the time::chrono::moment type, optimized for dealing with the Gregorian chronology.

Datetimes are created with new, now, or with one of the various "from_" functions. Alternatively, use a builder to construct a datetime piece-by-piece, by field assignements or by parsing strings with parse.

datetime instances are designed to be always valid and internally consistent. They should be treated as immutable, and their fields as private. All functions herein return valid datetimes (or appropriate errors), and never modify a datetime's value, even if passed as a pointer, which is used only for internal caching.

datetime fields are accessed, evaluated, and cached via the various "field" functions (year, month, day, etc). Accessing or modifying a datetime's fields directly is discouraged. To mutate a datetime in code, the use of the builder interface is recommended.

datetimes may be localized to different time::chrono::timezones via the in function. The "field" functions will evaluate the correct values accordingly. You'll find a standard selection of world timezones in the time::chrono module.

To convert datetimes to and from strings, use parse and format.

For arithmetics, use diff, add and hop. Note that calendrical arithmetic is highly irregular with many edge cases, so think carefully about what you want.

Index

Types

type builder;
type calculus;
type period;
type strategy;
type unit;

// Undocumented types:
type datetime;

Errors

type insufficient;
type invalid;

Constants

const EMAIL: str;
const EMAILZ: str;
const EPOCHAL_GREGORIAN: i64;
const EPOCHAL_JULIAN: i64;
const POSIX: str;
const RFC3339: str;
const STAMP: str;
const STAMP_NANO: str;
const STAMP_NOZL: str;

Functions

fn add(datetime, calculus, period...) datetime;
fn after(datetime, datetime) bool;
fn asformat(str, *datetime) (str | invalid | io::error);
fn before(datetime, datetime) bool;
fn bsformat([]u8, str, *datetime) (str | invalid | io::error);
fn day(*datetime) int;
fn diff(datetime, datetime) period;
fn epochal(*datetime) chrono::date;
fn eq(datetime, datetime) bool;
fn era(*datetime) int;
fn finish(*builder, strategy...) (datetime | insufficient | invalid);
fn format(io::handle, str, *datetime) (size | invalid | io::error);
fn from_instant(time::instant, chrono::locality) datetime;
fn from_moment(chrono::moment) datetime;
fn from_str(str, str) (datetime | insufficient | invalid);
fn hop(datetime, period...) datetime;
fn hour(*datetime) int;
fn in(chrono::locality, datetime) datetime;
fn is_leap_year(int) bool;
fn isoweek(*datetime) int;
fn isoweekyear(*datetime) int;
fn lookupzone(*datetime) chrono::zone;
fn min(*datetime) int;
fn month(*datetime) int;
fn new(chrono::locality, (time::duration | void), int...) (datetime | invalid);
fn newbuilder() builder;
fn now() datetime;
fn nsec(*datetime) int;
fn parse(*builder, str, str) (void | invalid);
fn period_eq(period, period) bool;
fn sec(*datetime) int;
fn sub(datetime, calculus, period...) datetime;
fn sundayweek(*datetime) int;
fn to_instant(datetime) time::instant;
fn to_moment(datetime) chrono::moment;
fn truncate(datetime, unit) datetime;
fn unitdiff(datetime, datetime, unit) i64;
fn week(*datetime) int;
fn weekday(*datetime) int;
fn year(*datetime) int;
fn yearday(*datetime) int;

// Undocumented functions:
fn transform(datetime, time::duration) datetime;

Types

type builder[link]

type builder = datetime;

A pseudo-datetime; a datetime which may hold invalid values, and does not guarantee internal validity or consistency.

This can be used to construct new datetimes. Start with newbuilder, then collect enough datetime information incrementally by direct field assignments and/or one or more calls to parse. Finish with finish.

let builder = datetime::newbuilder();
datetime::parse(&builder, "Year: %Y", "Year: 2038");
datetime::parse(&builder, "Month: %m", "Month: 01");
builder.day = 19;
let dt = datetime::finish(&builder, datetime::strategy::YMD);

type calculus[link]

type calculus = enum {
	// Units are added in the order of largest (years) to smallest
// (nanoseconds). If the resulting date does not exist, the first extant
// date previous to the initial result is returned.
DEFAULT, };

Specifies the behaviour of calendar arithmetic.

type period[link]

type period = struct {
	eras: int,
	years: int,
	// Can be 28, 29, 30, or 31 days long
months: int, // Weeks start on Monday
weeks: int, days: int, hours: int, minutes: int, seconds: int, nanoseconds: i64, };

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

type strategy[link]

type strategy = enum uint {
	YMD = 1 << 0, // year, month, day
YD = 1 << 1, // year, yearday
YWD = 1 << 2, // year, week, weekday
ISOYWD = 1 << 4, // isoyear, isoweek, weekday
ALL = YMD | YD | YWD | ISOYWD, // all strategies, in order as presented here
};

Specifies which builder fields and what strategy to use to calculate the date, and thus a valid datetime.

type unit[link]

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

};

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

type datetime[link]

Show undocumented member
type datetime = 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),
	min: (void | int),
	sec: (void | int),
	nsec: (void | int),
};

Errors

type insufficient[link]

type insufficient = !void;

A builder has insufficient information and cannot create a valid datetime.

type invalid[link]

type invalid = !chrono::invalid;

Invalid datetime.

Constants

def EMAIL[link]

def EMAIL: str;

datetime::format layout for the email date format.

def EMAILZ[link]

def EMAILZ: str;

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

def EPOCHAL_GREGORIAN[link]

def EPOCHAL_GREGORIAN: i64;

The Hare epoch of the Gregorian Common Era.

def EPOCHAL_JULIAN[link]

def EPOCHAL_JULIAN: i64;

The Hare epoch of the Julian Day Number.

def POSIX[link]

def POSIX: str;

datetime::format layout partly compatible with the default layout format for the POSIX locale. %d is used in place of POSIX %e.

def RFC3339[link]

def RFC3339: str;

datetime::format layout compatible with RFC 3339.

def STAMP[link]

def STAMP: str;

datetime::format layout for a simple timestamp.

def STAMP_NANO[link]

def STAMP_NANO: str;

datetime::format layout for a simple timestamp with nanoseconds.

def STAMP_NOZL[link]

def STAMP_NOZL: str;

datetime::format layout for a simple timestamp with nanoseconds, zone offset, zone abbreviation, and locality.

Functions

fn add[link]

fn add(dt: datetime, flag: calculus, pp: period...) datetime;

Adds a period of time to a datetime, most significant units first. Conserves relative distance from cyclical points on the calendar when possible. This can be used, for example, to find the date one year from now.

let dt = ... // 1999-05-13 12:30:45
datetime::add(dt, datetime::calculus::DEFAULT, datetime::period {
	years  = 22, // 2021-05-13 12:30:45
	months = -1, // 2021-04-13 12:30:45
	days   = -4, // 2020-04-09 12:30:45
});

fn after[link]

fn after(a: datetime, b: datetime) bool;

Returns true if datetime "a" succeeds datetime "b".

Temporal order is evaluated in a universal frame of reference, regardless of their locality or observed chronological values.

fn asformat[link]

fn asformat(layout: str, dt: *datetime) (str | invalid | io::error);

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

fn before[link]

fn before(a: datetime, b: datetime) bool;

Returns true if datetime "a" precedes datetime "b".

Temporal order is evaluated in a universal frame of reference, regardless of their locality or observed chronological values.

fn bsformat[link]

fn bsformat(buf: []u8, layout: str, dt: *datetime) (str | invalid | io::error);

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

fn day[link]

fn day(dt: *datetime) int;

Returns a datetime's day of the month.

fn diff[link]

fn diff(a: datetime, b: datetime) period;

Calculates the period between two datetimes.

fn epochal[link]

fn epochal(dt: *datetime) chrono::date;

Returns a datetime's number of days since the calendar epoch 0000-01-01.

fn eq[link]

fn eq(a: datetime, b: datetime) bool;

Returns true if two datetimes are equivalent.

Equivalence means they represent the same moment in time, regardless of their locality or observed chronological values.

fn era[link]

fn era(dt: *datetime) int;

Returns a datetime's era.

fn finish[link]

fn finish(f: *builder, m: strategy...) (datetime | insufficient | invalid);

Returns a datetime from a builder. The provided strategys will be tried in order until a valid datetime is produced, or otherwise fail. The default strategy is strategy::ALL.

fn format[link]

fn format(h: io::handle, layout: str, dt: *datetime) (size | invalid | io::error);

Formats a datetime 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).
%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 -- The second of the minute (range 00 to 60).
%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(i: time::instant, loc: chrono::locality) datetime;

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

fn from_moment[link]

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

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

fn from_str[link]

fn from_str(layout: str, s: str) (datetime | insufficient | invalid);

Creates a datetime from a string, parsed according to a layout, using strategy::ALL, or otherwise fails.

fn hop[link]

fn hop(dt: datetime, pp: period...) datetime;

Given a datetime and a period, "hops" to the minimum value of each field (years, months, days, etc) plus or minus an offset, and returns a new datetime. This can be used, for example, to find the start of last year.

Consults each period's fields from most to least significant (from years to nanoseconds).

If a period's field's value N is zero, it's a no-op. Otherwise, hop will reckon to the Nth inter-period point from where last reckoned. This repeats until all the given period's fields are exhausted.

let dt = ... // 1999-05-13 12:30:45
datetime::hop(dt, datetime::period {
	years  = 22, // produces 2021-01-01 00:00:00
	months = -1, // produces 2020-11-01 00:00:00
	days   = -4, // produces 2020-10-27 00:00:00
});

fn hour[link]

fn hour(dt: *datetime) int;

Returns a datetime's hour of the day.

fn in[link]

fn in(loc: chrono::locality, dt: datetime) datetime;

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

fn is_leap_year[link]

fn is_leap_year(y: int) bool;

Calculates whether a year is a leap year.

fn isoweek[link]

fn isoweek(dt: *datetime) int;

Returns a datetime's ISO week.

fn isoweekyear[link]

fn isoweekyear(dt: *datetime) int;

Returns a datetime's ISO week-numbering year.

fn lookupzone[link]

fn lookupzone(dt: *datetime) chrono::zone;

Finds, sets and returns a datetime's currently observed zone.

fn min[link]

fn min(dt: *datetime) int;

Returns a datetime's minute of the hour.

fn month[link]

fn month(dt: *datetime) int;

Returns a datetime's month of the year.

fn new[link]

fn new(
	loc: chrono::locality,
	offs: (time::duration | void),
	fields: int...
) (datetime | invalid);

Creates a new datetime. When loc=void, defaults to chrono::local.

// 0000 Jan  1st 00:00:00.000000000 +0000 UTC
datetime::new(time::chrono::UTC, 0);

// 2038 Jan 19th 03:14:07.000000618 +0000 UTC
datetime::new(time::chrono::UTC, 0, 2038, 01, 19, 03, 14, 07, 618);

// 2038 Jan 19th 02:00:00.000000000 +0100 Europe/Amsterdam
datetime::new(&time::chrono::tz("Europe/Amsterdam"), 1 * time::HOUR,
	2038, 01, 19, 02);

'offs' is the zone offset from the normal timezone (in most cases, UTC). For example, the "Asia/Tokyo" timezone has a single zoffset of +9 hours, but the "Australia/Sydney" timezone has zoffsets +10 hours and +11 hours, as they observe Daylight Saving Time.

If specified (non-void), 'offs' must match one of the timezone's observed zoffsets, or will fail. See time::chrono::fixedzone for custom timezones.

You may omit the zoffset. If the givem timezone has a single zone, new will use that zone's zoffset. Otherwise new will try to infer the zoffset from the multiple zones. This will fail during certain timezone transitions, where certain datetimes are ambiguous or nonexistent. For example:

fn newbuilder[link]

fn newbuilder() builder;

Creates a new builder.

fn now[link]

fn now() datetime;

Returns a datetime of the current system time, using time::clock::REALTIME and time::chrono::LOCAL.

fn nsec[link]

fn nsec(dt: *datetime) int;

Returns a datetime's nanosecond of the second.

fn parse[link]

fn parse(build: *builder, layout: str, s: str) (void | invalid);

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

datetime::parse(&builder, "%Y-%m-%d", "2038-01-19");
datetime::parse(&builder, "%H:%M:%S", "03:14:07");

fn period_eq[link]

fn period_eq(a: period, b: period) bool;

Returns true if two periods are numerically equal.

fn sec[link]

fn sec(dt: *datetime) int;

Returns a datetime's second of the minute.

fn sub[link]

fn sub(dt: datetime, flag: calculus, pp: period...) datetime;

Subtracts a calendrical period of time to a datetime, most significant units first. Conserves relative distance from cyclical points on the calendar when possible.

let dt = ... // 1999-05-13 12:30:45
datetime::subtract(dt, datetime::calculus::DEFAULT, datetime::period {
	years  = 22, // 1977-05-13 12:30:45
	months = -1, // 1977-06-13 12:30:45
	days   = -4, // 1977-06-17 12:30:45
});

fn sundayweek[link]

fn sundayweek(dt: *datetime) int;

Returns a datetime's Gregorian week starting Sunday.

fn to_instant[link]

fn to_instant(dt: datetime) time::instant;

Creates a time::instant from a datetime.

fn to_moment[link]

fn to_moment(dt: datetime) chrono::moment;

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

fn truncate[link]

fn truncate(dt: datetime, u: unit) datetime;

Truncates the given datetime at the provided nominal unit.

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

fn unitdiff[link]

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

Calculates the difference between two datetimes using the given nominal unit, truncating towards zero.

fn week[link]

fn week(dt: *datetime) int;

Returns a datetime's Gregorian week starting Monday.

fn weekday[link]

fn weekday(dt: *datetime) int;

Returns a datetime's day of the week.

fn year[link]

fn year(dt: *datetime) int;

Returns a datetime's year.

fn yearday[link]

fn yearday(dt: *datetime) int;

Returns a datetime's ordinal day of the year.

fn transform[link]

Show undocumented member
fn transform(dt: datetime, zo: time::duration) datetime;