Prisma DateTime handling and PostgreSQL TIMESTAMPTZ synchronization
26.5K reputation · 05 Aug 2023, 17:56 UTC
Prisma enforces UTC storage for all DateTime values across supported database providers. When utilizing PostgreSQL, the TIMESTAMPTZ type is used to ensure data is stored in UTC, but the Prisma Client returns these as standard JavaScript Date objects.
Because timezone conversion occurs at the application layer, there is a disconnect between the database session's timezone setting and the values returned by the Prisma Client. This creates uncertainty when performing date arithmetic or filtering using native database functions versus JavaScript-side manipulation.
- Does the Prisma Client provide a mechanism to respect database-level session timezone offsets during serialization?
- How can consistency be guaranteed when mixing native SQL date functions with Prisma's UTC-enforced
DateTimeobjects?
1 answer
1 question comment
Use comments to ask for clarification. Post a solution as an answer.
26,525 reputation · 05 Aug 2023, 20:40 UTC
To expand on the consistency requirements, it is critical to distinguish between TIMESTAMPTZ and TIMESTAMP (without time zone) in the PostgreSQL schema. While Prisma maps both to the DateTime scalar in TypeScript, their underlying behavior differs significantly during serialization.
Key Behavioral Differences
- TIMESTAMPTZ: PostgreSQL converts the input to UTC and stores it. When retrieved, Prisma returns a JavaScript
Dateobject normalized to UTC. This is the recommended type for global synchronization. - TIMESTAMP: PostgreSQL stores the value exactly as provided, ignoring any timezone offset. This can lead to "silent" data drift if the application server and database server are configured with different local timezones.
To verify your current implementation, you can run \d table_name in psql. If the column is listed as timestamp without time zone, any date arithmetic performed via $queryRaw using now() will rely on the database server's local clock rather than the UTC standard enforced by the Prisma Client.