fmt
- Format Date and Time¶
import "@preview/icu-datetime:0.2.0" as icu
let fmt(
dt,
zone: none,
locale: "en",
length: none,
date-fields: auto,
time-precision: auto,
zone-style: auto,
alignment: none,
year-style: none,
)
Formats a date and time in some locale
. Dates are assumed to be ISO dates.
Defaults¶
The function tries to infer the intended format automatically if date-fields
, time-precision
, and zone-style
all use their default values (auto
):
- If
dt
has date fields (year
,month
,day
), thendate-fields
will be set to"YMD"
- If
dt
has time fields (hour
,minute
,second
), thentime-precision
will be set to"minute"
- If
zone
has a value, thenzone-style
will be set to"localized-offset-short"
Arguments¶
dt
¶
The date and time to format. This can be a datetime
or a dictionary with year
, month
, day
, hour
, minute
, second
, and (optionally) nanosecond
.
Example
zone
¶
A zone passed as a dictionary with offset
(required), bcp47
or iana
.
offset
: The UTC offset either specified as a string (e.g."+05"
) or as an integer specifying the seconds (18000
).bcp47
: BCP-47 timezone ID (e.g."iodga"
(IANA: Indian/Chagos) - see timezone.xml). This is mutually exclusive withiana
.iana
: IANA TZ identifier (e.g."Brazil/West"
- see IANA and Wikipedia). This is mutually exclusive withbcp47
.
If zones are formatted on their own, dt
can be an empty dictionary ((:)
). However, when specified, the date and time will still be used to resolve the zone variant (standard/daylight). Otherwise, the standard variant will be used. Note that this doesn't resolve the variant at the specified date but the variant at the specified offset
.
Example
#let f(tz) = icu.fmt(
datetime.today(), // (1)!
zone: tz,
zone-style: "specific-long"
)
- #f((offset: "+04"))
- #f((offset: "+04", iana: "Asia/Baku"))
- #f((offset: "+04", bcp47: "azbak"))
- #f((offset: "+04", bcp47: "aedxb"))
- #f((offset: "-09:30"))
- #f((offset: "-09:30", iana: "Pacific/Marquesas"))
- Date specified to resolve zone variants.
locale
¶
The locale to use when formatting the datetime. A Unicode Locale Identifier. Notably, this can be used to set the calendar by setting ca
to a bcp47 calendar name.
Example
#let dt = datetime(
year: 2024,
month: 5,
day: 31,
hour: 18,
minute: 2,
second: 23,
)
- #icu.fmt(dt, locale: "en")
- #icu.fmt(dt, locale: "ko")
- #icu.fmt(dt, locale: "en-TH")
- #icu.fmt(dt, locale: "mk")
- #icu.fmt(dt, locale: "so")
- #icu.fmt(dt, locale: "fo")
- #icu.fmt(dt, locale: "vi")
- #icu.fmt(dt, locale: "vi-u-ca-buddhist")
length
¶
The length of the formatted string ("long"
, "medium"
(default), or "short"
).
The avialable options are also provided in length
as a dictionary.
Example
#let dt = datetime(
year: 2024,
month: 5,
day: 31,
hour: 18,
minute: 2,
second: 23,
)
*Long*
- #icu.fmt(dt, length: "long")
- #icu.fmt(dt, length: "long", locale: "hi")
- #icu.fmt(dt, length: "long", locale: "da")
*Medium*
- #icu.fmt(dt, length: "medium")
- #icu.fmt(dt, length: "medium", locale: "ja")
- #icu.fmt(dt, length: "medium", locale: "pt")
*Short*
- #icu.fmt(dt, length: "short")
- #icu.fmt(dt, length: "short", locale: "bn")
- #icu.fmt(dt, length: "short", locale: "az")
date-fields
¶
he fields of the date to include in the formatted string. "D"
(day of month), "MD"
, "YMD"
, "DE"
, "MDE"
, "YMDE"
, "E"
(weekday), "M"
(month), "YM"
, "Y"
(year), none
, or auto
(default, see defaults).
The avialable options are also provided in date-fields
as a dictionary.
Example
#table(
columns: 2,
[`date-fields`], [Output],
..icu
.date-fields // (1)!
.values()
.map(v => (
v,
icu.fmt(
(year: 2024, month: 5, day: 31),
date-fields: v,
length: "long",
),
))
.flatten()
)
date-fields
is a dictionary that contains all possible values fordate-fiels
.
time-precision
¶
How precise to display the time. "hour"
, "minute"
, "second"
, "subsecond{n}"
(n subsecond digits), "minute-optional"
("hour"
if minutes == 0
, otherwise "minute"
), none
, or auto
(default, see defaults).
The avialable options are also provided in time-precision
as a dictionary.
Example
#table(
columns: 3,
[`time-precision`], [American English], [British English],
..icu
.time-precision // (1)!
.values()
.map(style => (
style,
("en-US", "en-GB")
.map(locale => icu.fmt(
(hour: 16, minute: 0, second: 3, nanosecond: 123456789),
time-precision: style,
locale: locale,
))
.flatten(),
))
.flatten()
)
time-precision
is a dictionary that contains all possible values fortime-precision
.
zone-style
¶
How to format the timezone (if any). "specific-long"
, "specific-short"
, "localized-offset-long"
, "localized-offset-short"
, "generic-long"
, "generic-short"
, "location"
, "exemplar-city"
, none
, or auto
(default, see defaults).
The avialable options are also provided in zone-styles
as a dictionary.
Example
#table(
columns: 4,
[`zone-style`], [English], [Indonesian], [Japanese],
..icu
.zone-styles // (1)!
.values()
.map(style => (
style,
("en", "id", "jp")
.map(locale => icu.fmt(
datetime.today(),
zone: (offset: "+08", iana: "Asia/Makassar"),
zone-style: style,
locale: locale,
))
.flatten(),
))
.flatten()
)
zone-styles
is a dictionary that contains all possible values forzone-style
.
alignment
¶
How to align (pad) the formatted string. "auto"
, "column"
, or none
(default, implies "auto"
).
The avialable options are also provided in alignment
as a dictionary.
Example
year-style
¶
How to format the year and the era. "auto"
, "full"
, "with-era"
, none
(default, implies "auto"
).
The avialable options are also provided in year-styles
as a dictionary.
Example
#table(
columns: 5,
[`year-style`], [2024], [-128], [1984], [1847],
..icu
.year-styles // (1)!
.values()
.map(style => (
style,
..(2024, -128, 1984, 1847).map(y => icu.fmt(
(year: y, month: 1, day: 1),
date-fields: "Y",
year-style: style,
length: "short",
)),
))
.flatten()
)
year-styles
is a dictionary that contains all possible values foryear-style
.
experimental-pattern
¶
Specifies the pattern to format that date as. This is mutually exclusive with all other named arguments except zone
and locale
.
Warning
This argument is experimental - it might be put into its own function in the future. The calendar selection is implemented manually due to missing functionality in ICU4X (It's in my backlog to try and add it there). This is a low-level utility that assumes the pattern is already localized for the target locale.
The full list of placeholders can be found in the Date Field Symbol Table. Note that this argument doesn't check that the date and time are fully specified. If some fields are left out, they're default initialized.
The following symbols are unsupported by ICU4X: Y+
(year in "week of year"), u+
, Q+
, q+
, w+
, W+
, g+
, e
/ee
/c
/cc
(numeric week), B+
, k+
, j+
, J+
, C+
, S+
, and VV
.
Example
#let dt = datetime(
year: 2024,
month: 5,
day: 31,
hour: 18,
minute: 2,
second: 23,
)
#let tz = (offset: "+09", iana: "Pacific/Palau")
#let f(l, pat) = icu.fmt(dt, zone: tz, locale: l, experimental-pattern: pat)
+ #f("en", "yyyy.MM.dd G 'at' HH:mm:ss zzz")
+ #f("th-TH", "EEE, MMM d, ''yy")
+ #f("en", "h:mm a")
+ #f("nl", "hh 'o''clock' a, zzzz")
+ #f("gn", "K:mm a, z")
+ #f("en-AF", "yyyyy.MMMM.dd GGG hh:mm aaa")
+ #f("en", "y-MM-dd hh:mm a zzzz")