• BOSS 弱點 > 【特定技術】僅能使用原生 JS 開始,不能使用套件

  • 【特定技術】特別注意必須用 JS 處理各國時區

  • 【書寫能力】請寫一篇 BLOG 來介紹你的挑戰過程,並介紹 JavaScript 如何提供 GMT、UTC 時區語法,以及何謂 TimeStamp。

  • UI 設計稿

    UI設計稿


絲路 思路

一直以來都覺得 Date 是很複雜的東西,就懶得研究,實際研究之後的確有比較多的認識,不過我還是會盡量用套件處理時間的(握拳。

接下來就直接說明撰寫時的思路吧。



我的思考步驟

  1. 採取的方式是,HTML 畫面上的地點文字是靜態的,其他的時間全部藉由 JS 動態帶入。
  2. 抓取要帶入時間&日期&地區文字的元素之後,這時的他們是 nodelist,可以使用部分的陣列方法,此時全部取得的 nodelist 裡相同的 index 對應的都是相同的地區。
  3. 由於 nodelist 的 index 是相對應的,就可以按照順序以抓取的地區透過 Date().toLocaleString() 的 timezone 選項逐一帶入 textContent 。
  4. 最後一步是使用 window.setInterval() 每隔一秒取得一次時間(反正也只有顯示分鐘數,就不用太精確吧)

備註:

  • timezone 被我單獨拉出來,因為這樣子方便維護(雖然我不會再打開這個檔案)
  • window.onload 這一步非常重要 (當瀏覽器讀取完成,才去執行抓取時間的函式)


程式碼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
function getTime(){
let location = document.querySelectorAll('.location')
let dateText = document.querySelectorAll('.date')
let timeText = document.querySelectorAll('.time')

let timezone = {
'NEW YORK': 'America/New_York',
'LONDON': 'Europe/London',
'BANGKOK': 'Asia/Bangkok',
'TAIWAN': 'Asia/Taipei',
'SYDNEY': 'Australia/Sydney',
}

location.forEach( (item, index) => {
timeText[index].textContent = currentTime(timezone[item.textContent]).time
dateText[index].textContent =
`${currentTime(timezone[item.textContent]).date} ${currentTime(timezone[item.textContent]).year}`
})
}

function currentTime(timeZone){
let locale = 'en-US'
let options_YYYY = {
timeZone,
year : 'numeric',
}
let options_HHMM = {
timeZone,
hour12 : false,
hour: 'numeric',
minute: '2-digit'
}
let options_MMDD = {
timeZone,
month : 'short',
day : 'numeric',
}
return {
year: new Date().toLocaleString(locale, options_YYYY),
date: new Date().toLocaleString(locale, options_MMDD),
time: new Date().toLocaleString(locale, options_HHMM),
}
}

window.onload = getTime()
window.setInterval('getTime();', 1000)


GMT、UTC

原則上 GMT (Greenwich Mean Time) = UTC (International Atomic Time),實際上不然。

GMT 是根據一天的時間(或是說地球自轉一圈的時間)計算的,但因目前自轉速度是有減速的跡象,所以 GMT 的一秒會越來越久,而 UTC 是根據銫原子固定震盪次數的時間計算,UTC 基本上是更穩定的。
參考來源 : https://pansci.asia/archives/84978



JavaScript 上的 UTC

建立一個 JavaScript Date 物件來指向某一個時間點。Date 物件是基於世界標準時間(UTC) 1970 年 1 月 1 日開始的毫秒數值來儲存時間。
參考來源 : https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Date



JavaScript Date 物件實體

直接使用物件實體的方法來建立 Date 物件,不過字串解析時間時,充滿了各種坑,根據這邊的結論(直接看結論是怎樣?),為了避免被各瀏覽器之間的支援度雷到,使用字串解析時間時要極度小心。

如果你要我給建議,我可以說相容性最高的應該就是 Sat, 24 Sep 2016 20:42:16 GMT 這種日期時間格式,但請注意這種格式的缺點是【如果你沒有加上 GMT 時區,瀏覽器預設就會將這種格式解析為使用者電腦的本地時間】,如果沒注意到時區部分,對於全球性或跨國瀏覽的使用者來說可能會出現錯誤的時間差。否則請一律使用 ISO-8601 標準日期時間格式 ( 2016-09T02:34:33.346Z ),這種格式的優點就是【瀏覽器只會將這種格式解析為 GMT/UTC 標準時區的時間】,這樣反而可以強迫你用具有時區的思維來開發程式,出現時差錯誤的問題也會減少。

直接過去參考一下吧!!! https://blog.miniasp.com/post/2016/09/25/JavaScript-Date-usage-in-details

坑~

Date物件複雜的地方不只是它的進位並非十進位而已,年月日的進位還涉及閏年、星期幾的問題,以及全球各種不同語言、全球時區使用的本地化格式的問題等等各種問題。



timestamp

就是從1970年01月01日0分0秒起到現在的總秒數,注意,是毫秒數,通常取得之後會再乘以1000,反正也不需要這麼精確 ?
就我所知 timestamp 會存起來做為判斷時間先後的依據,後取得的大於先取得的值,例如判斷。

1
2
new Date('1970-01-01').getTime(); // 0
new Date('2020-01-01').getTime(); // 1577836800000


時區

實際使用時,時區是我最搞不懂的,因為 JS 會直接把取得的時間轉換為本地時間,所以不管怎麼處理最後得到的都會是瀏覽器的本地時間 QQ

JS 的 Date().toLocaleString() 有提供 timezone 的 option,但是有一些支援度的問題 (caniuse),IE 還有其他部分瀏覽器不支援。但我就是要用XD

之前有看到一篇文章有寫到,目前有在規劃日期的相關統整之類的,看這邊,但是目前普遍都會建議日期的處理使用工具函示庫比較安全,不然會容易有 bug ,最出名的 Moment.js ,不過現在moment.js 也已經停止更新了(you probably don’t need moment js anymore),

總之先這樣吧XDD ,菜雞不要說太多,會越說越錯。

參考
https://codertw.com/%E7%A8%8B%E5%BC%8F%E8%AA%9E%E8%A8%80/644589/
https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Date
https://blog.miniasp.com/post/2016/09/25/JavaScript-Date-usage-in-details

最後附上連結,如下


本文章若有任何資訊誤植或侵權,煩請告知,我會立刻處理。