Skip to content

fix: parse infinite dates - #1202

Merged
tdrz merged 2 commits into
electric-sql:mainfrom
efeesrefinal:fix/parse-infinite-and-bc-dates
Nov 9, 2026
Merged

tdrz merged 2 commits into
electric-sql:mainfrom
efeesrefinal:fix/parse-infinite-and-bc-dates

Conversation

@efeesrefinal

@efeesrefinal efeesrefinal commented Nov 8, 2026 •

Copy link
Copy Markdown
Contributor

The date, timestamp and timestamptz parser is new Date(x), which returns Invalid Date for infinity and -infinity:

const db = new PGlite()
;(await db.query(`select 'infinity'::timestamptz as a, '-infinity'::date as b`)).rows[0]
// { a: Invalid Date, b: Invalid Date }

Now they become Infinity and -Infinity, as in postgres.js, and the date serializer turns them back into infinity and -infinity. All other values still go through new Date.

Tested in Node 22:

  • The two new tests in tests/types.test.ts fail on main and pass with the change, together with the existing ones (39 in total).
  • ESLint and Prettier are clean on the changed files. I did not build the WASM, so the full test suite was not run.

@tdrz tdrz left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for this!

Unsure about the 'BC' part right now, see comment. I'd take the changes for the 'infinity' for now.

Comment thread packages/pglite/src/types.ts Outdated
Comment on lines +195 to +222
const dateParts =
/^(\d{4,})-(\d\d)-(\d\d)(?: (\d\d):(\d\d):(\d\d)(?:\.(\d+))?)?(?:([+-])(\d\d)(?::(\d\d))?(?::(\d\d))?)?( BC)?$/

function parseDateParts(x: string): Date | null {
const m = dateParts.exec(x)
if (!m) return null
const year = m[12] ? 1 - +m[1] : +m[1]
const month = +m[2] - 1
const day = +m[3]
const [hour, minute, second] = [+(m[4] ?? 0), +(m[5] ?? 0), +(m[6] ?? 0)]
const ms = m[7] ? +(m[7] + '00').slice(0, 3) : 0

// A timestamp without time zone is local time, like `new Date` reads it.
if (m[4] !== undefined && m[8] === undefined) {
const date = new Date(2000, 0, 1)
date.setFullYear(year, month, day)
date.setHours(hour, minute, second, ms)
return date
}

const date = new Date(Date.UTC(2000, month, day, hour, minute, second, ms))
date.setUTCFullYear(year)
if (m[8]) {
const offset = (+m[9] * 60 + +(m[10] ?? 0)) * 60 + +(m[11] ?? 0)
date.setTime(date.getTime() - (m[8] === '-' ? -offset : offset) * 1000)
}
return date
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is ... quite something! Isn't there a more humane way to do this?

@efeesrefinal efeesrefinal changed the title fix: parse infinity, BC dates and offsets with seconds fix: parse infinite dates Nov 9, 2026
@efeesrefinal

Copy link
Copy Markdown
Contributor Author

Thanks, that's fair. I removed the BC and offset parsing, so this now only handles infinity and -infinity.

@tdrz tdrz left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

@tdrz
tdrz merged commit 26a6e21 into electric-sql:main Nov 9, 2026
14 of 17 checks passed
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.

2 participants