parseDateTimeWithPattern
Signature
Section titled “Signature”parseDateTimeWithPattern(value: string, pattern: string, locale?: string | string[], options?: TwoDigitYearOptions): stringParse a datetime string against a caller-supplied token pattern (e.g. "MM/dd/yyyy HH:mm:ss", "dd-MMM-yyyy h:mm a") and return it as an ISO PlainDateTime string.
-
Decoding, not display. This is for consuming a known, fixed producer format — a CSV column, a legacy API field, a partially-typed form value — not for generating locale-correct output. For display, use
formatDateTime/formatDateToParts, which order fields per locale instead of hard-coding a field order (a token formatter, the inverse of this function, is deliberately out of scope for GMT). -
Accepts the full combined date + time token set (unlike
parseDateWithPattern/parseTimeWithPattern, which each reject the other’s tokens). ### Token tableToken Field Width Range Notes yyyyyear 4 digits 0000–9999 yyyear 2 digits 00–99 Needs options.yearWindow; returns""without itMMmonth 2 digits 01–12 Mmonth 1-2 digits 1–12 MMMMmonth name (long) locale — getLocaleMonthNames(locale, "long")MMMmonth name (short) locale — getLocaleMonthNames(locale, "short")ddday 2 digits 01–31 dday 1-2 digits 1–31 HHhour (24h) 2 digits 00–23 Hhour (24h) 1-2 digits 0–23 hhhour (12h) 2 digits 01–12 needs ato resolve to 24h — see belowhhour (12h) 1-2 digits 1–12 same mmminute 2 digits 00–59 mminute 1-2 digits 0–59 sssecond 2 digits 00–59 ssecond 1-2 digits 0–59 SSSmillisecond 3 digits 000–999 EEEEweekday name (long) locale — consumed, NOT cross-validated against the date (see below) EEEweekday name (short) locale — same ameridiem locale — getLocaleMeridiems(locale)→[AM-label, PM-label]GGGGera name (long) locale — BCE label ⇒ final year = 1 − parsed year GGera name (short) locale — same resolution -
Literal text follows the Unicode UTS #35 date format pattern rules. Text in
'single quotes'is a literal, letters included. Two adjacent quotes''are one literal', inside or outside quoted text:"yyyy''MM"reads"2024'03", and"'o''clock'"reads"o'clock". A quote that never closes makes the pattern malformed (""). Any other character that is not a letter (/ - , space :, digits and so on) is a literal with no quoting. -
MMMM/MMM/EEEE/EEE/a/GGGG/GGare locale-aware. Iflocaleis omitted and the pattern uses any of them, GMT defaults to"en-US"rather than returning""for every caller who didn’t have another locale in mind. -
EEEE/EEEare matched against the locale’s weekday names but the result is not cross-checked against the constructed date — e.g."Monday, 2024-03-15 14:00"parses successfully against"EEEE, yyyy-MM-dd HH:mm"even though 2024-03-15 is actually a Friday. This is a deliberate scope limit (no second weekday-index-to-ISO-dayOfWeek mapping layer). -
h/hhresolve to 24-hour using a matchedatoken: if the label is the PM label and hour !== 12, add 12; if the AM label and hour === 12, set hour to 0. With noatoken in the pattern at all, the pattern is still valid but the hour stays ambiguous — GMT resolves it as if AM had matched (12 → 0, otherwise unchanged). -
Adjacent variable-width numeric tokens with no literal separator (e.g.
"Mdyyyy") are inherently ambiguous: each becomes a greedy\d{1,2}/etc. in sequence, so the split between fields depends on regex backtracking, not on any documented rule. Prefer zero-padded tokens (MM,dd) or an explicit separator for reliable parsing. -
A shape-valid match does not by itself prove a real date/time: extracted fields are always handed to
Temporal.PlainDateTime.from(fields, { overflow: "reject" })— the regex only proves the shape, Temporal proves the value is real. -
Fields absent from
patterndefault the wayTemporal.PlainDateTime.fromdefaults an omitted field (time fields default to0;year/month/dayare still required for a valid result). -
A
yytoken needs the caller’s hundred-year window,options.yearWindow: no standard says which century a two-digit year belongs to, and a cut-off built into a library is right today and wrong later. Without a valid window ayypattern returns"". A pattern with noyynever reads the option, so a"rolling"window reads no clock for it. A two-digit year is a legacy form; a four-digit year is the one to ask a data source for.
Parameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
value | string | The string to decode (e.g. “03/15/2024 14:30:00”) |
pattern | string | The token pattern describing value’s shape (e.g. “MM/dd/yyyy HH:mm:ss”) |
locale | string | string[] | Optional BCP 47 locale tag, or a preference list of tags, for name-based tokens (default “en-US”) |
Options
Section titled “Options”options
The hundred-year window a yy token resolves in
Type: TwoDigitYearOptions.
| Option | Type | Default | Description |
|---|---|---|---|
yearWindow? | number | "rolling" | None. A value with a two-digit year returns the sentinel: no standard says which century it belongs to, so the caller states it. | The hundred-year window a two-digit year falls in. A number is the first year of a fixed window, an integer from 0 to 9900: 2000 reads 00–99 as 2000–2099; 1950 reads 50–99 as 1950–1999 and 00–49 as 2000–2049. A fixed window gives the same answer in any year, so it is the form for stored data, archives and anything re-processed later. "rolling" is the hundred years around today: from 50 years before the current UTC calendar year to 49 years after it (in 2026, 1976–2075). It is the form for live messages and never needs maintenance, but it gives a different answer for the same stored value as years pass. Any other value returns the function’s sentinel. |
Returns
Section titled “Returns”ISO PlainDateTime string, or "" on no match, malformed pattern, or invalid input
Related types
Section titled “Related types”Examples
Section titled “Examples”import { parseDateTimeWithPattern } from "@northguild/gmt/plain/parse";
parseDateTimeWithPattern("03/15/2024 14:30:00", "MM/dd/yyyy HH:mm:ss") // "2024-03-15T14:30:00"