后端返回日期传递至前端时自动减1天异常排查
前端接收后端日期统一少1天问题排查
问题背景
- 开发度假村客房可订状态日期选择器,功能由前后端两个函数协同实现:
- 后端函数请求外部API,将响应格式化为日期对象数组返回
- 前端函数调用后端接口,将返回结果传入渲染模块展示可订状态
- 异常表现:后端格式化完成的日期数组未做任何修改,但前端渲染日期始终比后端返回日期早1天,排查确认偏差发生在数据从后端传输到前端的过程中,与日期选择器本身解析逻辑无关
- 参考截图:
相关代码与日志
前端调用逻辑
getAvailAsync(startDate, endDate, attributeId, resortId, room, resort, duration).then(response => { console.log("returned to front end", response.res.availability) response.res.error ? "" : repeaterData.push(response.res) $w("#resortsRepeater").data = repeaterData if(repeaterData.length > 12) { $w("#loadMore").show() } if(repeaterData.length > 0) { $w("#loadingStrip").collapse() } })
前端控制台日志
前端接收的日期首个为7月15日,最后一个为7月26日,时区为GMT-0700(太平洋夏令时):
[ { "startDate": "Fri Jul 15 2022 17:00:00 GMT-0700 (Pacific Daylight Time)", "endDate": "Fri Jul 15 2022 17:00:00 GMT-0700 (Pacific Daylight Time)" }, { "startDate": "Sat Jul 16 2022 17:00:00 GMT-0700 (Pacific Daylight Time)", "endDate": "Sat Jul 16 2022 17:00:00 GMT-0700 (Pacific Daylight Time)" }, { "startDate": "Sun Jul 17 2022 17:00:00 GMT-0700 (Pacific Daylight Time)", "endDate": "Sun Jul 17 2022 17:00:00 GMT-0700 (Pacific Daylight Time)" }, { "startDate": "Mon Jul 18 2022 17:00:00 GMT-0700 (Pacific Daylight Time)", "endDate": "Mon Jul 18 2022 17:00:00 GMT-0700 (Pacific Daylight Time)" }, { "startDate": "Tue Jul 19 2022 17:00:00 GMT-0700 (Pacific Daylight Time)", "endDate": "Tue Jul 19 2022 17:00:00 GMT-0700 (Pacific Daylight Time)" }, { "startDate": "Tue Jul 26 2022 17:00:00 GMT-0700 (Pacific Daylight Time)", "endDate": "Tue Jul 26 2022 17:00:00 GMT-0700 (Pacific Daylight Time)" } ]
后端返回逻辑
if(validAvail == undefined) { resolve({ res: {error: "No availability found"}}) } else { console.log("Valid avail before passing to the front end", validAvail) validAvail.length > 0 ? resolve({ res: { ...resortInfo, ...roomInfo, availability: validAvail } }) : resolve({ res: {error: "No availability found"} }) }
后端控制台日志
后端返回的日期首个为7月16日,最后一个为7月27日,为UTC标准时间:
[ { "startDate": "2022-07-16T00:00:00.000Z", "endDate": "2022-07-16T00:00:00.000Z" }, { "startDate": "2022-07-17T00:00:00.000Z", "endDate": "2022-07-17T00:00:00.000Z" }, { "startDate": "2022-07-18T00:00:00.000Z", "endDate": "2022-07-18T00:00:00.000Z" }, { "startDate": "2022-07-19T00:00:00.000Z", "endDate": "2022-07-19T00:00:00.000Z" }, { "startDate": "2022-07-20T00:00:00.000Z", "endDate": "2022-07-20T00:00:00.000Z" }, { "startDate": "2022-07-27T00:00:00.000Z", "endDate": "2022-07-27T00:00:00.000Z" } ]
问题原因
该偏差不是传值异常,是时区转换的标准行为:
- 后端返回的是UTC零时区0点的时间,例
2022-07-16T00:00:00.000Z对应UTC时间7月16日0点 - 前端运行环境为GMT-0700(太平洋夏令时),比UTC时间晚7小时,UTC时间7月16日0点换算为当地时间就是7月15日17点,日期自然减1天
- 日志里的
{$date: "xxx"}是类MongoDB的日期对象存储格式,序列化时自动转UTC时间戳,本身无异常,问题核心是前端取日期时直接读取了本地时区的日期值,未做对齐处理。
修复方案
任选一种即可:
- 后端返回纯日期字符串:返回数据前不要直接传Date对象,将日期转为
YYYY-MM-DD格式的无时间、无时区字符串再传输,前端拿到后按当地时区解析为当天0点即可,不会出现偏移。后端转换示例:// d为原始Date对象 const dateStr = d.toISOString().split('T')[0]; // 输出2022-07-16格式 - 前端手动校准时区偏移:如果不修改后端返回格式,前端拿到Date对象后,加上本地时区偏移量,校准为当地0点再使用:
GMT-0700时区的const localDate = new Date(utcDate.getTime() + utcDate.getTimezoneOffset() * 60 * 1000);getTimezoneOffset()返回420(单位分钟,比UTC晚7小时即420分钟),加偏移后时间会校准为当地7月16日0点。 - 前后端统一业务时区:如果度假村业务固定在特定时区(如太平洋时区),后端生成日期时直接使用当地时区的0点,不要使用UTC 0点,从根源避免跨时区转换偏差。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

