gtz
Simple Gleam time zone conversions for all targets, built on top of tzif.
Converting an ambiguous calendar time to a timestamp
assumes the first occurrence of the ambiguous time. Accounting for [the
current 27] leap seconds depends on the host’s dataset. If you need more
control over where the time zone data comes from, how ambiguous dates
are handled, how leap seconds are accounted for, or the designation of the
given time in the zone, use the very nice tzif and/or zones packages
directly.
import gleam/time/timestamp
import gtz
let zone_name = gtz.local_name() // "Asia/Kolkata"
let assert Ok(zone) = gtz.build(zone_name)
timestamp.from_unix_seconds(1_729_257_776)
|> gtz.to_calendar(zone)
// -> #(
// calendar.Date(2024, calendar.October, 18),
// calendar.TimeOfDay(18, 52, 56, 0),
// duration.seconds(19_800),
// )
Types
Values
pub fn build(name: String) -> Result(TimeZone, Nil)
Build a TimeZone from an IANA zone name such as "America/New_York".
Returns an error if the name is not a zone the host recognizes.
On the Erlang target, the operating system’s TZif database at
/usr/share/zoneinfo is read once and memoized into a persistent term.
In bare environments where the host has no zoneinfo, the prebuilt zones
database is used as a fallback. On JavaScript, information for the given
zone is derived from the host’s native Temporal and Intl APIs.
Examples
gtz.local_name() |> gtz.build
// -> Ok(TimeZone)
gtz.build("Asia/Kolkata")
// -> Ok(TimeZone)
gtz.build("America/NewYork") // "New_York" is the correct name here
// -> Error(Nil)
pub fn from_calendar(
date: calendar.Date,
time: calendar.TimeOfDay,
zone: TimeZone,
) -> Result(timestamp.Timestamp, Nil)
Convert a date and time of day in zone to a timestamp. When you know
the offset, always prefer the timestamp.from_calendar in gleam_time
over this function.
When the time is ambiguous in the given time zone because of an offset
change such as daylight saving time, the timestamp that corresponds with
the first occurrence of that time is returned. When the time does not exist
in the given time zone because of an offset change such as daylight saving
time, Error(Nil) is returned.
Examples
let assert Ok(zone) = gtz.build("Australia/Lord_Howe")
// Clocks go back half an hour at 02:00, so 01:30 to 01:59 happens twice
gtz.from_calendar(
calendar.Date(2025, calendar.April, 6),
calendar.TimeOfDay(1, 45, 0, 0),
zone,
)
// -> Ok(Timestamp(1_743_864_300, 0)), the earlier of the two timestamps
// Clocks go forward from 02:00 to 02:30, so 02:15 never happens
gtz.from_calendar(
calendar.Date(2025, calendar.October, 5),
calendar.TimeOfDay(2, 15, 0, 0),
zone,
)
// -> Error(Nil)
pub fn local_name() -> String
Returns the name of the host system’s time zone.
Examples
gtz.local_name()
// -> "Pacific/Auckland"
On the Erlang target the zone is read from the operating system, in order:
the TZ environment variable, the symlink target of /etc/localtime, then
/etc/timezone or /etc/sysconfig/clock. If none of those yield an IANA
zone name, "UTC" is returned. On JavaScript the host’s Intl API is used.
pub fn to_calendar(
timestamp: timestamp.Timestamp,
zone: TimeZone,
) -> #(calendar.Date, calendar.TimeOfDay, duration.Duration)
Convert a timestamp to the equivalent date, time of day, and UTC offset in the given time zone.
Examples
let assert Ok(zone) = gtz.build("Asia/Kathmandu")
// Not every zone is a whole number of hours from UTC
timestamp.from_unix_seconds(1_729_257_776)
|> gtz.to_calendar(zone)
// -> #(
// calendar.Date(2024, calendar.October, 18),
// calendar.TimeOfDay(19, 7, 56, 0),
// duration.seconds(20_700),
// )