您的日期字符串不是指定使用的格式new Date
。规范中唯一的格式是ISO-8601 的简化版本,在 ES5 (2009) 中添加。你的字符串不是那种格式,但它真的很接近。将其更改为规范中未包含但普遍支持的格式也很容易
四种选择:
- 使用即将推出的
Temporal
功能(现在处于第 3 阶段)
- 指定格式
- 几乎普遍支持的未指定格式
- 自己解析
使用即将推出的Temporal
功能
截至 2021 年 8 月的此更新,该Temporal
提案处于第 3 阶段。您可以使用它来解析您的字符串,将其视为 UTC 或本地时间:
将字符串视为 UTC:
// (Getting the polyfill)
const {Temporal} = temporal;
const dateString = "2015-12-31 00:00:00";
const instant = Temporal.Instant.from(dateString.replace(" ", "T") + "Z");
// Either use the Temporal.Instant directly:
console.log(instant.toLocaleString());
// ...or get a Date object:
const dt = new Date(instant.epochMilliseconds);
console.log(dt.toString());
<script src="https://unpkg.com/@js-temporal/polyfill/dist/index.umd.js"></script>
或将其视为当地时间:
// (Getting the polyfill)
const {Temporal} = temporal;
const dateString = "2015-12-31 00:00:00";
console.log("Parsing as local time:");
const tz = Temporal.Now.timeZone();
const instant = tz.getInstantFor(dateString.replace(" ", "T"));
console.log(instant.toLocaleString());
const dt = new Date(instant.epochMilliseconds);
console.log(dt.toString());
<script src="https://unpkg.com/@js-temporal/polyfill/dist/index.umd.js"></script>
Temporal
不存在下面提到的指定日期/时间字符串格式在历史上没有指定时区的问题。
指定格式
如果您将空格更改为 a T
,您将符合规范:
var dateString = "2015-12-31 00:00:00";
// Treats the string as local time -- BUT READ BELOW, this varied
var d = new Date(dateString.replace(" ", "T"));
console.log(d.toString());
(我假设您实际上并没有使用字符串文字,因此replace
调用。)
为了在旧浏览器中进行可靠的时区处理,您还需要附加一个Z
(用于 GMT/UTC)或一个时区指示符(+
/ -
HH:MM
),因为在 ES5 中错误指定了没有它们的字符串处理,在 ES2015 中进行了更新,然后在 ES2016 中进一步更新。当前版本的现代浏览器现在遵循规范,其中说:
- 如果字符串上有时间但没有时区指示符,则以本地时间解析字符串
- 如果字符串上没有时间且没有时区指示符,则以 UTC 解析字符串
(ES5 表示始终默认为UTC。ES2015 表示始终默认为本地时间。ES2016是定义当前行为的地方。从那以后它一直很稳定。)
所以最好包含一个时区指示器,特别是如果您必须支持旧版浏览器。请注意,它必须是Z
(UTC) 或+
/ -
HH:MM
;CST
不允许使用诸如此类的缩写,因为它们没有标准。这是一个 UTC 示例:
var dateString = "2015-12-31 00:00:00";
// Treat the string as UTC
var d = new Date(dateString.replace(" ", "T") + "Z");
console.log(d.toString());
几乎普遍支持的未指定格式
规范中没有第二种格式,但几乎得到了普遍支持,并且已经存在了很长时间:YYYY/MM/DD HH:MM:SS
,它被解释为本地时间。所以:
var dateString = "2015-12-31 00:00:00";
// Treats the string as local time
var d = new Date(dateString.replace(/-/g, "/"));
console.log(d.toString());
不过,这又是未指明的行为,所以请谨慎购买。但它至少可以在 IE8+(可能更早)、Chrome 和其他任何使用 V8 JavaScript 引擎、Firefox 和 Safari 的平台上运行。
自己解析
自己解析该字符串也很容易。使用 ES2020+ 特性:
function parseDate(str) {
const [dateparts, timeparts] = str.split(" ");
const [year, month, day] = dateparts.split("-");
const [hours = 0, minutes = 0, seconds = 0] = timeparts?.split(":") ?? [];
// Treats the string as UTC, but you can remove the `Date.UTC` part and use
// `new Date` directly to treat the string as local time
return new Date(Date.UTC(+year, +month - 1, +day, +hours, +minutes, +seconds));
}
const dateString = "2015-12-31 00:00:00";
const d = parseDate(dateString);
console.log(d.toString());
或者只有 ES5 级别的功能(因为问题来自 2015 年):
function parseDate(str) {
var parts = str.split(" ");
var dateparts = parts[0].split("-");
var timeparts = (parts[1] || "").split(":");
var year = +dateparts[0];
var month = +dateparts[1];
var day = +dateparts[2];
var hours = timeparts[0] ? +timeparts[0] : 0;
var minutes = timeparts[1] ? +timeparts[1] : 0;
var seconds = timeparts[2] ? +timeparts[2] : 0;
// Treats the string as UTC, but you can remove the `Date.UTC` part and use
// `new Date` directly to treat the string as local time
return new Date(Date.UTC(year, month - 1, day, hours, minutes, seconds));
}
var dateString = "2015-12-31 00:00:00";
var d = parseDate(dateString);
console.log(d.toString());