Skip to content

Fix DateTime fields returning Invalid Date with unixepoch-ms#29274

Merged
jacek-prisma merged 4 commits intoprisma:mainfrom
connortessaro:fix/28890-unixepoch-ms-invalid-date
Mar 9, 2026
Merged

Fix DateTime fields returning Invalid Date with unixepoch-ms#29274
jacek-prisma merged 4 commits intoprisma:mainfrom
connortessaro:fix/28890-unixepoch-ms-invalid-date

Conversation

@connortessaro
Copy link
Copy Markdown
Contributor

@connortessaro connortessaro commented Feb 27, 2026

Summary

Fix DateTime fields returning Invalid Date when using unixepoch-ms.

Changes

  • Correct DateTime handling for unixepoch-ms (millisecond timestamps).
  • Add regression test covering DateTime read/write with unixepoch-ms.

Tests

  • Added/updated tests for this regression and verified they pass.

Fixes #28890

Summary by CodeRabbit

  • Bug Fixes

    • Safer handling of very large integers from the database: values that fit safely are returned as numbers, while out-of-range integers fall back to strings to prevent precision loss.
  • Tests

    • Added functional tests for millisecond-precision timestamps to verify created and aggregated datetime values are returned as valid Date instances across create, find, and aggregate scenarios.

Copilot AI review requested due to automatic review settings February 27, 2026 23:37
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Feb 27, 2026

Walkthrough

Bigint handling in the better-sqlite3 adapter was changed to convert safe bigints to numbers and keep unsafe bigints as strings. Added functional tests validating DateTime fields stored as unix-epoch milliseconds are returned as valid Date objects across create/retrieve, aggregate, and INTEGER-column scenarios.

Changes

Cohort / File(s) Summary
Adapter Bigint Conversion
packages/adapter-better-sqlite3/src/conversion.ts
Modified mapRow bigint handling to conditionally convert bigint values to numbers when Number.isSafeInteger(...) is true; otherwise retain string fallback.
Datetime Unixepoch Tests
packages/client/tests/functional/unixepoch-ms-datetime/tests.ts
Added three functional tests: create + retrieve (findFirst/findUnique-style), aggregate (_min/_max), and a manual INTEGER DateTime column scenario to ensure unixepoch-ms stored timestamps are returned as Date instances.

Suggested labels

lgtm, backport-6.x-candidate

Suggested reviewers

  • jacek-prisma
  • aqrln
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Fix DateTime fields returning Invalid Date with unixepoch-ms' directly summarizes the main change: fixing an issue where DateTime fields return Invalid Date when using unixepoch-ms format.
Linked Issues check ✅ Passed The PR addresses the core issue #28890: the adapter was not correctly converting numeric millisecond timestamps to Dates when using unixepoch-ms. The fix modifies mapRow to conditionally convert bigint to number when safe, enabling proper DateTime handling. Comprehensive tests are added covering manual INTEGER DateTime columns, CRUD operations, and aggregates.
Out of Scope Changes check ✅ Passed All changes are directly scoped to fixing the unixepoch-ms DateTime issue: the adapter conversion logic for bigint/number handling, and regression tests covering DateTime read/write scenarios with manual INTEGER columns.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1


ℹ️ Review info

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 455853d and f70bac7.

📒 Files selected for processing (2)
  • packages/adapter-better-sqlite3/src/conversion.ts
  • packages/client/tests/functional/unixepoch-ms-datetime/tests.ts

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes DateTime fields becoming Invalid Date when using the BetterSQLite3 driver adapter with timestampFormat: "unixepoch-ms" by adjusting how BigInt query results are mapped back into JSON-compatible values, and adds regression coverage for unix-millis stored directly in SQLite.

Changes:

  • Update BetterSQLite3 result mapping to convert bigint values to number when they fit safely, falling back to string otherwise.
  • Add functional tests to assert valid Date objects are returned when unix-millis timestamps are stored directly (including aggregates).

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
packages/client/tests/functional/unixepoch-ms-datetime/tests.ts Adds regression tests for reading DateTime values when unix-millis are stored directly and when aggregating.
packages/adapter-better-sqlite3/src/conversion.ts Adjusts row value conversion so safe bigint values are returned as number (helps unixepoch-ms DateTime parsing).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2


ℹ️ Review info

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f70bac7 and 8dbff88.

📒 Files selected for processing (1)
  • packages/client/tests/functional/unixepoch-ms-datetime/tests.ts

@jacek-prisma
Copy link
Copy Markdown
Contributor

jacek-prisma commented Mar 3, 2026

This doesn't actually address #28890, because that issue is only reproducible by creating the date column manually with type set to INTEGER. In order to verify that the fix actually works you should write a test that manually creates a column with type INTEGER.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
packages/client/tests/functional/unixepoch-ms-datetime/tests.ts (1)

111-130: ⚠️ Potential issue | 🟡 Minor

Test intent mismatch: findUnique() in name but findFirst() in code

Line 111 says findUnique(), but Line 122 executes findFirst(). Also, found?.createdAt + found! mixes null-safe and non-null assertions in the same test. Please align the name/query and assert non-null once before dereference.

Suggested fix
-    test('findUnique() returns valid Date when createdAt is stored as unix millis directly', async () => {
+    test('findFirst() returns valid Date when createdAt is stored as unix millis directly', async () => {
       const prisma = createClient(info, driverAdapter)

       const uuid = randomUUID()
       const nowMillis = Date.now()

       await prisma.$executeRaw`
         INSERT INTO Event (name, uuid, createdAt)
         VALUES ('event', ${uuid}, ${nowMillis})
       `

       const found = await prisma.event.findFirst({
         where: {
           uuid,
         },
       })

-      expect(found?.createdAt).toBeInstanceOf(Date)
+      expect(found).not.toBeNull()
+      expect(found!.createdAt).toBeInstanceOf(Date)
       expect(isNaN(found!.createdAt.getTime())).toBe(false)
     })

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 555faf9f-b116-4801-8ff3-cdf5818f8b96

📥 Commits

Reviewing files that changed from the base of the PR and between 8dbff88 and 77f2663.

📒 Files selected for processing (1)
  • packages/client/tests/functional/unixepoch-ms-datetime/tests.ts

@connortessaro
Copy link
Copy Markdown
Contributor Author

Thanks for flagging this. I added a test that creates a DateTime column backed by INTEGER and stores unixepoch-ms values to reproduce the issue discussed in #28890. The test now verifies that Prisma Client returns a valid Date (not Invalid Date) for that DateTime column.

@jacek-prisma jacek-prisma merged commit 7a1f497 into prisma:main Mar 9, 2026
249 of 253 checks passed
@connortessaro connortessaro deleted the fix/28890-unixepoch-ms-invalid-date branch March 10, 2026 18:03
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.

@prisma/adapter-better-sqlite3 DateTime fields return Invalid Date with timestampFormat: "unixepoch-ms"

3 participants