Moment.js 2.22.1格式化日期时日期滞后1天问题求助
嘿,这个坑我之前踩过!你遇到的问题核心是时区转换导致的日期偏移,咱们结合你的两个例子来分析:
问题原因拆解
示例1分析
你先用new Date(value)获取了本地时区的日、月、年,然后用month + ' ' + day + ' ' + fullYear拼接成字符串,再传给new Date()生成一个本地时区的日期(比如你所在时区是GMT+0100的话,这个日期就是2018-06-07T00:00:00+01:00)。
当你用moment.utc()处理这个Date对象时,Moment会把它转换为UTC时间——也就是2018-06-06T23:00:00Z,这时候格式化出来的日期自然变成了06号,而非预期的07号。
另外还有个小细节:getMonth()返回的是0-11(5对应6月),但你用MM-DD-YYYY格式解析时,MM要求的是1-12,这里其实也存在格式不匹配的隐患!
示例2分析
输入的日期是Thu May 31 2018 00:00:00 GMT+0100,这是一个带时区偏移的本地时间。用moment.utc(new Date(value))处理时,Moment会把它转成UTC时间:Wed May 30 2018 23:00:00 GMT+0000,所以格式化后显示30号就不奇怪了。
针对性解决方案
根据你的业务需求,有两种常用的解决思路:
思路1:不需要UTC,保留本地时区处理
如果你的业务逻辑不需要强制使用UTC时间,直接去掉.utc(),用Moment的本地模式处理即可:
- 示例1修改后代码:
// 注意月份要+1,匹配MM格式的1-12 moment(`${month + 1}-${day}-${fullYear}`, 'MM-DD-YYYY').format('DD-MM-YY') - 示例2修改后代码:
moment(new Date(value)).format('DD-MM-YY')
思路2:需要UTC时间,正确解析输入日期
如果必须用UTC处理,要确保Moment把输入的日期当作UTC来解析,而不是先转成本地时区再转UTC:
- 示例1可以直接用UTC模式解析字符串:
// 月份+1后用MM格式解析 moment.utc(`${month + 1}-${day}-${fullYear}`, 'MM-DD-YYYY').format('DD-MM-YY') - 示例2如果要把带时区的日期转为UTC但保留原日期(比如你想忽略时区偏移,只取日期部分),可以直接提取UTC的日、月、年:
const date = new Date(value); moment.utc([date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()]).format('DD-MM-YY')
总结
本质上,moment.utc()的作用是将输入的时间转换为UTC时区,如果你传入的是本地时区的Date对象,就会出现日期偏移。解决的关键是:明确你需要处理的是本地时区还是UTC时区,然后选择对应的Moment方法来解析和格式化。
内容的提问来源于stack exchange,提问作者Tom

