NestJS与TypeORM中MySQL日期过滤时区问题求助
解决NestJS查询MySQL datetime字段的时区匹配问题
问题出在哪
MySQL的datetime类型不存储时区信息,仅保存本地时间字符串;而JavaScript的Date对象会自动将传入的时间转换为UTC时区(比如你传入的2024-06-19 20:17:44会被转为2024-06-20T01:17:44.000Z),最终生成的SQL查询用UTC时间去匹配数据库里的本地时间,自然查不到数据。
解决办法
办法1:将传入时间转成数据库时区的字符串
直接构造对应时区的时间字符串,避免Date对象的自动时区转换。假设你的数据库使用东八区(UTC+8):
// 辅助函数:把传入时间转成东八区的YYYY-MM-DD HH:mm:ss格式 const convertToLocalTimeStr = (dateStr: string) => { const date = new Date(dateStr); // 手动添加时区偏移(东八区+8小时) date.setHours(date.getHours() + 8); // 转换为数据库兼容的时间字符串 return date.toISOString().slice(0, 19).replace('T', ' '); }; // 替换原findAll方法中的日期处理逻辑 if (startDate && endDate) { whereConditions.date_time_capture = Between( convertToLocalTimeStr(startDate), convertToLocalTimeStr(endDate) ); } else if (startDate) { whereConditions.date_time_capture = MoreThanOrEqual(convertToLocalTimeStr(startDate)); } else if (endDate) { whereConditions.date_time_capture = LessThanOrEqual(convertToLocalTimeStr(endDate)); }
办法2:给TypeORM配置数据库时区
在TypeORM的配置文件中,指定数据库所在时区,让框架自动处理时区转换:
// ormconfig.ts 或 app.module.ts中的TypeORM配置项 { type: 'mysql', host: '你的数据库地址', port: 3306, username: '数据库用户名', password: '数据库密码', database: '数据库名', entities: [__dirname + '/**/*.entity{.ts,.js}'], synchronize: false, // 添加时区配置,根据你的数据库实际时区调整(例如东八区为+08:00) timezone: '+08:00', }
配置后,TypeORM会自动将JavaScript的UTC时间转换为指定时区的时间,与数据库的datetime字段匹配。
办法3:换用MySQL的timestamp类型(可选)
如果业务允许,将date_time_capture字段类型改为timestamp,它会存储UTC时间,查询时MySQL会自动根据会话时区转换为本地时间。注意:timestamp有时间范围限制(1970-01-01 00:00:01 UTC 到 2038-01-19 03:14:07 UTC),超出范围无法使用。
验证方式
修改完成后,查看控制台输出的whereConditions,确认日期格式为YYYY-MM-DD HH:mm:ss且与数据库存储的时间一致,再执行查询即可返回正确结果。
内容的提问来源于stack exchange,提问作者Andres Lopez
相关产品推荐
相关产品推荐

