date-fns returns Safari 上的无效日期

date-fns returns invalid date on safari

我正在使用 date-fns 到 return 一些值,如下所示:

import { format, formatDistance } from "date-fns";

var date = new Date("2019-03-06 00:00:00");
console.log(format(new Date(date), "dd MMM, y"));

它在 Chrome 和 returns We Mar, y

上工作正常

但是 returns Invalid Date 在 Safari 中。

我认为这是因为日期(“2019-03-06 00:00:00”)不是 ISO 8601 格式。但这是我从端点接收到的格式。是否有任何选项可以将其转换为正确的格式并使其在 Safari 上运行?

我看到两个问题:

  1. 您第一次解析日期时依赖的是非标准输入格式。

  2. 您将 Date 传递给 Date 构造函数,这会强制它将日期转换为字符串,然后解析该字符串。

我只会解析一次,并在第一次调用 new Date 时使用 standard date/time format:

import { format, formatDistance } from "date-fns";

var date = new Date("2019-03-06T00:00:00");
// Note -----------------------^
console.log(format(date, "dd MMM, y"));
// No `new Date`   ^

请注意,您的字符串将被解析为 当地时间(在符合规范的 JavaScript 引擎上¹),因为它包含字符串的时间部分。不幸的是,在 ES2015 中添加了格式并在 ES2016 中进行了更新之后,这种情况发生了变化,但最终的结果是:

When the UTC offset representation is absent, date-only forms are interpreted as a UTC time and date-time forms are interpreted as a local time.

因为您的字符串没有 UTC 偏移量(没有 Z+00:00 或类似的),并且有时间,所以它在本地时间进行解析。 (同样,在符合规范的 JavaScript 引擎上¹)。

我的建议是要么不要使用内置的 Date 对象解析日期字符串,要么确保在字符串上始终有时区指示符。


¹ RobG pointed out that Safari parses new Date("2019-03-06T00:00:00") as UTC. Sadly, this is a bug in JavaScriptCore, Apple's JavaScript engine. It affects not only Safari, but Chrome on iOS as well (and probably any other iOS browser; I've tested Brave, Opera, and Dolphin), since Chrome has to use JavaScriptCore instead of its usual V8 on iOS because apps can't allocate executable memory, so JIT engines can't be used on iOS. But the V8 team have made an interpreter-only version of V8,因此 iOS 上的 Chrome(和 Brave)如果足够快,可能会更新为使用它。

对此的简单回答可以是,将日期转换为时间戳和值并将其提供给 format

import { format, formatDistance } from "date-fns";

var date = new Date("2019-03-06").getTime();
console.log(format(new Date(date), "dd MMM, y"));