Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 14 additions & 5 deletions src/date_utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -306,11 +306,20 @@ export function parseDate(
const formats = Array.isArray(dateFormat) ? dateFormat : [dateFormat];

for (const format of formats) {
const parsedDate = parse(value, format, refDate, {
locale: localeObject,
useAdditionalWeekYearTokens: true,
useAdditionalDayOfYearTokens: true,
});
// date-fns `parse` throws a RangeError for format tokens it cannot
// consume (e.g. the `z`/`zzz` timezone tokens, which are format-only).
// Guard against that so an unparseable token in `dateFormat` does not
// crash callers such as handleChange and discard the user's input.
let parsedDate: Date;
try {
parsedDate = parse(value, format, refDate, {
locale: localeObject,
useAdditionalWeekYearTokens: true,
useAdditionalDayOfYearTokens: true,
});
} catch {
continue;
}
if (
isValid(parsedDate) &&
(!strictParsing || value === formatDate(parsedDate, format, locale))
Expand Down
18 changes: 18 additions & 0 deletions src/test/date_utils_test.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1121,6 +1121,24 @@ describe("date_utils", () => {
expect(actual).toEqual(expected);
});

it("should not throw when dateFormat contains an unparseable timezone token (#6303)", () => {
// date-fns `parse` cannot consume the `z`/`zzz` timezone tokens and
// throws a RangeError ("Format string contains an unescaped latin
// alphabet character `z`"). parseDate must swallow that so typing an
// input does not crash handleChange and the user's value is not lost.
const value = "July 6, 2026 3:30 PM (GMT+0)";
const dateFormat = "MMMM d, yyyy h:mm aa (zzz)";

let actual: Date | null = null;
expect(() => {
actual = parseDate(value, dateFormat, undefined, false);
}).not.toThrow();

// The date/time portion still resolves via the native Date fallback.
expect(actual).not.toBeNull();
expect(actual).toEqual(new Date(2026, 6, 6, 15, 30, 0, 0));
});

describe("native Date fallback when strictParsing is false (#6164)", () => {
it("should parse date in different format using native Date fallback", () => {
// User types MM/dd/yyyy but dateFormat is yyyy-MM-dd
Expand Down