你的日期字符串没有指定与
new Date
一起工作的格式。该规范中唯一的格式是
ISO-8601的一个简化版本
(2009年在ES5中加入,在ES2015和ES2016中更新),以及由
Date.prototype.toString
.你的字符串没有采用这两种格式,但它确实接近于类似ISO-8601的格式。把它改成规范中没有的、但被普遍支持的格式也很容易
Four options for you:
Use the upcoming
Temporal
feature (it's now at Stage 3)
The specified format
An unspecified format that's near-universally supported
Parse it yourself
Use the upcoming
Temporal
feature
The
Temporal
proposal
在2021年8月的这次更新中处于第三阶段。你可以用它来解析你的字符串,将其视为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>
替换代码2】没有下面提到的问题,即历史上没有指定时区时,指定的日期/时间字符串格式。
The ISO-8601-like format
如果你把空间改成
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中进一步更新。当前版本的现代浏览器现在遵循的规范是:。
If there's a time on the string but and no timezone indicator, parse the string in local time
If there's no time on the string and no timezone indicator, parse the string in 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());
An unspecified format that's near-universally supported
还有一种格式不在规范中,但几乎被普遍支持,而且已经有很长一段时间了。替换代码23】,它被解释为当地时间。所以。
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中工作。
Parse it yourself
自己解析这个字符串也很容易。使用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());