datetime
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;
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 epochunix(*datetime) int;
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;
fn transform(datetime, time::duration) datetime;
Types
type builder
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
type calculus = enum {
DEFAULT,
};
Specifies the behaviour of calendar arithmetic.
type period
type period = struct {
eras: int,
years: int,
months: int,
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
type strategy = enum uint {
YMD = 1 << 0,
YD = 1 << 1,
YWD = 1 << 2,
ISOYWD = 1 << 4,
ALL = YMD | YD | YWD | ISOYWD,
};
Specifies which builder fields and what strategy to use to calculate the
date, and thus a valid datetime.
type unit
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
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
type insufficient = !void;
A builder has insufficient information and cannot create a valid datetime.
type invalid
type invalid = !chrono::invalid;
Invalid datetime.
Constants
def EMAILZ
def EMAILZ: str;
datetime::format layout for the email date format, with zone offset and
zone abbreviation.
def EPOCHAL_GREGORIAN
def EPOCHAL_GREGORIAN: i64;
The Hare epoch of the Gregorian Common Era.
def EPOCHAL_JULIAN
def EPOCHAL_JULIAN: i64;
The Hare epoch of the Julian Day Number.
def POSIX
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 STAMP_NANO
def STAMP_NANO: str;
datetime::format layout for a simple timestamp with nanoseconds.
def STAMP_NOZL
def STAMP_NOZL: str;
datetime::format layout for a simple timestamp with nanoseconds,
zone offset, zone abbreviation, and locality.
Functions
fn add
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
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(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
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(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
fn day(dt: *datetime) int;
Returns a datetime's day of the month.
fn diff
fn diff(a: datetime, b: datetime) period;
Calculates the period between two datetimes.
fn epochal
fn epochal(dt: *datetime) chrono::date;
Returns a datetime's number of days since the calendar epoch 0000-01-01.
fn epochunix
fn epochunix(dt: *datetime) int;
Returns a datetime's number of seconds since the Unix epoch 1970-01-01.
fn eq
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
fn era(dt: *datetime) int;
Returns a datetime's era.
fn finish
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(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).
%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_str
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
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
fn hour(dt: *datetime) int;
Returns a datetime's hour of the day.
fn is_leap_year
fn is_leap_year(y: int) bool;
Calculates whether a year is a leap year.
fn isoweek
fn isoweek(dt: *datetime) int;
Returns a datetime's ISO week.
fn isoweekyear
fn isoweekyear(dt: *datetime) int;
Returns a datetime's ISO week-numbering year.
fn lookupzone
fn lookupzone(dt: *datetime) chrono::zone;
Finds, sets and returns a datetime's currently observed zone.
fn min
fn min(dt: *datetime) int;
Returns a datetime's minute of the hour.
fn month
fn month(dt: *datetime) int;
Returns a datetime's month of the year.
fn new
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, 1, 19, 3, 14, 7, 618);
// 2038 Jan 19th 02:00:00.000000000 +0100 Europe/Amsterdam
datetime::new(&time::chrono::tz("Europe/Amsterdam"), 1 * time::HOUR,
2038, 1, 19, 2);
'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:
- In the Europe/Amsterdam timezone, at 1995 March 26th,
the local time 02:30 was never observed,
as the clock jumped forward 1 hour from 02:00 CET to 03:00 CEST.
- In the Europe/Amsterdam timezone, at 1995 September 24th,
the local time 02:30 was observed twice (00:30 UTC & 01:30 UTC),
as the clock jumped back 1 hour from 03:00 CEST to 02:00 CET.
fn newbuilder
fn newbuilder() builder;
Creates a new builder.
fn nsec
fn nsec(dt: *datetime) int;
Returns a datetime's nanosecond of the second.
fn parse
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
fn period_eq(a: period, b: period) bool;
Returns true if two periods are numerically equal.
fn sec
fn sec(dt: *datetime) int;
Returns a datetime's second of the minute.
fn sub
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
fn sundayweek(dt: *datetime) int;
Returns a datetime's Gregorian week starting Sunday.
fn truncate
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
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
fn week(dt: *datetime) int;
Returns a datetime's Gregorian week starting Monday.
fn weekday
fn weekday(dt: *datetime) int;
Returns a datetime's day of the week.
fn year
fn year(dt: *datetime) int;
Returns a datetime's year.
fn yearday
fn yearday(dt: *datetime) int;
Returns a datetime's ordinal day of the year.
Show undocumented member
fn transform(dt: datetime, zo: time::duration) datetime;