diff --git a/packages/utils/src/formatting.test.ts b/packages/utils/src/formatting.test.ts index 6e8d43ce8fc..eb1a4108919 100644 --- a/packages/utils/src/formatting.test.ts +++ b/packages/utils/src/formatting.test.ts @@ -68,6 +68,10 @@ describe('formatAbsoluteDate', () => { expect(result).toMatch(/May/) expect(result).toMatch(/2023/) }) + + it('returns the original input for an unparseable date', () => { + expect(formatAbsoluteDate('not-a-date')).toBe('not-a-date') + }) }) describe('formatTime', () => { @@ -99,9 +103,10 @@ describe('formatCompactTimestamp', () => { expect(result).toMatch(/^\d{2}-\d{2} \d{2}:\d{2}$/) }) - it('returns a formatted string even for invalid dates (no throw)', () => { + it('returns the original input for invalid dates instead of a NaN string', () => { const result = formatCompactTimestamp('not-a-date') - expect(typeof result).toBe('string') + expect(result).toBe('not-a-date') + expect(result).not.toContain('NaN') }) }) diff --git a/packages/utils/src/formatting.ts b/packages/utils/src/formatting.ts index 3c26b464f2a..4b65f70ce3d 100644 --- a/packages/utils/src/formatting.ts +++ b/packages/utils/src/formatting.ts @@ -100,10 +100,16 @@ export function formatDate(date: Date): string { /** * Formats a date string to absolute format for tooltip display * @param dateString - ISO date string to format - * @returns A formatted date string (e.g., "Jan 22, 2026, 01:30 PM") + * @returns A formatted date string (e.g., "Jan 22, 2026, 01:30 PM"), or the + * original `dateString` unchanged when it cannot be parsed into a valid date */ export function formatAbsoluteDate(dateString: string): string { const date = new Date(dateString) + // An unparseable string yields an Invalid Date whose formatters return + // "Invalid Date"; fall back to the original input instead. + if (Number.isNaN(date.getTime())) { + return dateString + } return date.toLocaleDateString('en-US', { year: 'numeric', month: 'short', @@ -145,11 +151,17 @@ export function formatTimeWithSeconds(date: Date, includeTimezone = true): strin /** * Format an ISO timestamp into a compact format for UI display * @param iso - ISO timestamp string - * @returns A formatted string in "MM-DD HH:mm" format + * @returns A formatted string in "MM-DD HH:mm" format, or the original `iso` + * string unchanged when it cannot be parsed into a valid date */ export function formatCompactTimestamp(iso: string): string { try { const d = new Date(iso) + // Invalid dates do not throw; their getters return NaN, so the catch + // below never fires. Guard explicitly and fall back to the input string. + if (Number.isNaN(d.getTime())) { + return iso + } const mm = String(d.getMonth() + 1).padStart(2, '0') const dd = String(d.getDate()).padStart(2, '0') const hh = String(d.getHours()).padStart(2, '0')