Skip to content

Commit db865e9

Browse files
committed
Fix timestamps with years before 100 being parsed as 19xx/20xx
The date and timestamp parser passed PostgreSQL's text output straight to new Date(x). For a year below 100 such as '0050-06-15 12:30:00+00', JavaScript's legacy date parser maps the year into the 1900s (or returns Invalid Date), so the value was silently off by about 1900 years. Normalize the text to ISO 8601 (space to T, two-digit timezone offset to +HH:00) so the ISO parser is used, which handles years below 100 correctly. Years 100 and above are unaffected.
1 parent e7dfa14 commit db865e9

2 files changed

Lines changed: 8 additions & 1 deletion

File tree

src/types.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,10 @@ export const types = {
2929
to: 1184,
3030
from: [1082, 1114, 1184],
3131
serialize: x => (x instanceof Date ? x : new Date(x)).toISOString(),
32-
parse: x => new Date(x)
32+
parse: x => {
33+
const iso = x.replace(' ', 'T')
34+
return new Date(iso === x ? x : iso.replace(/([+-]\d{2})$/, '$1:00'))
35+
}
3336
},
3437
bytea: {
3538
to: 17,

tests/index.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,10 @@ t('Date', async() => {
101101
return [0, now - (await sql`select ${ now } as x`)[0].x]
102102
})
103103

104+
t('Date before year 100', async() =>
105+
['0050-06-15T12:30:00.000Z', (await sql`select '0050-06-15 12:30:00+00'::timestamptz as x`)[0].x.toISOString()]
106+
)
107+
104108
t('Json', async() => {
105109
const x = (await sql`select ${ sql.json({ a: 'hello', b: 42 }) } as x`)[0].x
106110
return ['hello,42', [x.a, x.b].join()]

0 commit comments

Comments
 (0)