Date Validation
GMT’s validation functions return booleans. They never throw — invalid input yields
false. The ambiguity of false (invalid vs. genuinely not-the-case) is the core
mistake.
Mistakes
Section titled “Mistakes”Not validating before parsing
Feeding an unvalidated user input string into parseYearFromDate or any other parser produces an empty string or null silently. Validate first, then parse.
Wrong
const year = parseYearFromDate(userInput); // "not-a-date" → ""Right
import { isValidDate, parseYearFromDate } from "@northguild/gmt";
if (isValidDate(userInput)) {const year = parseYearFromDate(userInput); // safe — input is known-valid}Not validating timezone before use
Passing an invalid IANA timezone to getZonedNow or any zoned function returns an empty string. Always validate the timezone with isValidTimeZone first.
Wrong
getZonedNow("not-a-zone"); // ""Right
import { isValidTimeZone, getZonedNow } from "@northguild/gmt/zoned";
if (isValidTimeZone(tz)) {getZonedNow(tz); // safe}Using try-catch for validation
GMT functions never throw — they return sentinel values. A try-catch block around a GMT call will never fire, giving a false sense of safety.
Wrong
try {const r = parseRfc3339(input); // never throws} catch (e) {// never reached}Right
import { parseRfc3339 } from "@northguild/gmt/zoned";
const r = parseRfc3339(input);if (r === "") {// handle invalid input}Confusing range validators with interval validators
isValidDateRange takes one object, { value1, value2 }, and by default requires value1 strictly before value2 (pass options: { allowEqual: true } to accept equal dates). isValidDateInterval takes two positional dates and accepts start === end, an empty interval. Neither takes a range string. They are not interchangeable.
Wrong
isValidDateRange("2024-03-15/2024-03-20"); // false — not a range stringisValidDateInterval({ start: "2024-03-15", end: "2024-03-20" }); // false — not an objectRight
import { isValidDateRange, isValidDateInterval } from "@northguild/gmt";
isValidDateRange({ value1: "2024-03-15", value2: "2024-03-20" }); // trueisValidDateInterval("2024-03-15", "2024-03-20"); // trueisValidDateRange({ value1: "2024-03-15", value2: "2024-03-15" }); // false — equal dates need allowEqualisValidDateInterval("2024-03-15", "2024-03-15"); // true — an interval may be emptyAssuming intervals accept reversed bounds
isValidDateInterval returns false when start > end. GMT intervals do not auto-normalize reversed bounds — fix the order before validation.
Wrong
isValidDateInterval("2024-03-20", "2024-03-15"); // false — start > endRight
import { isValidDateInterval } from "@northguild/gmt";
isValidDateInterval("2024-03-15", "2024-03-20"); // true — correct order