Skip to content

fix: parse dates with years before 100 correctly - #1074

Open
spokodev wants to merge 1 commit into
electric-sql:mainfrom
spokodev:fix/date-year-before-100
Open

fix: parse dates with years before 100 correctly#1074
spokodev wants to merge 1 commit into
electric-sql:mainfrom
spokodev:fix/date-year-before-100

Conversation

@spokodev

@spokodev spokodev commented Aug 5, 2026

Copy link
Copy Markdown

Problem

The date / timestamp / timestamptz parser in packages/pglite/src/types.ts is parse: (x) => new Date(x). PostgreSQL emits a year below 100 as e.g. 0050-06-15 12:30:00+00, which is not strict ISO 8601 (space separator, two-digit offset), so new Date falls back to its legacy parser, which maps the year into the 1900s or returns garbage:

const db = new PGlite()
;(await db.query(`select '0050-06-15 12:30:00+00'::timestamptz as v`)).rows[0].v  // 1950-06-15  (should be 0050)
;(await db.query(`select '0099-06-15 12:30:00+00'::timestamptz as v`)).rows[0].v  // 1999-06-15  (should be 0099)
;(await db.query(`select '0001-06-15 12:30:00+00'::timestamptz as v`)).rows[0].v  // 2015-01-06  (garbage)

Any date / timestamp / timestamptz with a year of 1 to 99 is silently corrupted (off by ~1900 years, or Invalid Date).

Fix

Normalize the text to ISO 8601 before new Date: replace the date/time space with T, and expand a two-digit timezone offset +HH to +HH:00. The ISO parser then handles years below 100 correctly. Years 100 and above produce identical output to before.

Test

Added timestamptz 1184 before year 100 to packages/pglite/tests/types.test.ts. Verified via parseType that years 1–99 now parse to the correct year, and that years ≥ 100 and the date (1082) / timestamp (1114) cases are unchanged.


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

PostgreSQL emits years below 100 as e.g. '0050-06-15 12:30:00+00', which
is not strict ISO 8601, so new Date() fell back to its legacy parser and
mapped the year into the 1900s (0050 became 1950, 0099 became 1999) or
returned Invalid Date. Normalize the text to ISO 8601 (space to T,
two-digit timezone offset to +HH:00) before parsing. Years 100 and above
are unaffected.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant