Skip to content

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.

HIGH

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
}
HIGH

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
}
MEDIUM

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 === null) {
// handle invalid input
}
MEDIUM

Confusing range validators with interval validators

isValidDateRange checks that a date range string has valid bounds. isValidDateInterval validates an interval object (start + end with optional open-ended flags). They are not interchangeable.

Wrong

isValidDateRange("2024-03-15/2024-03-20"); // valid range string
// using this to validate an interval object — wrong function

Right

import { isValidDateRange, isValidDateInterval } from "@northguild/gmt";

isValidDateRange("2024-03-15/2024-03-20"); // range string — correct
isValidDateInterval({ start: "2024-03-15", end: "2024-03-20" }); // interval object — correct
MEDIUM

Assuming 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({ start: "2024-03-20", end: "2024-03-15" }); // false — start > end

Right

import { isValidDateInterval } from "@northguild/gmt";

isValidDateInterval({ start: "2024-03-15", end: "2024-03-20" }); // true — correct order