javascript - 将 Node/JavaScript 中的格式化日期转换为 UTC
问题描述
我正在使用 Node/Express 服务器在将日期发送到浏览器之前对其进行格式化。我拥有的日期以 UTC 格式保存在数据库中,例如:
2020-09-15 11:52:22.000
我现在想在不更改的情况下格式化这个日期,并将其发送到浏览器,所以无论节点服务器在哪里,也无论浏览器在哪里,它总是显示这个 UTC 日期。查看此日期的人将在美国、英国、欧盟,但我希望他们都看到相同的 UTC 日期。
我在英国,我正在使用date-fns
,我目前正在本地运行 Node。我的应用程序已经使用了date-fns
,我不想仅仅为这个任务添加另一个日期/时间依赖项。
如果我这样做:
const d = format(new Date('2020-09-15 11:52:22.000'), 'dd MMM yyyy HH:mm:ss')
我得到:15 Sep 2020 12:52:22
...这是我当地时间(英国,英国夏令时)的日期。
如果有一件事让我感到困惑,那就是日期和时间!:-)
在 Node 中,我如何获取2020-09-15 11:52:22.000
并格式化它以获得15 Sep 2020 11:52:22
..?
解决方案
你的问题是:
new Date('2020-09-15 11:52:22.000')
强烈建议不要对不支持的格式使用内置解析器。它依赖于实现,并且经常在不同的实现中返回不同的结果。
此外,该字符串没有时区,因此应视为本地。因此,即使正确解析,它也将代表具有不同偏移量的每个地点的不同时刻。
Date-fns 有一个强大的解析器,所以你应该使用它而不是内置的解析器。如果您希望时间戳被视为 UTC,最简单的方法是添加尾随“Z”和时区标记以进行解析。
要支持输出时区,您必须包含date-fns-tz。以下是您可以在npm.runkit运行的一些代码。格式部分似乎产生了正确的结果,但是如果将时区标记添加到格式字符串(即“X”或“XX”),它会显示本地时区偏移量,而不是应用于字符串的偏移量,以便显示正确偏移,您必须手动添加它(我认为这是 date-fns-tz 中的错误)。
const dateFns = require("date-fns");
const { zonedTimeToUtc, utcToZonedTime, format } = require('date-fns-tz');
let timestamp = '2020-09-15 11:52:22.000';
let tz = 'Z';
let date = dateFns.parse(timestamp + tz, 'yyyy-MM-dd HH:mm:ss.SSSX', new Date());
// Show timestamp was parsed as UTC
console.log(date.toISOString()); // 2020-09-15T11:52:22.000Z
// Produce UTC output - need to set timezone first
let utcDate = utcToZonedTime(date, 'UTC');
// Manually add timezone to formatted string
console.log(format(utcDate, 'd MMM yyyy HH:mm \'UTC\'', 'UTC')); // 15 Sep 2020 11:52 UTC
请注意,utcToZonedTime(date, 'UTC')
实际上创建了一个由指定偏移量修改的新日期并将其分配给utcDate,我认为这是一个真正的 kludge。它现在只有在你知道它是如何被修改的时候才有用,你不知道它实际上应该代表什么时间。在这种情况下,可能很清楚,因为我们使用的是 UTC,但其他偏移量问题更大。
如果初始时间戳采用 ECMAScript 支持的格式,例如与toISOString生成的格式相同:2020-09-15T11:52:22.000Z,将节省大量精力。
推荐阅读
- windows - 在 Windows 上休息:有什么理由反对使用外部 openssl?
- angular - 角度路由器解析器 - 重新加载时从父级获取参数
- php - 将fastcgi_pass从网络套接字切换到unix套接字后,Laravel“由于不活动而导致页面过期”
- swift - Swift 4 从“执行”函数调用中获取布尔结果
- javascript - 如何用零填充数组中缺失的月份?
- reactjs - React Navigation:如何从堆栈返回另一个堆栈中的屏幕
- swift - 无法在 Mojave 上安装 jazzy
- c++ - 我可以将智能指针推送到智能指针列表吗?
- javascript - 当用户将鼠标悬停在chart.js中绘制的折线图上时,如何让工具提示显示更长时间?
- sbt - 为未执行的 sbt 子项目任务(例如编译、测试)添加了依赖项