如何解决Prisma读取数据库Date类型时日期少一天的问题?
Prisma获取@db.Date字段日期少一天的解决办法
在Svelte应用中使用Prisma查询数据库时,发现@db.Date类型的shift_date字段返回值比数据库存储值少一天。比如数据库存的是2023-03-07,Prisma返回的是Mon Mar 06 2023 19:00:00 GMT-0500,但@db.DateTime类型的字段正常。
模型定义:
model TurnReport { entry_id Int @id(map: "PK_TurnReport") @default(autoincrement()) comment String @db.Text datetime DateTime @db.DateTime author String? @db.VarChar(100) area_id Int shift_date DateTime @db.Date shift_num Int @db.TinyInt ip String? @db.VarChar(32) }
问题原因
核心是时区不匹配:
- 数据库的
DATE类型是无时区的纯日期,存储的是YYYY-MM-DD格式的日期值。 - Prisma将
@db.Date映射到DateTime类型时,会把数据库的纯日期转换为带时区的Date对象。如果你的本地时区是西五区(GMT-0500),数据库的2023-03-07会被解析为GMT时间的2023-03-07T00:00:00Z,转换到西五区就是2023-03-06T19:00:00,看起来日期就少了一天。
解决方案
1. 修正Prisma模型字段类型
把模型中shift_date的类型从DateTime改为Date,和数据库的DATE类型对应:
shift_date Date @db.Date
修改后重新生成Prisma客户端:
npx prisma generate
这样Prisma会直接返回无时区的纯日期对象,避免时区转换导致的偏移。
2. 手动调整时区转换
如果不想修改模型,可以在获取数据后,将返回的Date对象转换为正确的日期格式:
// 方法1:转成UTC日期字符串(YYYY-MM-DD) const correctDate = new Date(turnReport.shift_date).toISOString().split('T')[0]; // 方法2:提取UTC的年、月、日构造日期 const dateObj = new Date(turnReport.shift_date); const correctDate = `${dateObj.getUTCFullYear()}-${String(dateObj.getUTCMonth()+1).padStart(2, '0')}-${String(dateObj.getUTCDate()).padStart(2, '0')}`;
3. 查询时直接格式化日期
使用Prisma的Raw SQL查询,直接从数据库返回格式化后的日期字符串,跳过Prisma的类型转换:
// MySQL示例 const turnReports = await prisma.$queryRaw` SELECT entry_id, comment, datetime, author, area_id, DATE_FORMAT(shift_date, '%Y-%m-%d') as shift_date, shift_num, ip FROM TurnReport `; // PostgreSQL示例 const turnReports = await prisma.$queryRaw` SELECT entry_id, comment, datetime, author, area_id, TO_CHAR(shift_date, 'YYYY-MM-DD') as shift_date, shift_num, ip FROM TurnReport `;
内容的提问来源于stack exchange,提问作者Avi4nFLu
相关产品推荐
相关产品推荐

