使用 date-fns 将日期解析为 UTC 的正确方法
Posted
技术标签:
【中文标题】使用 date-fns 将日期解析为 UTC 的正确方法【英文标题】:Proper way to parse a date as UTC using date-fns 【发布时间】:2021-03-18 20:33:05 【问题描述】:我有一个带有一些时间戳的日志文件
2020-12-03 08:30:00
2020-12-03 08:40:00
...
我从日志提供者的文档中知道时间戳是用 UTC 编写的(尽管不使用 ISO 格式)
现在我想parse them with date-fns:
const toParse = "2020-12-03 08:40:00"
parse(toParse, 'yyyy-MM-dd HH:mm:ss', new Date()).toISOString()
因为我的计算机的语言环境是 UTC+1,所以我看到的是:
> "2020-12-03T07:40:00Z"
预期:
> "2020-12-03T08:40:00Z".
这是我目前用来告诉 date-fns 解析为 UTC 的 hack:
const toParse = "2020-12-03 08:40:00"
parse(toParse + '+00', 'yyyy-MM-dd HH:mm:ss' + 'X', new Date()).toISOString()
正如预期的那样,
> "2020-12-03T08:40:00Z".
有没有使用 date-fns 的正确方法?正在寻找等同于时刻的moment.utc()
【问题讨论】:
您可能想看看developer.mozilla.org/en-US/docs/Web/javascript/Reference/… 您知道将存储日期调整为您的时区的偏移量。 Date-fns-tz 支持 Intl.DateTimeFormat。 无论哪种方式,您都应该指明日期时间值所具有的时区。您可以简化您的 hack:parseIso(toParse+'Z').toISOString()
如果“2020-12-03 08:40:00”被解析为UTC +1,则Z时间是07:40:00Z,而不是09:40。 :-)
感谢 RobG,我进行了编辑以修复错误
【参考方案1】:
我不知道“正确”,但您可以使用 zonedTimeToUtc 将时间戳视为具有您喜欢的任何偏移量或时区,包括 UTC,例如
// Setup
var parse = require('date-fns');
var zonedTimeToUtc = require('date-fns-tz');
// Parse an ISO 8601 timestamp recognised by date-fns
let loc = 'UTC';
let s1 = '2020-12-03 08:30:00';
let utcDate = zonedTimeToUtc(s1, loc);
// Show UTC ISO 8601 timestamp
console.log(utcDate.toISOString()); // "2020-12-03T08:30:00.000Z"
// Parse non–standard format yyyyMMdd
let s2 = '20210119';
let fIn = 'yyyyMMdd';
let d = zonedTimeToUtc(parse(s2, fIn, new Date()), loc);
console.log(d.toISOString()); // "2021-01-19T00:00:00.000Z"```
您可以在npm.runkit.com/date-fns 进行测试。
【讨论】:
谢谢,这正是我想要的!但是,您的代码没有使用fIn
(幸运的是,在此示例中,它以 UTC 解析,但日志的格式可能不太友好)。 zonedTimeToUtc(parse(s, fIn, new Date()), loc);
工作。
@YannP — 是的,如果 date-fns 无法识别格式,那么您需要添加 parse。我发现始终将 Date 传递给 parse 的要求是一个莫名其妙的设计决策。
完全同意。我必须在我的拉取请求中添加评论,以解释为什么“需要”它......【参考方案2】:
使用 parse 和 zonedTimeToUtc 的示例
it('should parse polish date', async () =>
expect.assertions(1)
const dateWithoutTime = '29 gru 2003'
const parsed = parse(dateWithoutTime, 'd LLL yyyy', new Date(),
locale: pl,
)
const dateUTC = zonedTimeToUtc(parsed, 'UTC')
expect(dateUTC.toISOString()).toStrictEqual('2003-12-29T00:00:00.000Z')
)
【讨论】:
【参考方案3】:我认为您正在寻找parseJSON,它支持多种格式(但不允许您指定源格式)。
将 UTC 时间的完整 ISO 日期字符串(以 JSON 格式传输日期的典型格式)转换为 JavaScript Date 实例。
import parseJSON from 'date-fns';
const utcDate = parseJSON('2020-12-03 08:40:00');
// Thu Dec 03 2020 19:40:00 GMT+1100 (Australian Eastern Daylight Time)
【讨论】:
以上是关于使用 date-fns 将日期解析为 UTC 的正确方法的主要内容,如果未能解决你的问题,请参考以下文章