Javascript時間構造的詭異

JavaScript爲咱們提供了不是很好用的Date做爲時間日期對象,除了接口設計怪異以外,還有一些隱藏很深的bug,先看接口設計:chrome

  • Date()直接返回當前時間字符串,無參數。
  • new Date()則是會根據參數來返回對應的時間對象,參數頗有意思:
// 無參數,並返回當前時間。
new Date();
// 可接受一個數字參數,該參數表示與1970年1月1日0點之間的毫秒數。
new Date(value);
// 可接受一個字符串參數,參數形式相似於Date.parse()方法。
new Date(dateString);
// 可接受年月日時分秒參數,是本地時間。
new Date(year, month[, day[, hour[, minutes[, seconds[, milliseconds]]]]]);

先且不說這樣的接口未免不夠靈活(很難處理各類字符串格式的時間),最詭異的一點是其中使用dateString的那個構造方法,MDN網站在這個函數下有下面一段註釋:併發

clipboard.png

注意這裏用的是strongly discouraged - 強烈不推薦使用,原先的我沒有重視這句話,直到。。。付出慘痛的代價。函數

現象

個人一款每日打卡類的App,由於有大量的時間運算,爲了能接受各類時間,我作了一個方便的函數:網站

date2ymd(input) {
    let day = (input instanceof Date) ? input : new Date(input)
    return `${day.getFullYear()}-${day.getMonth() + 1}-${day.getDate()}`
}

上面的函數在某些input時沒有問題,但當參數爲相似’2018-10-1’這種格式,按照MDN的文檔,就屬於強烈不推薦使用的形式,但我沒有留意,App發佈以後,不錯,大部分用戶沒有反饋問題,直到某天,一個阿根廷的用戶給我郵件反饋,說界面上的日曆彷佛錯亂了,我試着更改本身的時區到對應的-3時區,截圖一看:spa

clipboard.png

上圖中彩色小方塊的區域是年視圖,原本應該和下面的日曆一一對應,但在這個時區下,年視圖徹底錯位了,確定是哪裏計算錯誤了,通過調試,我找到了上面這個函數,並發現了問題,咱們用chrome的console演示一下:firefox

clipboard.png

看到了嗎? 從9號到10號,轉換出的時間沒有翻天,固然,咱們能夠爲這種轉換找到理由,JS應該是把這種參數當成UTC時間了,咱們看看firefox:設計

clipboard.png

Firefox的表現能夠理解,由於UTC和-3:00時區之間有個時間差,雖然這依然不是我想要的,但比起chrome的跳變要好接受一些,咱們把輸入時間換一個格式,再看下在chrome下的例子:調試

clipboard.png

這種格式終於符合了正常邏輯,也就是短槓和斜槓分隔的時間處理上是不一致的,斜槓分隔的時間終於正確的按照了本地時間進行處理。code

結論

正如MDN所說,不要使用單字符串參數的Date構造函數,即便你知道各類格式之間的區別,也不建議使用,畢竟記憶這些微妙,甚至不兼容的差異毫無心義。對象

相關文章
相關標籤/搜索