Sitemap

[JavaScript] JS 的時間觀

關於 Date 與時間操作

8 min read5 days ago

--

最後更新時間:2026–10–31

Press enter or click to view image in full size
達利是我目前最喜歡的藝術家,雖然這種時鐘後來出現了很多致敬款XD | Photo by Marija Zaric on Unsplash

對「空間」這個領域一直滿感興趣,具體顯現方式就是喜歡看地圖。雖然我不是物理系(甚至以前高中物理超爛),但時間跟空間是緊密關聯的兩個概念,就算不用搬出愛因斯坦,光看時區這件事就知道空間會影響時間,至少對人類認知而言。

最近在看 JavaScript 的 Date() 物件,發現時間是一個坑,好多奇怪的事,順手在這邊分享一下。

JavaScript Date 物件

先看一下 MDN 的一段說明:

JavaScript Date objects represent a single moment in time in a platform-independent format. Date objects encapsulate an integral number that represents milliseconds since the midnight at the beginning of January 1, 1970, UTC (the epoch).

Wait, what???

第一次看會覺得三小,為什麼會有 1970 年之類的年份出現在一個物件的解釋。白話地說,Date 物件代表一個時間點,而 Date 物件把這個時間點封裝起來變成一個方便操作的物件,那這個所謂的「時間點」具體是什麼呢?是一個整數,而這個整數代表了從 1970 年 1 月 1 日子夜 00:00 開始到那個時間點總共過了多少毫秒(1,000 毫秒是 1 秒)

好,此時此刻你一定在想,1970/1/1 那天到底發生什麼事,沒錯,當然發生了一件大事,那就是人類在 1969/12/31 那晚跨年了!!!說不定還放了煙火,可喜可賀可喜可賀。好,先別急著關掉網頁,講個正經的,查了一下發現其實沒什麼特殊原因,如果你有點進去 Date 的 MDN 會發現裡面有提到 epoch、UNIX epoch,JavaScript 只是跟著用 UNIX time 去計算時間,那這個 UNIX time 顧名思義跟 UNIX 作業系統有關,UNIX 從 1969 年開發、1971 與 1973 年分別於貝爾實驗室內外發佈,哎喲,1970 年該不會跟這個有關吧,你真聰明,其實這個時間點的設定沒有什麼天文或物理上的特殊意義,主要是歷史因素,UNIX 在設計時間系統時需要選一個固定的時間點作為 0 秒來計算時間,而他們當時也不是一開始就這樣設定,而是經歷了些波折與考量,最後才選擇這個時間點,主打一個方便,有興趣可以自行考古或去看這篇討論。

講完 1970 這件怪事還有個東西,就是那段 MDN 說明還有寫到一個詞叫 UTC,這個要跟 GMT 一起看:

  • GMT(Greenwich Mean Time,格林威治標準時間):以英國格林威治天文台為基準、屬於天文學上的時間,更常被當作一個時區名稱來用,例如台灣就是 GMT +8
  • UTC(Coordinated Universal Time,世界協調時間):以原子鐘計時,比起時區更像是一個時間標準,但基本上跟 GMT 是差不多的東西,有興趣可以看這篇有趣的文章

所以 MDN 那段就是在說以 UTC 這個時間標準從 1970/1/1 開始計算。看到這邊有沒有發現另一件怪怪的事,為啥 Coordinated Universal Time 的縮寫不是 CUT 啊?結果是因為當時英國人希望用英文當縮寫(CUT)而法國人希望用法文當縮寫(TUC),最後妥協用 UTC……靠,算你們厲害。

看到這邊大概知道 Date 是個什麼東西了,來看些基本語法吧

Date 基本操作

可以知道當下的時間:

const now = new Date()
console.log(now);
// 印出像是這樣的字串:2026-10-30T00:50:16.117Z

印出來的那個字串晚一點再介紹一下,先繼續看其他語法。剛剛有說 Date 就是把某個時間點封裝起來方便操作,既然是這樣,那剛剛 now 這個變數難不成可以接一些操作方法?厲害,簡直軟體天才,就跟你想的一樣。例如可以這樣:

const now = new Date()
console.log(now.getTime());
// 印出像是這樣的數字:1793321823149

哦哦哦,出現了,1793321823149 這個數字就是本篇開頭提到的「從 1970 年 1 月 1 日子夜 00:00 開始到某個時間點總共過了多少毫秒」

Get Johnny Fang’s stories in your inbox

Join Medium for free to get updates from this writer.

不信嗎?來簡單驗算一下年份

  • 1 秒 = 1,000 毫秒
  • 1 分鐘 = 60 秒 = 60,000 毫秒
  • 1 小時 = 3,600,000 毫秒
  • 加速一下,1 年 = 365 天 x 24 小時 x 360 萬毫秒 = 31,536,000,000
  • 把剛剛出現的 1,793,321,823,149 除以前一項,大約是 56.86 年
  • 1970 + 56 = 2026,也就是今年

接著來一口氣看一些操作:

const now = new Date()
console.log(now.getFullYear()); // 2026
console.log(now.getMonth()); // 9
console.log(now.getDate()); // 31
console.log(now.getDay()); // 6
console.log(now.getHours()); // 9
console.log(now.getMinutes()); // 20
console.log(now.getSeconds()); // 13

依序取得該時間點是幾年幾月幾號星期幾、幾點幾分幾秒,也就是 2026 年 10 月 31 號星期六 09:20:13。等等,好像混入了一個怪怪的東西,getMonth() 明明寫 9 我怎麼說是 10 月?對,這是一個很ㄎㄅ的坑,Date() 的月份是從 0 開始算,所以一月是 0,二月是 1,以此類推。

請留意,別把 getDate() 跟 getDay() 搞混,前者是幾號、後者是星期幾,而後者有個小坑,就是星期日是 0 而不是 7,可留意一下。

另外,getHours() 會拿到執行環境的本地時區,如果想拿到 UTC 時間可以用 getUTCHours()

還有其他語法例如取得 UTC 時間等等,有興趣請自行玩一下 MDN。

ISO 8601

上面有提到可以印出像是這樣的字串:「2026-10-30T00:50:16.117Z」,這是基於 ISO 8601 標準的時間格式,ISO 就是國際標準化組織(International Organization for Standardization),顧名思義就是制定各種國際標準的組織。眼尖的你應該也會發現怎麼跟 UTC 一樣,為啥縮寫不是 IOS 而是 ISO,原因邏輯差不多,就是如果用不同國家的語言縮寫都不一樣,後來決定借用希臘字 isos(ίσος,equal 的意思)變成 ISO,嗯,這件事也滿 ISO 的。

回到字串,拆解一下:

  • 2026-10-30:幾年幾月幾號
  • T:Time 的意思,也是一個分隔符,把日期跟時間分開
  • 00:50:16.117:0 點 50 分 16 秒 117 毫秒
  • Z:代表 UTC 時間 +0,所以如果要換成台灣時間要再 +8 小時

至於為什麼是 Z,早期航海、軍事與航空領域會用字母表示不同時區,而本初子午線(也就是 0° 經度所在的時區)被指定為 Z zone。這個時區後來等同於 UTC 的基準時區。

而 Date 有個語法就是 toISOString(),負責將 Date() 所產生的 instance 轉換成該時間點的 ISO 標準格式字串:

const time = new Date("05 October 2011 14:48 UTC");
console.log(time.toISOString());
// 2011-10-05T14:48:00.000Z

雖然直接 console.log(time) 的結果看起來也是 ISO 字串,但那只是 console 幫你把 Date 物件顯示成類似 ISO 字串的樣子,而且那是在 Node.js 環境時,如果用 Chrome DevTools Console 會是 Wed Oct 05 2011 22:48:00 GMT+0800 (台北標準時間)。不信的話可以這樣檢驗:

const time = new Date("05 October 2011 14:48 UTC");
const timeToISOString = time.toISOString()
console.log(typeof time); // object
console.log(typeof timeToISOString); // string

轉成 ISO 字串除了時間格式標準統一外,這也是可以放進 JSON 方便前後端溝通的資料格式。

結尾

老實說這整篇我自己是當作吸收冷知識的角度在研究,因為:

  • 有滿多套件都可以協助處理時間問題
  • 如果是接手舊專案,這些處理時間的基礎設施應該早就建好了
  • 若新建專案確實要注意,知道這些或許有點幫助,但現在應該也都是 AI 做了

總之,如果這些資訊有幫助的話那就太棒了,不管是對技術或增加冷知識而言。對時區有興趣的話也可以去看看經線,會發現許多奇怪的事XD

--

--