2013-12-20 80 views
8

我有一些時間戳存儲爲Postgres類型timestamp without time zone使用node-postgres獲取Postgres「沒有時區的時間戳」在utc

我將使用時間戳2013-12-20 20:45:27作爲示例。我打算這代表UTC時間戳。

在psql中,如果我運行查詢SELECT start_time FROM table_name WHERE id = 1,我會返回該時間戳字符串,如預期的那樣:2013-12-20 20:45:27

但是,如果在我的Node應用程序中,我使用node-postgres庫來運行相同的查詢,我會在本地時區返回一個時間戳:Fri Dec 20 2013 20:45:27 GMT-0600 (CST)。這是一個Javascript日期對象,但它已經存儲爲該時區。我真正想要的是一個代表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的返回的日期字符串時區指定(即Z,或+06:30沒有,那麼它只是構建一個JavaScript日期對象,我相信它只包含本地時區。我可能需要更改我的應用程序以在DB中存儲時區或覆蓋此轉換器。

回答

3

這不是最好的解決方案,但我只是的SwitchE d使用Postgres類型timestamp with time zone並確保我堅持到數據庫的所有日期都是UTC。

+0

在我的情況下,由於夏令時問題,這個解決方案無論如何都比較安全。 –

11

不恢復一個老問題,但看到我怎麼只是有相同的問題here,還存在另一種解決方案,它通過覆蓋型分析器工程使用timestamp without time zone

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

這將保持node-pg將該值解析爲一個Date對象,併爲您提供原始時間戳字符串。

來源:node-postgres issues

+0

這應該是可接受的解決方案 – SneakyMummin

+0

我不知道這是否仍被認爲是可行的,但它改變了解析器的行爲,以返回一個字符串而不是日期對象(至少在pg-promise的當前迭代中,在封面下使用node-postgres)。這打破了我所有預計會返回日期的代碼,所以這個解決方案對我沒有幫助。只有對我有用的東西是在將它傳遞給日期構造函數之前修改stringValue:'return new Date(stringValue +'+0000')'。希望看到一個更好的方法來從不指定時區的ISO 8601字符串創建UTC日期對象。 – stone

+0

確實如此,但OP說一串就夠了。無論哪種方式,重寫解析器都很容易返回任何需要的東西,包括新的日期對象。 – BadIdeaException

1

您可以修改解析器明白了,作爲@BadIdeaException建議。以下是關於爲什麼它不能按預期工作的更多細節以及兩種可能的解決方案。

對於timestamp without time zone類型列,解析器接收ISO 8601格式的字符串,沒有指定時區:2016-07-12 22:47:34

任何時候你在JavaScript中創建一個Date對象,如果不指定時區,它假定日期在當前時區。對於UTC定義的日期,根據定義在GMT時區內,除非您的Javascript正好在GMT時區運行,否則這會給您一個日期,其中的錯誤絕對值(date.value)爲,日期爲

因此,即ISO 8601字符串不能由Date構造函數直接轉換爲UTC日期。選項有:修改字符串,它會被解釋爲UTC:

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

,或者讓你的約會與「錯」(電流)時區創建,然後它在提取值(仍您當前的時區),然後使用這些值在UTC時區中生成日期。請注意Date.UTC()返回日期而不是一個對象,然後可以將其傳遞給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()) 
    ); 
}