Skip to content

formatDateTimeToParts

formatDateTimeToParts(value: string, locale?: string | string[], options?: DateTimeFormatOptions): { type: string; value: string; }[]

Return the locale-formatted parts of a PlainDateTime.

  • This is GMT’s substitute for a token formatter (Luxon toFormat, date-fns format). A token pattern hard-codes field order and ships US ordering to every locale; formatToParts gives the caller full control over presentation while the locale keeps control of order.
  • Each part is { type, value } where type can be: "era", "year", "relatedYear", "yearName", "month", "day", "weekday", "hour", "minute", "second", "fractionalSecond", "dayPeriod", "literal".
  • A lunisolar calendar adds two more: zh-u-ca-chinese and ko-u-ca-dangi emit "relatedYear" (the Gregorian year the cycle falls in) and "yearName" (the sexagenary cycle name) in place of, or beside, "year". Code that looks up a "year" part must handle their absence.
  • The caller should iterate the array as returned; reassembling in a fixed order reintroduces exactly the bug formatToParts exists to avoid.
  • With no date/time field and no dateStyle/timeStyle, year, month, day, hour, minute and second default to "numeric" (ECMA-402 as amended by Temporal), so the parts rebuild exactly what Temporal.PlainDateTime#toLocaleString returns for the same value.
  • A zoneless value never yields a "timeZoneName" part (Temporal’s PlainDateTime format has no zone field): a timeZoneName option is ignored, and a "long"/"full" timeStyle keeps its hour, minute and second and drops the zone, formatting as the locale’s "medium" time. As in Intl.DateTimeFormat, timeZoneName together with dateStyle/timeStyle yields [].
  • The literal before the day period depends on the runtime. CLDR 42 (ICU 72) put U+202F NARROW NO-BREAK SPACE there for en-US; Node 22 and 24 return it in the parts, and Node 26 returns an ordinary space (U+0020) instead. Both were checked on those runtimes. The examples show the Node 22 and 24 form, written as "\u202f" so the difference is visible. Treat the two characters as equal when you compare parts.
  • Returns [] for invalid input.
  • Compatibility: before 1.16.0 a call with no field options returned only the date parts. Pass { year: "numeric", month: "numeric", day: "numeric" } to keep that output.
  • Compatibility: before 1.16.0 a "long"/"full" timeStyle added the internal UTC anchor as a timeZoneName part. formatZonedToParts on the value at UTC returns those parts.
  • options null returns [], as ECMA-402’s CoerceOptionsToObject rejects it. Any other non-object — a string, a number, a boolean — formats with the defaults, as Intl.DateTimeFormat does: CoerceOptionsToObject calls ToObject on it and the wrapper carries no recognised option. Only null and undefined are special-cased.
ParameterTypeDescription
valuestringISO PlainDateTime string
localestring | string[]optional BCP 47 locale identifier (default: runtime default), or a preference list of tags (ECMA-402)

options

optional Intl.DateTimeFormatOptions

Type: DateTimeFormatOptions.

OptionTypeDefaultDescription
…Intl.DateTimeFormatOptions——Every field of DateTimeFormatOptions, as ECMA-402 defines it.

array of { type, value } parts, or [] on invalid input

Members of each item

MemberTypeDescription
typestringThe kind of part, named as ECMA-402 Intl.DateTimeFormat.prototype.formatToParts names it: a field such as "year", "month" or "day", or "literal" for the separator text between fields.
valuestringThe text of the part in the requested locale, exactly as the formatter wrote it. Joining every value in array order gives the whole formatted text.
import { formatDateTimeToParts } from "@northguild/gmt/plain/format";
formatDateTimeToParts("2024-03-15T14:30:00", "en-US") // [{ type: "month", value: "3" }, { type: "literal", value: "/" }, { type: "day", value: "15" }, { type: "literal", value: "/" }, { type: "year", value: "2024" }, { type: "literal", value: ", " }, { type: "hour", value: "2" }, { type: "literal", value: ":" }, { type: "minute", value: "30" }, { type: "literal", value: ":" }, { type: "second", value: "00" }, { type: "literal", value: "\u202f" }, { type: "dayPeriod", value: "PM" }]
output 

plain/format/formatDateTimeToParts.ts