如何避免MongoDB存储服务器生成的当前日期时自动减1小时?
解决MongoDB存储$currentDate时区偏移及代码逻辑问题
问题核心
你遇到的时间差问题主要来自两个点:
- MongoDB的
$currentDate默认存储UTC时间,如果客户端设置到期时间时用的是本地时区而非UTC,就会出现时间差; - 现有代码存在逻辑错误:更新
currentDate后,你用的还是查询时的旧single.currentDate值做判断,根本没用到刚更新的数据库值。
解决方案
1. 彻底重构定时任务逻辑(最推荐)
不需要额外存储currentDate字段,直接在查询时用当前UTC时间对比到期时间,批量更新状态,既高效又避免时区混乱:
const autoUpdateDatabase = async () => { cron.schedule('* * * * *', async () => { try { // 筛选:未关闭 + 到期时间 ≤ 当前UTC时间 const updateResult = await Auction.updateMany( { isClose: false, expiryDate: { $lte: new Date() } // new Date()默认生成UTC时间 }, { $set: { isClose: true }, $unset: { expiryDate: "" } // 清空到期时间 } ); if (updateResult.modifiedCount > 0) { console.log(`已自动结束 ${updateResult.modifiedCount} 个到期拍卖`); } else { console.log("无到期拍卖需要处理"); } } catch (err) { console.error("更新拍卖状态失败:", err); } }); };
2. 统一客户端与服务器的时区处理
确保客户端提交到期时间时,转换为UTC格式再传给API:
// 客户端示例:将用户输入的时间转为UTC字符串 const userInputExpiry = "2022-09-12T13:00"; // 假设是用户本地时间 const utcExpiry = new Date(userInputExpiry).toISOString(); // 然后将utcExpiry传给API存储到MongoDB
3. 验证Heroku服务器时区(可选)
虽然MongoDB用UTC存储,但如果服务器时区配置异常,可能影响代码中new Date()的生成。可以在Heroku控制台执行以下命令查看时区:
heroku run date
如果显示非UTC,可以通过设置环境变量强制使用UTC:
heroku config:add TZ=UTC
原代码的关键错误说明
- 用
map(async () => {})时,map不会等待异步函数执行完成,会导致批量更新逻辑混乱; - 更新
currentDate后,single.currentDate还是查询时的旧值,你的判断逻辑根本没用到刚更新的数据库值,等于白做了$currentDate更新。
内容的提问来源于stack exchange,提问作者Eunice
相关产品推荐
相关产品推荐

