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.
datetime
s 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::epochal;
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 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;
Constructs a new datetime. 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 proleptic Gregorian calendar, using relative
units of time. Used for calendar 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
epochal, and thus a valid datetime.
type unit
type unit = enum {
ERA,
YEAR,
MONTH,
WEEK,
DAY,
HOUR,
MINUTE,
SECOND,
NANOSECOND,
};
The various datetime units that can be used for 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),
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;
The given combination of date, time, and locality is invalid.
Constants
def EMAILZ
def EMAILZ: str;
datetime::format string 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 string used by default for POSIX date(1).
def STAMP_NANO
def STAMP_NANO: str;
datetime::format string for a simple timestamp with nanoseconds.
def STAMP_NOZL
def STAMP_NOZL: str;
datetime::format string 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 the first date is after the second date.
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 the first date is before the second date.
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 difference between two datetimes.
fn epochal
fn epochal(dt: *datetime) chrono::epochal;
Returns a datetime's number of days since the calendar epoch 0000-01-01
fn eq
fn eq(a: datetime, b: datetime) bool;
Returns true if two dates are numerically equal.
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 fail otherwise. 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).
%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
fn from_instant(i: time::instant, loc: chrono::locality) datetime;
Creates a datetime from a time::instant.
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 fails otherwise.
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 field's value N is zero, nothing happens. 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 given 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 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, 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:
- 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 now
fn now() datetime;
Returns a datetime for the immediate system time.
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 datetime string into a builder, using a "layout" format string
with a set of specifiers as documented under format. Partial, incremental
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 truncate
fn truncate(dt: datetime, u: unit) datetime;
Truncates the given datetime at the provided unit. For example, truncating to
the nearest unit::YEAR will set the month, 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 unit,
truncating towards zero.
fn week
fn week(dt: *datetime) int;
Returns a datetime's Gregorian week
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;