Date

時間分為以有無時區分類,分為帶有時區資訊的字串與無帶有時區的字串與timestamp

帶有時區的:

2017-09-10 12:00:00

以上傳入new Date 或 moment() 會以當下時區 做轉換內部放置的UTC 時間,時區為GMT + 8

new Date('2017-09-10 12:00:00').getHours()
>> 12
new Date('2017-09-10 12:00:00').getUTCHours()
>> 4

若 傳入無時區的字串的時候,則會根據當下時區的做轉換,時區為 GMT + 8,而UTC 則跟原本傳入的時間一致

new Date('2017-09-10T12:00:00Z').getHours()
>> 20
new Date('2017-09-10T12:00:00Z').getUTCHours()
>> 12
new Date('2017-09-21')
>> Thu Sep 21 2017 08:00:00 GMT+0800 (CST)
new Date('2017-09-21').toUTCString()
>> "Thu, 21 Sep 2017 00:00:00 GMT"
new Date('2017-09-21 00:00:00').toUTCString()
>> "Wed, 20 Sep 2017 16:00:00 GMT"

Mongodb 預設放置 UTC 字串,所以如何跟前端傳入的時間格式做配合,變成設計的考量之一

  1. 若前端傳入帶有時區的資訊,則new Date("2017-09-10 12:00:00")Mongodb 會自動根據server 時區 以UTC 放置。

    1. 這會導致前端與server 時區不一致 導致存放時間有誤的問題

    2. 所以前端要把時間轉為utc 無時區資訊丟給server 存放 變成 new Date("2017-09-10T12:00:00Z")

  2. 要撈出指定時間區段時,則使用條件進行查詢{$gte: new Date("2017-09-10 12:00:00"), $lt: new Date(''2017-09-10 18:00:00")}

    1. 此問題是會根據server 所在的時間做時間的轉換,若server 的時區與前端不同,則轉換後會導致查詢時間有誤

      1. e.g 若server 時區為 GMT + 4 則查詢的UTC 時間區段為 2017-09-10T08:00:00Z ~ 2017-09-10T14:00:00Z 與預期的2017-09-10T04:00:00Z ~ 2017-09-10T10:00:00Z 有誤

      2. 第二種方式 查詢時直接傳來UTC 格式(無時區)的資訊,讓server 不會根據當下時區作轉換

      3. 第三種方式,是第一種加上額外的時區資訊,讓server 可以轉換

  3. 若前端要使用後端的API 資料中的時間格式,最好的方式是給UTC 無時區格式,方便前端根據browser 所在的時區進行轉換,而且不論如何轉換,所代表的時間都是同一時間。

    1. 若給的是時區時間,則server 在 轉換前必須得知前端的時區,否則無法轉換成正確的時間字串

      1. e.g 前端是GMT + 8 要的是2017-09-16 12:00:00 轉換成UTC 是 2017-09-16T04:00:00Z ,若此時因server是GMT +7 的時區,然後根據條件查詢到的物件,裡面的日期server 轉換後會是 2017-09-16 11:00:00。 前端拿到就錯亂了。

    2. 所以物件內就放置從DB出來的UTC 時間,前端拿到後會根據當下的時區去轉換為正確的時間

  4. 注意到因為輸入格式不同而導致起始時間也有些微不同(不知是否chrome bug),以下這些也是帶有時區的timestamp 2019-02

Last updated

Was this helpful?