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
dthas date fields (year,month,day), thendate-fieldswill be set to"YMD" - If
dthas time fields (hour,minute,second), thentime-precisionwill be set to"minute" - If
zonehas a value, thenzone-stylewill 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-fieldsis 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-precisionis 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-stylesis 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-stylesis 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")