This library is a wrapper around ICU4X’ datetime
formatting for Typst which provides internationalized formatting for dates, times, and timezones.
As the WASM bundle includes all localization data, it’s quite large (about 8 MiB).
Example
#import "@preview/icu-datetime:0.1.0": fmt-date, fmt-time, fmt-datetime, experimental
// These functions may change at any time
#import experimental: fmt-timezone, fmt-zoned-datetime
#let day = datetime(
year: 2024,
month: 5,
day: 31,
)
#let time = datetime(
hour: 18,
minute: 2,
second: 23,
)
#let dt = datetime(
year: 2024,
month: 5,
day: 31,
hour: 18,
minute: 2,
second: 23,
)
#fmt-date(day, locale: "de", length: "full") \
#fmt-time(time, locale: "de", length: "medium") \
#fmt-datetime(dt, locale: "fi", date-length: "full") \
#fmt-timezone(
"-07",
iana: "America/Los_Angeles",
local-date: dt,
zone-variant: "st",
includes: "specific-non-location-long"
) \
#fmt-zoned-datetime(
dt,
(
offset: "-07",
iana: "America/Los_Angeles",
zone-variant: "st", // standard
)
)
API
fmt-date
#let fmt-date(
dt,
locale: "en",
length: "full"
)
Formats a date in some locale
. Dates are assumed to be ISO dates.
dt
: The date to format. This can be adatetime
or a dictionary withyear
,month
,day
.locale
: A Unicode Locale Identifier.length
: The length of the formatted date (“full”, “long” (default), “medium”, “short”, ornone
).
fmt-time
#let fmt-time(
dt,
locale: "en",
length: "short"
)
Formats a time in some locale
.
dt
: The time to format. This can be adatetime
or a dictionary withhour
,minute
,second
, and (optionally)nanosecond
.locale
: A Unicode Locale Identifier.length
: The length of the formatted time (“medium”, “short” (default), ornone
).
fmt-datetime
#let fmt-datetime(
dt,
locale: "en",
date-length: "long",
time-length: "short"
)
Formats a date and time in some locale
. Dates are assumed to be ISO dates.
dt
: The date and time to format. This can be adatetime
or a dictionary withyear
,month
,day
,hour
,minute
,second
, and (optionally)nanosecond
.locale
: A Unicode Locale Identifier.date-length
: The length of the formatted date part (“full”, “long” (default), “medium”, “short”, ornone
).time-length
: The length of the formatted time part (“medium”, “short” (default), ornone
).
fmt-timezone
⚠ Warning: This function is experimental and can change at any time.
#let fmt-timezone(
offset,
iana: none,
bcp47: none,
local-date: none,
metazone-id: none,
zone-variant: none,
locale: "en",
fallback: "localized-gmt",
includes: ()
)
Formats a timezone in some locale
.
-
offset
: A string specifying the GMT offset (e.g. “-07”, “Z”, “+05”, “+0500”, “+05:00”) -
iana
: Name of the IANA TZ identifier (e.g. “Brazil/West” - see IANA and Wikipedia). This is mutually exclusive withbcp47
. This identifier will be converted to a BCP-47 ID. -
bcp47
: Name of the BCP-47 timezone ID (e.g. “iodga” - see timezone.xml). This is mutually exclusive withiana
. -
local-date
: A local date to calculate the metazone-id. This is mutually exclusive withmetazone-id
. When formatting zoned-datetimes this isn’t necessary. -
metazone-id
: A short ID of the metazone. A metazone is a collection of multiple time zones that share the same localized formatting at a particular date and time (e.g. “phil” - see metaZones.xml (bottom)). -
zone-variant
: Many metazones use different names and offsets in the summer than in the winter. In ICU4X, this is called the zone variant. Supportsnone
,"st"
(standard), and"dt"
(daylight). -
locale
: A Unicode Locale Identifier -
fallback
: The timezone format fallback. Either"LocalizedGmt"
or a dictionary for an ISO 8601 fallback (e.g.(iso8601: (format: "basic", minutes: "required", seconds: "never"))
). -
includes
: An array or a single item (str/dictionary) of part(s) to include - corresponds to calls onTimeZoneFormatter
. Valid options are:generic-location-format
(e.g. “Los Angeles Time”)generic-non-location-long
(e.g. “Pacific Time”)generic-non-location-short
(e.g. “PT”)localized-gmt-format
(e.g. “GMT-07:00”)specific-non-location-long
(e.g. “Pacific Standard Time”)specific-non-location-short
(e.g. “PDT”)iso8601
: A dictionary of ISO 8601 options(iso8601: (format: "utc-basic", minutes: "optional", seconds: "optional"))
(e.g. “-07:00”)
fmt-zoned-datetime
⚠ Warning: This function is experimental and can change at any time.
#let fmt-zoned-datetime(
dt,
zone,
locale: "en",
fallback: "localized-gmt",
date-length: "long",
time-length: "long"
)
Formats a date and a time in a timezone. Dates are assumed to be ISO dates.
dt
: The date and time to format. This can be adatetime
or a dictionary withyear
,month
,day
,hour
,minute
,second
, and (optionally)nanosecond
.zone
: The timezone. A dictionary withoffset
,iana
,bcp47
,metazone-id
, andzone-variant
. The options correspond to the arguments forfmt-timezone
. Onlyoffset
is mandatory - the other fields provide supplemental information for named timezones.locale
: A Unicode Locale Identifierfallback
: The timezone format fallback. Either"localized-gmt"
or a dictionary for an ISO 8601 fallback (e.g.(iso8601: (format: "basic", minutes: "required", seconds: "never"))
).date-length
: The length of the formatted date part (“full”, “long” (default), “medium”, “short”, ornone
).time-length
: The length of the formatted time part (“full”, “long” (default), “medium”, “short”, ornone
).
Using Locally
Download the latest release, unzip it to your local Typst packages, and use #import "@local/icu-datetime:0.1.0"
.
Building
To build the library, you need to have Rust, Deno, and wasm-opt
installed.
deno task build
While developing, you can symlink the WASM file into the root of the repository (it’s in the .gitignore
):
# Windows (PowerShell)
New-Item icu-datetime.wasm -ItemType SymbolicLink -Value ./target/wasm32-unknown-unknown/debug/icu_typ.wasm
# Unix
ln -s ./target/wasm32-unknown-unknown/debug/icu_typ.wasm icu-datetime.wasm
Use cargo b --target wasm32-unknown-unknown
to build in debug mode.