std.calendar
API summary (generated from the Beans source by npm run coverage): 3 package functions · 2 types · 9 static methods · 23 instance methods · 7 public fields · 7 enum variants.
std.calendar represents calendar dates and times, converts between them and
epoch timestamps, and parses and formats RFC 3339 and HTTP dates. Read the
source at
stdlib/std/calendar/calendar.b.
import std.calendarRules that shape the package
Section titled “Rules that shape the package”The package uses UTC. It parses numeric offsets but does not provide local
time, a timezone database, or daylight-saving rules. For example,
2024-03-05T09:30:00+05:30 is converted to UTC and stored as that instant.
Leap seconds are not modelled. Every minute has exactly 60 seconds and
every day exactly 86400, which is what the epoch counters in std.time already
assume. second is therefore 0..=59, and a timestamp written with :60 is
refused rather than quietly moved.
The calendar is proleptic Gregorian — the Gregorian leap rule extended backwards through the years it was not yet in use, so year 1500 here is Gregorian, not Julian. The two conversion kernels are Howard Hinnant’s, from “chrono-Compatible Low-Level Date Algorithms”.
Package functions
Section titled “Package functions”pub fn is_leap_year(year: int) -> boolpub fn days_in_month(year: int, month: int) -> intpub fn days_from_civil(year: int, month: int, day: int) -> intis_leap_yearis the Gregorian rule: divisible by 4, except centuries, except those divisible by 400.days_in_monthgives the length of a month, February included.days_from_civilis the day number for a date, counted from 1970-01-01 — negative before it. It is the kernel everything else is built on, exposed because date arithmetic that never builds aDateTimeis cheaper without one.
Weekday
Section titled “Weekday”pub enum Weekday { sunday monday tuesday wednesday thursday friday saturday}
pub fn name() -> stringpub fn short_name() -> stringpub fn number() -> intnameis the full English name ("Monday"),short_namethe three-letter form ("Mon") that HTTP dates use.numberis0for Sunday through6for Saturday.
DateTime
Section titled “DateTime”A plain struct, so it copies rather than being shared, and its fields are readable directly.
pub struct DateTime { pub year: int pub month: int pub day: int pub hour: int pub minute: int pub second: int pub nanosecond: int}month is 1..=12 and day is 1..=31 — the numbers people write, not
zero-based ones. second is 0..=59.
Making one
Section titled “Making one”pub static fn now() -> DateTimepub static fn epoch() -> DateTimepub static fn of(year: int, month: int, day: int, hour: int, minute: int, second: int, nanosecond: int) -> Result<DateTime>pub static fn of_date(year: int, month: int, day: int) -> Result<DateTime>pub static fn from_epoch_nanos(nanos: int) -> DateTimepub static fn from_epoch_millis(millis: int) -> Result<DateTime>pub static fn from_epoch_seconds(seconds: int) -> Result<DateTime>pub static fn parse_rfc3339(text: string) -> Result<DateTime>pub static fn parse_http_date(text: string) -> Result<DateTime>nowreads the wall clock.epochis 1970-01-01T00:00:00Z.ofandof_datebuild one from parts and answererrwhen the parts do not name a real instant — month 13, the 31st of a 30-day month, February 29th of a common year, a second of 60.of_dateisofwith the time of day zeroed.- The
from_epoch_*family converts a counter back to a date.from_epoch_nanoscannot fail; the other two can, because a large enough seconds or millis value would overflow the nanosecond range. parse_rfc3339reads2024-03-05T09:30:00Zand offset forms like+05:30, converting to UTC.parse_http_datereads the RFC 9110 format (Tue, 05 Mar 2024 09:30:00 GMT) thatDate,Last-ModifiedandIf-Modified-Sincecarry.
Reading it back
Section titled “Reading it back”pub fn epoch_day() -> intpub fn epoch_seconds() -> intpub fn epoch_millis() -> intpub fn epoch_nanos() -> Result<int>pub fn weekday() -> Weekdaypub fn day_of_year() -> int- The
epoch_*family is the inverse offrom_epoch_*. Onlyepoch_nanosreturns aResult, because a far enough date does not fit a 64-bit nanosecond count. day_of_yearis1..=366.
Moving it
Section titled “Moving it”pub fn plus_nanos(nanos: int) -> Result<DateTime>pub fn plus_seconds(seconds: int) -> Result<DateTime>pub fn plus_minutes(minutes: int) -> Result<DateTime>pub fn plus_hours(hours: int) -> Result<DateTime>pub fn plus_days(days: int) -> Result<DateTime>Each answers a new DateTime and leaves the receiver alone. A negative
argument goes backwards. They return a Result because the arithmetic can run
off the end of the representable range.
Comparing
Section titled “Comparing”pub fn compare(other: DateTime) -> intpub fn is_before(other: DateTime) -> boolpub fn is_after(other: DateTime) -> boolpub fn seconds_until(other: DateTime) -> intpub fn millis_until(other: DateTime) -> intcompareis negative, zero or positive as the receiver sorts before, equal to or afterother.- The two
*_untilmethods are signed differences — negative whenotheris in the past.
Formatting
Section titled “Formatting”pub fn to_date_string() -> stringpub fn to_time_string() -> stringpub fn to_rfc3339() -> stringpub fn to_http_date() -> stringto_date_string is 2024-03-05, to_time_string is 09:30:00, to_rfc3339
is the full 2024-03-05T09:30:00Z, and to_http_date is
Tue, 05 Mar 2024 09:30:00 GMT. Each to_* round-trips through its matching
parse_*.
Worked example
Section titled “Worked example”import std.ioimport std.calendar
fn main() { match calendar.DateTime.of(2024, 3, 5, 9, 30, 0, 0) { ok(when) => { io.println(when.to_rfc3339()) // 2024-03-05T09:30:00Z io.println(when.to_http_date()) // Tue, 05 Mar 2024 09:30:00 GMT io.println(when.weekday().name()) // Tuesday io.println(when.day_of_year()) // 65 match when.plus_days(30) { ok(later) => { io.println(later.to_date_string()) } // 2024-04-04 err(problem) => { io.println("overflow") } } } err(problem) => { io.println("not a real instant") } }
io.println(calendar.is_leap_year(2024)) // true io.println(calendar.days_in_month(2024, 2)) // 29}See also
Section titled “See also”- std.time and std.random, the clocks this package converts to and from.
- std.http, which carries the HTTP date format
parse_http_dateandto_http_dateread and write.