2017-01-12 107 views
1

我正在使用pg-promise lib來使用Postgres DB。我不明白爲什麼有PG Promise沒有正確返回「帶時區的時間戳」字段

SELECT date FROM ro WHERE id = 13; 

回報

date   
------------------------ 
2017-01-19 00:00:00+02 
(1 row) 

這PGP電話直接查詢DB:

var sql = 'SELECT date from ro WHERE id = 1366'; 
    Dbh.odb.any(sql) 
     .then(ro => { 
     console.log(ro); 
     res.ok(ro) 
     }) 

回報

{ 
    "date": "2017-01-18T22:00:00.000Z" 
} 

我期望是

{ 
    "date": "2017-01-19T00:00:00.000Z" 
} 
+0

庫可能會轉換爲本地時間,並且數據庫將其存儲在服務器的本地時間。 – ppovoski

+0

確保您使用的是最新版本的庫,因爲時間轉換的方式在很久以前就已更新。 –

+0

順便說一句,你正在查詢不同的記錄ID-S:'13'和'1366'。此外,你正在獲得同一時間,但對於不同的時區 - 「T00」和「T22」。 –

回答

2

您是否在運行pg-promise的同一臺機器上運行psql

從文檔上timestamp with timezone

對於具有時區的時間標記,內部存儲的數值總是UTC(全球統一時間,習慣上稱爲格林威治標準時間,GMT)。使用該時區的適當偏移量將具有指定明確時區的輸入值轉換爲UTC。如果在輸入字符串中沒有規定時區,則假定其位於由系統的TimeZone parameter指示的時區,並且使用時區區域的偏移量轉換爲UTC。

當輸出帶時區值的時間戳時,它始終從UTC轉換到當前時區區域,並在該區域中顯示爲本地時間。要查看其他時區的時間,請更改時區或使用時區構造中的(請參閱第9.9.3節)。

所以時區被存儲在UTC,以及檢索基於所述TimeZone參數,從該文檔(略清理)

TimeZone配置參數可以被設置,

  1. 在文件postgresql.conf
  2. Chapter 19中描述的任何其他標準方式。
  3. SQL命令SET TIME ZONE設置會話的時區。這是SET TIMEZONE TO的一種替代拼寫,具有更多SQL規範兼容的語法。
  4. PGTZ環境變量由libpq客戶端用於在連接時向服務器發送SET TIME ZONE命令。

,所以你可以隨時,

var sql = `SELECT date AT TIME ZONE '+02' from ro WHERE id = 1366`; 
    Dbh.odb.any(sql) 
     .then(ro => { 
     console.log(ro); 
     res.ok(ro) 
     }) 

或設置客戶端會話,或者服務器的時區。

你可以找到timezone這裏

SELECT * FROM pg_timezone_names(); 
2

psql輸出顯示您有時間戳是在午夜,但是,UTC + 2時區(2017年1月19日00潛在價值:00:00+這是比UTC早兩個小時的時間。

也就是說,當UTC + 2的時間是00:00:00時,它僅是UTC前一天的22:00:00 - 這就是你得到的:2017-01- 18T22:00: 00.000 Z

如果您從該UTC日期創建JavaScript日期,則如果您使用UTC + 2,則將獲得午夜。這是我看到在UTC + 2 Chrome的控制檯:

new Date('2017-01-18T22:00:00.000Z'); 
Thu Jan 19 2017 00:00:00 GMT+0200 (EET) 

如果你真的希望擁有存儲爲午夜(UTC)時間戳記,當你插入日期應定義時區。但請注意,那麼UTC + 2將不會是午夜:

new Date('2017-01-19T00:00:00.000Z'); 
Thu Jan 19 2017 02:00:00 GMT+0200 (EET)