利用原生 JavaScript 計算各時區時間
之前有介紹過 Moment.js,透過它的 moment-timezone 套件,就可以很輕易地用來計算各個時區的時間。不過今天要透過原生的 JavaScript(Vanilla JS)來試著解決這個問題。
之前有介紹過 Moment.js,透過它的 moment-timezone 套件,就可以很輕易地用來計算各個時區的時間。不過今天要透過原生的 JavaScript(Vanilla JS)來試著解決這個問題。
為什麼會有這篇文章呢,其實是在參加六角學院的 JS 地下城挑戰。除了不定時釋出新的題目外,更有特定的 BOSS 弱點要使用特定的技術才能完成。像這一題就要求只能用原生、不能用套件,甚至要寫一篇文章來介紹挑戰過程,所以這裡會先介紹 JS 如何計算各個時區的時間,接著再附上這題的挑戰狀況。
利用 JavaScript 計算各時區時間
其實 JavaScript 的 Date
物件,有個方法叫做 toLocaleString()
,只要搭配適當的參數,就能夠轉成各個時區、各個語言的(每個國家表示時間的方法不同,有人用 YYYY-MM-DD,有人用 DD/MM/YYYY)表示方法。基本用法大概是:
new Date().toLocaleString('language', {...options});
舉個例子,如果我們要以臺灣的表示法表示臺北時區的話,就可以用:
new Date().toLocaleString('zh-TW', {timeZone: 'Asia/Taipei'});
輸出大概會是:
2019/2/2 上午2:56:27
舉一反三,如果要以美國的表示法表示紐約時區,就可以:
new Date().toLocaleString('en-US', {timeZone: 'America/New_York'});
輸出就會是:
2/1/2019, 1:57:17 PM
而 options
裡面還有很多參數可以用,例如如果要 24 小時制的話,可以加上 hour12: false
的選項,詳細可以參考 MDN 的介紹。
UTC?GMT?差在哪裡?
雖然到這裡這題就大致做完了,不過還是順便說一下這兩個東西。還記得小時候地理課本都講我們的時區是 GMT+8,長大以後不知道為什麼大家都講 UTC+8。
關於 UTC 和 GMT 的問題,可以參考泛科學的這篇文章:到底是 GMT+8 還是 UTC+8 ?,是個不錯的科普小知識。不過,在寫 JavaScript 的時候,通常看到 UTC
指的就是國際標準時間。舉個例子:
const now = new Date();
now.getHours(); // 取得本地的小時(0~23)
now.getUTCHours(); // 取得國際標準時間的小時(0~23)
比較特別的大概只有 getTime()
,會取得由 1970-01-01 00:00:00 UTC 開始,到現在經過的毫秒數。並沒有 getUTCTime()
這種東西。
1970-01-01 是什麼日子?
這其實是 Timestamp(又稱 UNIX Timestamp、POSIX Timestamp)定義的。在有些地方不能用字串來存時間,只會存數字,所以當年工程師們就定義了 1970 年的元旦當作起始點,並用之後經過的秒數來當作 Timestamp,例如我寫這篇文章的時間(2019-02-02 03:16)的 Timestamp 就可以表示為 1549048560
。
順帶一提,Timestamp 不會把潤秒算進去 XD
所以第四題怎麼做
這題應該要做到這樣:點此看線上設計稿
大概講一下,基本上解出各國的時區,表示成 24 小時制,就差不多了,剩下就是字串處理了。例如我們已經算出 2019/2/1 03:16:00
的話,只要透過 split()
拿到後半部的時間、再用 slice()
或 substring()
保留時和分的部分,就可以算出右邊的時鐘了。左邊的部分,基本上也是 split()
兩次,把年、月、日分開來重組,就能算出左邊的日期了。
別忘記用一個 setInterval
,確保你的時鐘會跟著走。附上這題的 程式碼、Demo。
延伸閱讀
最後再介紹一個東西。雖然 Moment.js 帶了一個 format()
方法,讓我們不管是 'YYYY-MM-DD'、還是 'DD/MM/YYYY' 都可以很輕鬆的輸出,但你知道其實這表示法有國際標準嗎?看看什麼是 ISO 8601 吧。
如果你也想挑戰的話,歡迎看看六角學院的 說明影片。