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

为何yyyy-mm-dd格式字符串转Date异常,yyyy/mm/dd却正常?

问题描述

我有一个日期字符串2022-04-01,想要转换成Date对象,写了如下代码:

const startDate0Hours = new Date(new Date(startDate.value).setHours(0, 0, 0, 0));
console.log('this is the date (string):', startDate.value);
console.log('this is without replace:', new Date(startDate.value));
console.log('this is with replace (/-/g, "/"):', new Date((startDate.value).replace(/-/g,'/')));
console.log('this is with setHours(0,0,0,0):', startDate0Hours)

执行后输出:

this is the date (string): 2022-04-01
this is without replace: Thu Mar 31 2022 21:00:00 GMT-0300 (Brasilia Standard Time)
this is with replace (/-/g, "/"): Fri Apr 01 2022 00:00:00 GMT-0300 (Brasilia Standard Time)
this is with setHours(0,0,0,0): Thu Mar 31 2022 00:00:00 GMT-0300 (Brasilia Standard Time)

为什么用连字符-的日期字符串转换后日期提前一天且时间为21点,而用斜杠/的却能正确转换?


原因解析

这本质是JavaScript对不同日期字符串格式的解析规则差异:

  1. yyyy-mm-dd格式(ISO 8601标准格式):
    当你用new Date("2022-04-01")时,JS会默认把这个日期解析为UTC时区的00:00:00。你的本地时区是GMT-0300(巴西利亚时间),UTC的4月1日0点减去3小时,就是本地时间3月31日21点,这就是第一个输出的由来。

  2. yyyy/mm/dd格式:
    这种非ISO格式的日期字符串,JS会直接按照本地时区的00:00:00来解析,所以得到的就是本地时间4月1日0点,和你预期一致。

  3. 关于setHours(0,0,0,0)的问题:
    你先通过new Date(startDate.value)得到了本地时间3月31日21点的Date对象,然后调用setHours(0,0,0,0)是设置本地时区的0点,所以这个对象就变成了本地时间3月31日0点,这就是第三个输出的结果——不是你想要的4月1日0点。


解决方法

如果想要把yyyy-mm-dd格式的字符串转成本地时区的0点Date对象,有几种可靠的方式:

方式1:手动构造日期(最稳妥,无时区歧义)

直接拆分日期字符串,用new Date(year, monthIndex, day)构造(注意月份是0基的,4月对应3):

const dateStr = "2022-04-01";
const [year, month, day] = dateStr.split("-").map(Number);
const localMidnight = new Date(year, month - 1, day);
// 输出:Fri Apr 01 2022 00:00:00 GMT-0300 (Brasilia Standard Time)

方式2:先转UTC再转本地时区

先解析为UTC的0点,再设置本地时区的0点:

const dateStr = "2022-04-01";
const utcDate = new Date(dateStr + "T00:00:00Z"); // 明确指定UTC时间
const localMidnight = new Date(utcDate.getTime());
localMidnight.setHours(0, 0, 0, 0);
// 或者更简洁:
const localMidnight = new Date(new Date(dateStr).setUTCHours(0,0,0,0));

方式3:使用日期处理库(推荐)

如果项目中经常处理日期,建议用Day.js、Luxon这类轻量库,避免手动处理时区和格式的坑:

// Day.js示例
const dayjs = require('dayjs');
const localMidnight = dayjs("2022-04-01").startOf('day').toDate();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 09:24:25