You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用ExpressJS向MongoDB存储数据时日期自动减1问题

ExpressJS存入MongoDB日期自动减1的解决办法

问题现象

提交的请求体中日期为06/27/2023,但存入MongoDB后变为2023-06-26T18:30:00.000Z,日期自动减1。

请求体示例

{
    "name":"Articulation Exam",
    "location":"IoN Center",
    "timing":"11:00am",
    "date":"06/27/2023",
    "maximum_allowed_participants":100,
    "active_participants":1
}

数据库存储结果

{
        "_id": "6485a0737cd0de176a0c87c0",
        "name": "Articulation Exam",
        "location": "IoN Center",
        "timing": "11:00am",
        "date": "2023-06-26T18:30:00.000Z",
        "maximum_allowed_participants": 100,
        "active_participants": 1,
        "createdAt": "2023-06-11T10:22:43.046Z",
        "updatedAt": "2023-06-11T10:22:43.046Z",
        "__v": 0
    }

路由代码

router.route('/post').post((req,res)=>{
    const data = {
        name:req.body.name,
        location:req.body.location,
        timing:req.body.timing,
        date:new Date(req.body.date),
        maximum_allowed_participants:req.body.maximum_allowed_participants,
        active_participants:req.body.active_participants
    }

    const newRecord = new Events(data);

    newRecord.save()
    .then(response=>res.send('A new event "'+response.name+'" has been added Succssfully!'))
    .catch(err=>res.send(err));
})

Schema定义

const eventSchema = new Schema({
    name:{
        type:String,
        required:true,
        trim:true,
        minlength:3
    },
    location:{
        type:String,
        required:true,
        trim:true,
        minlength:2
    },
    timing:{
        type:String,
        required:true,
        trim:true,
    },
    date:{
        type:Date,
        required:true
    },
    maximum_allowed_participants:{
        type:Number,
        required:true
    },
    active_participants:{
        type:Number,
        required:true
    }
},
{
    timestamps:true
});

原因分析

这是时区差异导致的:

  • MongoDB默认以UTC时间存储日期数据。
  • 使用new Date(req.body.date)时,JS会基于服务器本地时区解析06/27/2023(默认视为当天0点),随后自动转换为UTC时间存储。
  • 从存储结果2023-06-26T18:30:00.000Z来看,服务器所在时区为UTC+5:30(印度标准时间),本地时间06/27 00:00转换为UTC就是06/26 18:30,因此数据库中显示转换后的UTC日期。

解决办法

方法1:手动构造UTC日期

拆分输入的日期字符串,用Date.UTC构造UTC时区的当天0点:

router.route('/post').post((req,res)=>{
    // 拆分MM/DD/YYYY格式的日期
    const [month, day, year] = req.body.date.split('/');
    // 构造UTC日期(JS中月份从0开始,需减1)
    const utcDate = new Date(Date.UTC(year, month - 1, day));

    const data = {
        name:req.body.name,
        location:req.body.location,
        timing:req.body.timing,
        date: utcDate,
        maximum_allowed_participants:req.body.maximum_allowed_participants,
        active_participants:req.body.active_participants
    }

    const newRecord = new Events(data);

    newRecord.save()
    .then(response=>res.send('A new event "'+response.name+'" has been added Succssfully!'))
    .catch(err=>res.send(err));
})

这样存储的日期会是2023-06-27T00:00:00.000Z,对应本地时区的06/27。

方法2:用日期处理库(如moment.js)

使用moment.js便捷处理时区,确保解析为UTC日期:

  1. 安装moment:npm install moment
  2. 修改路由代码:
const moment = require('moment');

router.route('/post').post((req,res)=>{
    const data = {
        name:req.body.name,
        location:req.body.location,
        timing:req.body.timing,
        // 按MM/DD/YYYY解析并转为UTC日期
        date: moment(req.body.date, 'MM/DD/YYYY').utc().toDate(),
        maximum_allowed_participants:req.body.maximum_allowed_participants,
        active_participants:req.body.active_participants
    }

    const newRecord = new Events(data);

    newRecord.save()
    .then(response=>res.send('A new event "'+response.name+'" has been added Succssfully!'))
    .catch(err=>res.send(err));
})

方法3:读取时转换为本地时区

如果不需要修改存储逻辑,可在读取数据时将UTC时间转换为本地时区显示:

// 示例:读取记录后转换日期
Events.findById('6485a0737cd0de176a0c87c0')
.then(event => {
    // 将UTC日期转为本地时区的MM/DD/YYYY格式字符串
    const localDate = event.date.toLocaleDateString('en-US', {
        year: 'numeric',
        month: '2-digit',
        day: '2-digit'
    });
    event.localDate = localDate;
    res.send(event);
})

内容的提问来源于stack exchange,提问作者Gokul

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 10:23:13