questdb中的所有时间戳都是UTC时间,但是当我用nodejs questdb客户端读取它们时,它会给予我正确的时间,但是是我的本地时区。
例如,在数据库中存储了10:00 UTC的时间,当在nodejs中阅读这个时间时,我将获得10:00 GMT+0200(因此8:00 UTC)。
如何将时间读取为UTC/GMT+0200,以便获得正确的Date对象?
这是我当前从questdb读取数据的代码:
async getData(unitId: string) {
const client = new Client([...]);
await client.connect();
const res = await client.query(
`select Timestamp from 'myData' where ...`,
);
await client.end();
return res.rows.map((x) => x?.Timestamp); // Timestamp is already an Date object with 10:00 GMT+0200
}
编辑:
为了更清楚地说明我的问题:
数据库包含日期2023-09-26T06:18:56.740000Z
。我只是在当地时间8:18保存了该条目,因为我位于GMT+0200,这是正确的UTC时间。
现在,当我想用上面的代码从数据库中获取这个条目时,我会得到一个日期,就像时间戳条目被读取为本地时间一样。这意味着它将采用06:18并将GMT+0200应用于它,使其成为06:18 GMT+0200。当我做Timestamp.toISOString()
时,我会得到2023-09-26T04:18:56.740Z
。
3条答案
按热度按时间ujv3wf0j1#
JavaScript
Date
对象 * 始终 * 仅为UTC。它们是Unix时间戳的简单 Package 器,具有毫秒精度。您可以使用.valueOf()
或.getTime()
来查看时间戳,或者将其强制为数字类型(即+d
)。如果你的数据库在JS
Date
对象中返回UTC时间,那么它已经在做正确的事情了。你展示的代码返回了
Date
对象,但是你没有展示你是如何使用这些对象的。您可能正在查看将Date
对象强制转换为字符串以供显示的结果。例如,对.toString()
的调用将使用计算机的本地时区将基于UTC的时间戳转换为本地时间,然后发出表示本地时间的字符串。相比之下,调用.toISOString()
或.toUTCString()
将发出一个表示UTC时间的字符串,而不进行任何转换。值得注意的是(这通常是一个陷阱)-如果你
console.log(someDateObject)
-结果字符串可能是 either 本地时间或UTC时间,这取决于环境。ECMAScript规范和WhatWG控制台规范都没有定义它应该是什么,多年来不同的JavaScript实现选择了不同的方式。不记录Date
对象,而是记录Date
对象上的某个函数的字符串输出-例如.toISOString()
(如果需要UTC)。t5zmwmid2#
您所引用的代码片段使用
pg
库,因此您应该查看其文档,即数据类型页面:https://node-postgres.com/features/types文件提到以下内容:
同样,当阅读
date
、timestamp
或timestamptz
列值返回到JavaScript中时,node-postgres将把值解析为JavaScript Date对象的示例。node-postgres将
DATE
和TIMESTAMP
列转换为设置在process.env.TZ
的节点进程的本地时间。所以,这就是为什么你得到一个带有本地时区而不是UTC的
Date
。如果您不想弄乱环境变量,可以为
timestamp
类型定义一个自定义解析器。请查看https://github.com/brianc/node-pg-types中的示例以了解更多详细信息。P.S.潜在的原因是Postgres假设
timestamp
time没有时区,而在QuestDB中它总是有UTC时区。我们以后会努力解决的。vvppvyoh3#
我目前的一个快速解决方法是再次将时区添加到Date: