【问题标题】:date-fns returns invalid date on safaridate-fns 在 safari 上返回无效日期
【发布时间】:2019-09-03 10:25:00
【问题描述】:

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

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 上运行良好并返回 We Mar, y

但在 Safari 中返回 Invalid Date

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

【问题讨论】:

  • 为什么要解析两次日期?
  • 也许:"2019-03-06 00:00:00".split(" ").join("T")

标签: javascript date date-fns


【解决方案1】:

我看到两个问题:

  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 中更新后,这种情况发生了变化,但最终的结果是:

当 UTC 偏移表示不存在时,仅日期形式被解释为 UTC 时间,而日期时间形式被解释为本地时间。

由于您的字符串没有 UTC 偏移量(没有 Z+00:00 或类似的),并且确实有时间,因此它以当地时间解析。 (同样,在符合规范的 JavaScript 引擎上¹)。

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


¹RobG 指出 Safari 将 new Date("2019-03-06T00:00:00") 解析为 UTC。可悲的是,这是 Apple 的 JavaScript 引擎 JavaScriptCore 中的a bug。它不仅影响 Safari,还影响 iOS 上的 Chrome(可能还有任何其他 iOS 浏览器;我测试过 Brave、Opera 和 Dolphin),因为 Chrome 必须在 iOS 上使用 JavaScriptCore 而不是其通常的 V8,因为应用程序不能分配可执行内存,因此无法在 iOS 上使用 JIT 引擎。但是 V8 团队已经创建了一个interpreter-only version of V8,所以如果速度足够快,iOS 上的 Chrome(和 Brave)可能会更新以使用它。

【讨论】:

  • 有没有办法将"2019-03-06 00:00:00" 转换为"2019-03-06T00:00:00",因为我无法控制从 API 获得的内容?
  • @user1012181 - 字符串替换:theDate = theDate.replace(/ /g, "T");。您需要检查 API 提供给您的内容是 UTC 还是本地时间。如果是 UTC,请在末尾添加 ZtheDate = theDate.replace(/ /g, "T") + "Z";
  • 谢谢,我去看看
  • "…它是在当地时间解析的。"。不,Safari 的解析器坏了,new Date("2019-03-06T00:00:00") 被解析为 UTC。 :-(
  • @RobG - "(在符合规范的浏览器上)" :-) (但我发现这两个地方都没有。)我很惊讶 Safari但是,仍然与规范不一致,呃。这就是为什么我不将日期解析为没有时区的字符串。
【解决方案2】:

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

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

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

【讨论】:

    猜你喜欢
    • 2021-06-22
    • 1970-01-01
    • 2016-10-28
    • 1970-01-01
    • 2021-06-25
    • 2021-03-28
    • 2021-01-23
    • 2019-02-02
    • 1970-01-01
    相关资源
    最近更新 更多