Parsing
Use these functions when you need to read a single field out of an existing ISO string, or when you’re decoding a non-ISO producer format into GMT’s canonical shape.
Extract a component from an ISO string
Section titled “Extract a component from an ISO string”import { parseYearFromDate, parseMonthFromDate, parseDayFromDate, parseHourFromTime, parseMinuteFromTime, parseSecondFromTime,} from "@northguild/gmt";
parseYearFromDate("2024-03-15"); // "2024"parseMonthFromDate("2024-03-15"); // "03"parseDayFromDate("2024-03-15"); // "15"parseHourFromTime("14:30:45"); // "14"parseMinuteFromTime("14:30:45"); // "30"parseSecondFromTime("14:30:45"); // "45"These return zero-padded strings (sentinel ""), not numbers. Months are
1-indexed (matching the Temporal spec): "03" is March, so convert with Number and
subtract 1 before using it as an array index.
A year is written as Temporal writes it: four digits from 0000 to 9999, and a sign and six
digits outside that range. Every function that returns a year does this, the "year" unit
of parseUnitFromDate and its siblings included:
import { parseUnitFromDate, parseYearFromDate } from "@northguild/gmt";
parseYearFromDate("0005-06-01"); // "0005"parseYearFromDate("+010000-01-01"); // "+010000"parseYearFromDate("-000005-01-01"); // "-000005"parseUnitFromDate("0005-06-01", "year"); // "0005"There are parse*FromDateTime siblings for datetime strings, plus
parseDayOfWeekFromDate and parseWeekFromDate, which return numbers (sentinel null).
Calendar quantities (derived, not stored)
Section titled “Calendar quantities (derived, not stored)”These compute a derived quantity rather than extracting a stored field, so they
live in calculate/, not parse/:
import { getDaysInMonth, getDaysInYear, getDayOfYear, getWeeksInYear, getWeeksInMonth, getWeekOfMonth, getWeekYear, getLocaleWeekYear,} from "@northguild/gmt";
getDaysInMonth("2024-02-15"); // 29 (leap year)getDayOfYear("2024-03-01"); // 61getWeekYear("2024-12-30"); // 2025 — ISO week-numbering yeargetWeeksInMonth("2024-02-15", "en-US"); // 5 — calendar-grid rowsParse a fixed producer format against a token pattern
Section titled “Parse a fixed producer format against a token pattern”parseDateWithPattern/parseDateTimeWithPattern/parseTimeWithPattern decode a
known, fixed non-ISO producer format — a CSV column, a legacy API field, a
partially-typed form value — against a caller-supplied token pattern. This is for
decoding, not display: the pattern hard-codes the field order, so formatDate and
formatDateToParts remain the right choice for locale-correct output:
import { parseDateWithPattern, parseDateTimeWithPattern, parseTimeWithPattern,} from "@northguild/gmt";
parseDateWithPattern("03/15/2024", "MM/dd/yyyy"); // "2024-03-15"parseDateTimeWithPattern("15-Mar-2024 14:30", "dd-MMM-yyyy HH:mm"); // "2024-03-15T14:30:00"parseTimeWithPattern("02:30:45 PM", "hh:mm:ss a"); // "14:30:45"parseDateWithPattern("02/31/2024", "MM/dd/yyyy"); // "" — shape-valid, not a real dateThe regex only proves shape; Temporal.*.from(..., { overflow: "reject" }) proves
the value is real. All three return "" on no match, a malformed pattern, or a
shape-valid-but-unreal date/time.
Tokens
Section titled “Tokens”| Tokens | Reads |
|---|---|
yyyy MM dd HH mm ss SSS | fixed-width fields |
M d H h m s | variable-width fields |
MMMM MMM EEEE EEE a GGGG GG | locale-aware names |
'single quotes' | literal text |
Two single quotes in a row are one literal quote, inside or outside quoted text, as UTS #35 reads them:
import { parseDateWithPattern } from "@northguild/gmt";
parseDateWithPattern("'2024-01-15'", "''yyyy-MM-dd''");// "2024-01-15" — the pattern's '' is a literal ' on each sideA locale parameter (default "en-US") controls name-token matching:
parseDateWithPattern("15. März 2024", "dd. MMMM yyyy", "de-DE");// "2024-03-15"Two-digit years
Section titled “Two-digit years”A yy token needs your own hundred-year window, options.yearWindow. No standard says
which century a two-digit year belongs to, so without a window a yy pattern returns "".
A number is the first year of a fixed window. "rolling" is the hundred years around the
current UTC year:
parseDateWithPattern("24-03-15", "yy-MM-dd", "en-US", { yearWindow: 2000 });// "2024-03-15" — a window starting in 2000 reads 24 as 2024
parseDateWithPattern("99-03-15", "yy-MM-dd", "en-US", { yearWindow: 1950 });// "1999-03-15" — a window starting in 1950 reads 99 as 1999 ...
parseDateWithPattern("24-03-15", "yy-MM-dd", "en-US", { yearWindow: 1950 });// "2024-03-15" — ... and 24 as 2024
parseDateWithPattern("24-03-15", "yy-MM-dd");// "" — no window, no answerParse a named machine format (email, HTTP, SQL, RFC 3339)
Section titled “Parse a named machine format (email, HTTP, SQL, RFC 3339)”These four return "" on invalid input (they produce a whole datetime string, not
a number), matching the sentinel convention of their format* counterparts:
import { parseRfc2822, parseHttpDate, parseSqlDateTime, parseRfc3339 } from "@northguild/gmt";
parseRfc2822("Fri, 15 Mar 2024 14:30:00 -0400");// "2024-03-15T14:30:00-04:00[-04:00]"
parseHttpDate("Fri, 15 Mar 2024 14:30:00 GMT");// "2024-03-15T14:30:00Z"
parseHttpDate("Sun Nov 6 08:49:37 1994");// "1994-11-06T08:49:37Z" — also reads the obsolete rfc850-date and asctime-date forms
parseSqlDateTime("2024-03-15 14:30:00");// "2024-03-15T14:30:00"parseSqlDateTime("2024-03-15 14:30");// "" — the SQL literal grammar requires seconds, and a year of 0001–9999
parseRfc3339("2024-03-15T14:30:00-04:00");// "2024-03-15T14:30:00-04:00[-04:00]"A receiver reads RFC 5322’s full and obsolete syntax: comments, any letter case, two-digit
years and zone names. A day name that contradicts the date returns "":
parseRfc2822("fri,15 Mar 24 14:30 -0400 (EDT)");// "2024-03-15T14:30:00-04:00[-04:00]"
parseRfc2822("Sat, 15 Mar 2024 14:30:00 -0400");// "" — 15 March 2024 was a FridayEach has a format* counterpart in the Formatting guide.
Each also has a validator that is true exactly when the parser returns a value:
isValidRfc2822DateTime, isValidHttpDate, isValidSqlDateTime and isValidRfc3339DateTime.
Use it to check a string, not the regex pattern for the format. A pattern proves the shape
alone, so it matches a day that does not exist:
import { isValidHttpDate, isValidRfc2822DateTime, isValidRfc3339DateTime, isValidSqlDateTime, rfc3339DateTime,} from "@northguild/gmt";
rfc3339DateTime.test("2023-02-29T10:00:00Z"); // trueisValidRfc3339DateTime("2023-02-29T10:00:00Z"); // false — 2023 has no 29 FebruaryisValidRfc2822DateTime("Sat, 15 Mar 2024 14:30:00 -0400"); // false — a FridayisValidHttpDate("Sun Nov 6 08:49:37 1994"); // true — asctime-dateisValidHttpDate("Fri, 15 Mar 2024 24:00:00 GMT"); // false — hour 24isValidSqlDateTime("2024-02-30 14:30:00"); // false — February has no 30thisValidSqlDateTime("2024-03-15 14:30:00"); // trueThe rfc2822DateTime and httpDate patterns also do not match the obsolete forms the
parsers read, so a pattern can reject a string its parser accepts.
See also
Section titled “See also”- Formatting — the inverse: producing strings for display and interchange
- Validation — checking a string before parsing
parseYearFromDatereferenceparseDateWithPatternreferenceparseRfc2822referenceisValidRfc3339DateTimereference