| Type | Description |
|---|---|
| TimeZone (trait) | Resolves a NaiveDateTime to a UTC offset; implemented by Utc, FixedOffset, FixedZone, and Location |
| MappedLocalTime[T] | The result of resolving a local (wall-clock) reading: Single, Ambiguous (DST fold), or Absent (DST gap); T is a FixedOffset or a DateTime[Tz] |
| Utc | The UTC zone: always offset zero |
| FixedOffset | A constant UTC offset, ±23:59:59 |
| FixedZone | A named zone with one constant offset; zone_name/%Z report the name |
| DateTime[Tz] | A NaiveDateTime paired with a time zone Tz |
| Location | A time zone backed by parsed IANA tzdata, resolving historical transitions and DST |
| TransitionBounds | The validity window (start/end) of a Location's segment covering a given instant |
///|
test {
let naive = @core.NaiveDateTime::new(
@core.NaiveDate::from_ymd(2024, 6, 15).unwrap(),
@core.NaiveTime::from_hms(12, 0, 0).unwrap(),
)
let dt = @tz.DateTime::from_utc(
naive,
@tz.FixedOffset::east(9 * 3600).unwrap(),
)
assert_eq(dt.offset(), @tz.FixedOffset::east(9 * 3600).unwrap())
assert_eq(
dt.naive_local(),
@core.NaiveDateTime::new(
@core.NaiveDate::from_ymd(2024, 6, 15).unwrap(),
@core.NaiveTime::from_hms(21, 0, 0).unwrap(),
),
)
}///|
test {
let naive = @core.NaiveDateTime::new(
@core.NaiveDate::from_ymd(2024, 6, 15).unwrap(),
@core.NaiveTime::from_hms(12, 15, 0).unwrap(),
)
let dt = @tz.DateTime::from_utc(
naive,
@tz.FixedOffset::east(9 * 3600 + 1800).unwrap(),
)
let truncated = dt.truncate(@core.TimeDelta::hours(1L).unwrap()).unwrap()
assert_eq(
truncated.naive_utc(),
@core.NaiveDateTime::new(
@core.NaiveDate::from_ymd(2024, 6, 15).unwrap(),
@core.NaiveTime::from_hms(12, 0, 0).unwrap(),
),
)
assert_eq(
truncated.naive_local(),
@core.NaiveDateTime::new(
@core.NaiveDate::from_ymd(2024, 6, 15).unwrap(),
@core.NaiveTime::from_hms(21, 30, 0).unwrap(),
),
)
}///|
test {
let ny = @tz.Location::load("America/New_York").unwrap()
let dst_start_2024 = @core.NaiveDateTime::from_timestamp(1_710_054_000L, 0).unwrap()
assert_eq(
ny.offset_from_utc(dst_start_2024),
@tz.FixedOffset::east(-14400).unwrap(),
)
assert_eq(ny.zone_name(dst_start_2024), "EDT")
}| Method | Signature | Description |
|---|---|---|
| offset_from_utc(NaiveDateTime) | -> FixedOffset | The offset in effect at a given UTC instant; never ambiguous |
| offset_from_local(NaiveDateTime) | -> MappedLocalTime[FixedOffset] | The offset(s) for a given local (wall-clock) instant, handling DST ambiguity/gaps |
| zone_name(NaiveDateTime) | -> String | The zone abbreviation/name in effect at a given UTC instant |
| is_dst(NaiveDateTime) | -> Bool | Whether daylight saving time is in effect at a given UTC instant; false by default, overridden by Location, PosixTz and Local |
| transition_bounds(NaiveDateTime) | -> TransitionBounds | The validity window of the offset in effect at a given UTC instant; unbounded on both sides by default, overridden by Location (its own transition_bounds), PosixTz and Local |
| offset_from_abbreviation(String, NaiveDateTime) | -> FixedOffset? | The offset a zone abbreviation (e.g. "EST") denotes in this zone, resolved at a given UTC instant; None by default (Utc, FixedOffset), overridden by Location (see its own method), PosixTz (its standard and DST names) and Local |
///|
pub enum MappedLocalTime[T] {
Single(T)
Ambiguous(T, T) // a DST fold: two valid results, (earliest, latest)
Absent // a DST gap: no valid result
}| Method | Signature | Description |
|---|---|---|
| single() | -> T? | The value, only when unambiguous; None for Ambiguous/Absent |
| unwrap() | -> T | The value when unambiguous; aborts, naming the reason, on Ambiguous or Absent |
| earliest() | -> T? | The earliest possible value (the sole value, or the first of an Ambiguous fold); None for Absent |
| latest() | -> T? | The latest possible value (the sole value, or the second of an Ambiguous fold); None for Absent |
| map((T) -> U) | -> MappedLocalTime[U] | Transform every value carried by self, preserving its shape |
///|
test {
let dt = @tz.DateTime::from_ymd_hms(2024, 3, 5, 9, 0, 0, @tz.Utc::new()).unwrap()
let moved = dt.with_hour(10).single().bind(d => d.with_minute(30).single())
assert_eq(moved.map(d => d.hour() * 100 + d.minute()), Some(1030))
}| Method | Signature | Description |
|---|---|---|
| Utc::new() | -> Self | Construct the (zero-sized) UTC zone value |
| Utc::now() | -> DateTime[Utc] | The current UTC instant, read from the host's wall clock. Unlike every other function in this package, not a pure function of its arguments. Total: a host clock outside NaiveDate's range (about 5.8 million years either side of 1970) is a broken environment, and aborts. The precision is at most one millisecond: the clock is read in whole milliseconds, so the sub-millisecond part is always zero, and a coarser host clock gives coarser values. |
| offset_from_utc(NaiveDateTime) | -> FixedOffset | Always FixedOffset::east(0) |
| offset_from_local(NaiveDateTime) | -> MappedLocalTime[FixedOffset] | Always Single(FixedOffset::east(0)) |
| zone_name(NaiveDateTime) | -> String | Always "UTC" |
| to_string() (Show) | -> String | "UTC", the same text as zone_name |
| Method | Signature | Description |
|---|---|---|
| FixedOffset::east(Int) | -> Self? | An offset east of UTC by the given seconds; None outside ±23:59:59 |
| FixedOffset::west(Int) | -> Self? | An offset west of UTC by the given seconds (negated internally); same range |
| local_minus_utc() | -> Int | The offset in seconds (negative for a western offset) |
| utc_minus_local() | -> Int | The sign-reversed offset in seconds (positive for a western offset) |
| offset_from_utc(NaiveDateTime) | -> FixedOffset | Returns self, unchanged, regardless of the given instant |
| offset_from_local(NaiveDateTime) | -> MappedLocalTime[FixedOffset] | Always Single(self) |
| zone_name(NaiveDateTime) | -> String | Colon-separated sign, hour, and minute, e.g. "+09:00"; extended with a seconds component for a non-whole-minute offset, e.g. "-04:56:02" |
| to_string() (Show) | -> String | The same colon-separated text as zone_name, e.g. "+09:00" |
| Method | Signature | Description |
|---|---|---|
| FixedZone::new(String, FixedOffset) | -> Self | A zone with the given name and constant offset |
| name() | -> String | The zone's name |
| offset() | -> FixedOffset | The zone's constant offset |
| offset_from_utc(NaiveDateTime) / offset_from_local(NaiveDateTime) | -> FixedOffset / -> MappedLocalTime[FixedOffset] | The constant offset; the local form is always Single |
| zone_name(NaiveDateTime) | -> String | The zone's name, or the offset text ("+09:00") when the name is empty |
| offset_from_abbreviation(String, NaiveDateTime) | -> FixedOffset? | The offset when the abbreviation equals the text zone_name reports (the zone's name, or the offset text for an unnamed zone), else None, so parse_date_time_in can read a %Z name back |
///|
fn[T : @core.Datelike + @core.Timelike] local_day_and_hour(
value : T,
) -> (Int, Int) {
(@core.Datelike::day(value), @core.Timelike::hour(value))
}
///|
test "a DateTime is read in its local time through the traits" {
let utc = @core.NaiveDateTime::new(
@core.NaiveDate::from_ymd(2024, 6, 15).unwrap(),
@core.NaiveTime::from_hms(20, 0, 0).unwrap(),
)
let tokyo = @tz.DateTime::from_utc(
utc,
@tz.FixedOffset::east(9 * 3600).unwrap(),
)
assert_eq(local_day_and_hour(tokyo), (16, 5))
}| Method | Signature | Description |
|---|---|---|
| DateTime::from_utc(NaiveDateTime, Tz) | -> Self[Tz] | Wrap a UTC naive datetime with the given time zone |
| DateTime::unix_epoch() | -> Self[Utc] | The Unix epoch instant, 1970-01-01T00:00:00Z; also the Default for DateTime[Utc] (no other zone has a natural default) |
| DateTime::from_local(NaiveDateTime, Tz) (Tz : TimeZone) | -> MappedLocalTime[Self[Tz]] | Build from a local (wall-clock) naive datetime, resolving DST ambiguity via tz.offset_from_local |
| DateTime::from_local_lenient(NaiveDateTime, Tz) (Tz : TimeZone) | -> Self[Tz] | Like from_local but always succeeds: an unambiguous reading resolves exactly; a fold takes its first occurrence (as earliest()); a gap is read with the offset in effect just before the transition, landing after the gap by its length (02:30 in a 02:00-03:00 gap becomes 03:30) |
| Method | Signature | Description |
|---|---|---|
| Location::load(String) | -> Self? | Look up an embedded IANA zone by name (e.g. "Asia/Tokyo"), following aliases; None if the name is unknown, including the empty string (which is not an alias for UTC); "UTC" resolves like any other zone; a zone is parsed once per name and reused by later calls |
| Location::load_system(String) | -> Self? | Like Location::load, but on native searches the directory named by $ZONEINFO, then the system zoneinfo directories (/usr/share/zoneinfo, /usr/share/lib/zoneinfo, /usr/lib/locale/TZ, /etc/zoneinfo), then the embedded database, so host tzdata newer than the embedded release takes effect. File names match as the host file system does (on a case-insensitive one, "asia/tokyo" is found, and name() keeps the given text), while the embedded database is case-sensitive. A file that is not TZif is skipped; None if no source has the zone or the name is empty, absolute, or contains ... On js, wasm and wasm-gc it is Location::load. $ZONEINFO must be a directory; zip archives are not supported. Reads live OS state |
| Location::zone_names() | -> Array[String] | The names of the embedded zones, ascending by string order; each loads through Location::load. Names the source tzdata tree linked to another zone are aliases and are not listed, though load accepts them. A new array on every call |
| Location::tzdata_version() | -> String | The IANA tz database release of the embedded snapshot (e.g. "2026c"), or "unknown" when the snapshot was generated from a tree without a +VERSION file. Location::load_system may read newer host data |
| Location::utc() | -> Self | The UTC zone as a Location (equal to Location::load("UTC"), name() is Some("UTC")), for APIs taking a Location rather than the separate Utc type |
| Location::from_tzif_bytes(Bytes) | -> Self? | Parse a zone directly from raw TZif bytes; None if malformed |
| Location::from_tzif_bytes_named(String, Bytes) | -> Self? | Like from_tzif_bytes, but name() reports the given name; any text is accepted as given, without validation |
| name() | -> String? | The IANA identifier this Location was loaded with (the name as given to Location::load, not canonicalized through an alias); None for one built via from_tzif_bytes |
| to_string() (Show) | -> String | name(), or an empty string for a Location without one |
| offset_from_abbreviation(String, NaiveDateTime) | -> FixedOffset? | The offset an abbreviation (e.g. "EST") denotes: that of the type in effect at the given UTC instant if it matches, else of the first type in the zone's table with that abbreviation; None if none has it |
| type_at(NaiveDateTime) | -> LocalTimeType | The offset, DST flag, and abbreviation in effect at a given UTC instant |
| offset_from_utc(NaiveDateTime) | -> FixedOffset | The offset in effect at a given UTC instant |
| offset_from_local(NaiveDateTime) | -> MappedLocalTime[FixedOffset] | The offset(s) for a given local instant, resolving DST folds and gaps |
| zone_name(NaiveDateTime) | -> String | The abbreviation in effect at a given instant, e.g. "EDT" |
| transition_bounds(NaiveDateTime) | -> TransitionBounds | The validity window of the segment covering a given instant; see TransitionBounds |
| Method | Signature | Description |
|---|---|---|
| start() | -> NaiveDateTime? | The instant this segment began; None if unbounded (before the zone's first recorded transition, or for a zone with no transitions at all) |
| end() | -> NaiveDateTime? | The instant the next segment begins; None if unbounded (past the zone's last recorded transition, when no POSIX rule extrapolates further) |
| Method | Signature | Description |
|---|---|---|
| LocalTimeType::new(Int, Bool, String) | -> Self? | Construct from UTC offset (seconds), DST flag, and abbreviation; None if the offset is outside ±86399 (±23:59:59), so every LocalTimeType has an offset a FixedOffset can hold |
| utc_offset() | -> Int | UTC offset in seconds |
| is_dst() | -> Bool | Whether daylight saving is in effect |
| abbreviation() | -> String | The zone abbreviation, e.g. "EST"/"EDT" |
| Backend | Source |
|---|---|
| native | $TZ or, when unset, /etc/localtime |
| js | The zone name reported by the runtime's Intl, resolved as a $TZ value would be (in practice an IANA name); $TZ is not read by this library, so whether it is honored is up to the runtime; None if the name is not in the embedded tz database |
| wasm, wasm-gc | $TZ alone; with $TZ unset there is nothing to fall back on, because these backends have no file access, so Local::new() is None; hosts that have no environment variables at all, such as a browser, therefore always give None |
| Method | Signature | Description |
|---|---|---|
| Local::new() | -> Self? | Resolves the host's configured time zone; None if it could not be determined. Reads live host state — not a pure function of its arguments. |
| Local::now() | -> DateTime[Local]? | The current instant in the host's local zone, the counterpart of Utc::now(); None when Local::new() is None, that is, when the zone cannot be determined; the clock itself is read as in Utc::now(), so with the same precision of at most one millisecond |
| offset_from_utc(NaiveDateTime) | -> FixedOffset | Delegates to the resolved zone |
| offset_from_local(NaiveDateTime) | -> MappedLocalTime[FixedOffset] | Delegates to the resolved zone |
| zone_name(NaiveDateTime) | -> String | Delegates to the resolved zone |
| Symbol | Signature | Description |
|---|---|---|
| parse_tzif(Bytes) | -> TzifData? | Parse raw TZif bytes (header, transition table, local-time-type table, leap seconds, POSIX TZ footer) |
| parse_posix_tz(String) | -> PosixTz? | Parse a POSIX TZ rule string (all three date-rule forms: Jn, n, Mm.w.d) |
| Type | Key methods | Description |
|---|---|---|
| TzifData | transitions(), transition_types(), local_time_types(), leap_seconds(), posix_tz() | The parsed contents of a TZif file; the array accessors return copies, and posix_tz() is the already-parsed PosixTz? footer (None when empty or absent; a malformed one makes parse_tzif return None) |
| PosixTz | type_at(NaiveDateTime) (a UTC reading, like Location::type_at), offset_from_local(NaiveDateTime) | An evaluated POSIX TZ rule, for extrapolating past a TZif file's last recorded transition; also a TimeZone in its own right (a constant offset when the rule has no DST part, e.g. JST-9) |
pub trait TimeZone {
fn offset_from_utc(Self, NaiveDateTime) -> FixedOffset
fn offset_from_local(Self, NaiveDateTime) -> MappedLocalTime[FixedOffset]
fn zone_name(Self, NaiveDateTime) -> String
fn is_dst(Self, NaiveDateTime) -> Bool
fn transition_bounds(Self, NaiveDateTime) -> TransitionBounds
fn offset_from_abbreviation(Self, String, NaiveDateTime) -> FixedOffset?
}fn[Tz : TimeZone] DateTime::from_local(naive_local : NaiveDateTime, tz : Tz) -> MappedLocalTime[DateTime[Tz]]fn[Tz : TimeZone] DateTime::from_local_lenient(naive_local : NaiveDateTime, tz : Tz) -> DateTime[Tz]fn[Tz : TimeZone] DateTime::from_ymd_hms(year : Int, month : Int, day : Int, hour : Int, min : Int, sec : Int, tz : Tz) -> MappedLocalTime[DateTime[Tz]]fn[Tz] DateTime::round(self : DateTime[Tz], granularity : TimeDelta) -> Result[DateTime[Tz], RoundingError]fn[Tz] DateTime::round_subsecs(self : DateTime[Tz], digits : Int) -> Result[DateTime[Tz], RoundingError]fn[Tz] DateTime::round_up(self : DateTime[Tz], granularity : TimeDelta) -> Result[DateTime[Tz], RoundingError]fn[Tz] DateTime::truncate(self : DateTime[Tz], granularity : TimeDelta) -> Result[DateTime[Tz], RoundingError]fn[Tz : TimeZone] DateTime::with_day(self : DateTime[Tz], day : Int) -> MappedLocalTime[DateTime[Tz]]fn[Tz : TimeZone] DateTime::with_day0(self : DateTime[Tz], day0 : Int) -> MappedLocalTime[DateTime[Tz]]fn[Tz : TimeZone] DateTime::with_hour(self : DateTime[Tz], hour : Int) -> MappedLocalTime[DateTime[Tz]]fn[Tz : TimeZone] DateTime::with_minute(self : DateTime[Tz], minute : Int) -> MappedLocalTime[DateTime[Tz]]fn[Tz : TimeZone] DateTime::with_month(self : DateTime[Tz], month : Int) -> MappedLocalTime[DateTime[Tz]]fn[Tz : TimeZone] DateTime::with_month0(self : DateTime[Tz], month0 : Int) -> MappedLocalTime[DateTime[Tz]]fn[Tz : TimeZone] DateTime::with_nanosecond(self : DateTime[Tz], nanosecond : Int) -> MappedLocalTime[DateTime[Tz]]fn[Tz : TimeZone] DateTime::with_ordinal(self : DateTime[Tz], ordinal : Int) -> MappedLocalTime[DateTime[Tz]]fn[Tz : TimeZone] DateTime::with_ordinal0(self : DateTime[Tz], ordinal0 : Int) -> MappedLocalTime[DateTime[Tz]]fn[Tz : TimeZone] DateTime::with_second(self : DateTime[Tz], second : Int) -> MappedLocalTime[DateTime[Tz]]fn[Tz : TimeZone] DateTime::with_year(self : DateTime[Tz], year : Int) -> MappedLocalTime[DateTime[Tz]]impl TimeZone for FixedOffsetimpl Show for FixedOffsetfn FixedOffset::offset_from_abbreviation(_self : FixedOffset, _abbreviation : String, _near : NaiveDateTime) -> FixedOffset?fn FixedOffset::offset_from_local(self : FixedOffset, _dt : NaiveDateTime) -> MappedLocalTime[FixedOffset]fn offset_from_abbreviation(self : FixedZone, abbreviation : String, _near : NaiveDateTime) -> FixedOffset?fn FixedZone::offset_from_abbreviation(self : FixedZone, abbreviation : String, _near : NaiveDateTime) -> FixedOffset?fn FixedZone::offset_from_local(self : FixedZone, _dt : NaiveDateTime) -> MappedLocalTime[FixedOffset]pub struct Local {
// private fields
}fn offset_from_abbreviation(self : Local, abbreviation : String, near : NaiveDateTime) -> FixedOffset?fn Local::offset_from_abbreviation(self : Local, abbreviation : String, near : NaiveDateTime) -> FixedOffset?fn Local::offset_from_local(self : Local, naive_local : NaiveDateTime) -> MappedLocalTime[FixedOffset]fn offset_from_abbreviation(self : Location, abbreviation : String, near : NaiveDateTime) -> FixedOffset?fn Location::offset_from_abbreviation(self : Location, abbreviation : String, near : NaiveDateTime) -> FixedOffset?fn Location::offset_from_local(self : Location, naive_local : NaiveDateTime) -> MappedLocalTime[FixedOffset]fn offset_from_abbreviation(self : PosixTz, abbreviation : String, _near : NaiveDateTime) -> FixedOffset?fn PosixTz::offset_from_abbreviation(self : PosixTz, abbreviation : String, _near : NaiveDateTime) -> FixedOffset?fn PosixTz::offset_from_local(self : PosixTz, naive_local : NaiveDateTime) -> MappedLocalTime[FixedOffset]fn Utc::offset_from_abbreviation(_self : Utc, _abbreviation : String, _near : NaiveDateTime) -> FixedOffset?Install
Download zipA date and time library for MoonBit