使用node-postgres在utc中获取Postgres的“没有时区的时间戳”

我有一些时间戳存储为Postgrestypes的timestamp without time zone

我将以2013-12-20 20:45:27时间戳为例。 我打算这代表一个UTC时间戳。

在psql中,如果我运行查询SELECT start_time FROM table_name WHERE id = 1 ,我得到的时间戳string,如预期: 2013-12-20 20:45:27

但是,如果在我的Node应用程序中,我使用node-postgres库来运行相同的查询,我会在当地时区取回一个时间戳: Fri Dec 20 2013 20:45:27 GMT-0600 (CST) 。 这是一个Javascriptdate对象,但它已经存储为该时区。 我真正想要的是一个date对象(甚至只是一个string),代表2013-12-20 20:45:27 GMT+0000 。 我已经知道这一次是UTC。

我已经尝试在我的postgresql.conf文件中设置时区参数: timezone = 'UTC' ,结果没有区别。

我究竟做错了什么?

编辑

这个问题似乎是在这个文件中: https : //github.com/brianc/node-postgres/blob/master/lib/types/textParsers.js

如果从Postgres返回的datestring没有指定时区(即Z ,或+06:30 ,那么它只是构build一个JavaScriptdate对象,我相信这只会包括本地时区。更改我的应用程序以在DB中存储时区或覆盖此转换器。

不是为了恢复一个老问题,而是看到我刚才在这里遇到了同样的问题,还有一个替代解决scheme,它通过覆盖typesparsing器来使用timestamp without time zone

 var pg = require('pg'); var types = pg.types; types.setTypeParser(1114, function(stringValue) { return stringValue; }); 

这将保持node-pg将该值parsing为Date对象,并给予原始的时间戳string。

来源:从节点postgres问题得到它

这不是最好的解决scheme,但我只是转而使用timestamp with time zone的Postgrestypestimestamp with time zone并确保我坚持到数据库的所有date都是UTC。

您可以修改parsing器,如@BadIdeaException所示。 以下是关于为什么它不能按预期工作的更多细节,以及两个可能的解决scheme。

对于timestamp without time zonetypestimestamp without time zone列,parsing器接收到ISO 8601格式的string,没有指定时区: 2016-07-12 22:47:34

任何时候如果你在Javascript中创build一个Date对象,如果你没有指定一个时区,那么它假定date在当前时区。 对于按照定义在GMT时区中的UTCdate,除非您的Javascript正好在GMT时区中运行,否则这会为您提供不正确的绝对值(date.value)的date。

因此, ISO 8601string不能由Date构造函数直接转换为UTCdate 。 您的选项是:修改string,以便将其解释为UTC:

 var pg = require('pg'); var types = pg.types; types.setTypeParser(1114, function(stringValue) { return new Date(stringValue + "+0000"); }); 

或者使用“错误”(当前)时区创builddate,然后提取它的值(仍在当前时区中),然后使用这些值在UTC时区中生成date。 请注意Date.UTC()返回一个date而不是一个对象,然后可以传递给Date构造函数。

 types.setTypeParser(1114, function(stringValue) { var temp = new Date(stringValue); return new Date(Date.UTC( temp.getFullYear(), temp.getMonth(), temp.getHours(), temp.getMinutes(), temp.getSeconds(), temp.getMilliseconds()) ); }