Skip to content

Commit 375dbb8

Browse files
fix(utils): return original input from date formatters on invalid dates
formatCompactTimestamp and formatAbsoluteDate both build their output from Date getters. An unparseable string produces an Invalid Date whose getters return NaN rather than throwing, so formatCompactTimestamp's try/catch fallback never ran and it returned "NaN-NaN NaN:NaN", while formatAbsoluteDate returned the literal "Invalid Date". Both now check Number.isNaN(date.getTime()) up front and fall back to the original input string, which is what the existing catch was meant to do. Valid dates are unaffected. Updates the formatCompactTimestamp invalid-date test to assert the returned value instead of only its type, and adds a matching test for formatAbsoluteDate. Co-authored-by: eeshsaxena <eeshsaxena@gmail.com>
1 parent 2977db5 commit 375dbb8

2 files changed

Lines changed: 17 additions & 2 deletions

File tree

packages/utils/src/formatting.test.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,10 @@ describe('formatAbsoluteDate', () => {
6868
expect(result).toMatch(/May/)
6969
expect(result).toMatch(/2023/)
7070
})
71+
72+
it('returns the original input for an unparseable date', () => {
73+
expect(formatAbsoluteDate('not-a-date')).toBe('not-a-date')
74+
})
7175
})
7276

7377
describe('formatTime', () => {
@@ -99,9 +103,10 @@ describe('formatCompactTimestamp', () => {
99103
expect(result).toMatch(/^\d{2}-\d{2} \d{2}:\d{2}$/)
100104
})
101105

102-
it('returns a formatted string even for invalid dates (no throw)', () => {
106+
it('returns the original input for invalid dates instead of a NaN string', () => {
103107
const result = formatCompactTimestamp('not-a-date')
104-
expect(typeof result).toBe('string')
108+
expect(result).toBe('not-a-date')
109+
expect(result).not.toContain('NaN')
105110
})
106111
})
107112

packages/utils/src/formatting.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,11 @@ export function formatDate(date: Date): string {
104104
*/
105105
export function formatAbsoluteDate(dateString: string): string {
106106
const date = new Date(dateString)
107+
// An unparseable string yields an Invalid Date whose formatters return
108+
// "Invalid Date"; fall back to the original input instead.
109+
if (Number.isNaN(date.getTime())) {
110+
return dateString
111+
}
107112
return date.toLocaleDateString('en-US', {
108113
year: 'numeric',
109114
month: 'short',
@@ -150,6 +155,11 @@ export function formatTimeWithSeconds(date: Date, includeTimezone = true): strin
150155
export function formatCompactTimestamp(iso: string): string {
151156
try {
152157
const d = new Date(iso)
158+
// Invalid dates do not throw; their getters return NaN, so the catch
159+
// below never fires. Guard explicitly and fall back to the input string.
160+
if (Number.isNaN(d.getTime())) {
161+
return iso
162+
}
153163
const mm = String(d.getMonth() + 1).padStart(2, '0')
154164
const dd = String(d.getDate()).padStart(2, '0')
155165
const hh = String(d.getHours()).padStart(2, '0')

0 commit comments

Comments
 (0)