
開發契機:正視 Date 物件帶來的混亂
「想把 UTC 轉成 JST」、「看不懂伺服器日誌顯示的到底是哪國的時間」。
只要是工程師,大概都曾有過被「日期與時區」泥淖困住的經驗。特別是 JavaScript 的 Date 物件,其行為模式往往與直覺不符,長期以來一直是開發者的天敵之一。
過去,引入外部函式庫如 Moment.js, date-fns 或 Day.js 進行處理是主流做法。然而,在開發 DevToolKits 的過程中,我給自己加了一個限制。我問自己:「難道只為了一個時間轉換,就得讓使用者下載幾十 KB 的函式庫嗎?」
「利用現代瀏覽器的內建功能,一定能做出最輕量的時區轉換器。」基於這份自我「挑戰書」,時區轉換工具 的開發正式展開。
技術巧思:將標準 API 發揮到極致
我們關注的是瀏覽器內建的 Intl(Internationalization API)。
1. 利用 Intl.DateTimeFormat 進行「精確拆解」
若僅靠標準 API,要將特定時區的日期以 ISO 8601 格式輸出其實意外地麻煩。因此,我們採取了利用 formatToParts 將日期如零件般拆解後,再進行重組的手法。
const formatter = new Intl.DateTimeFormat('en-CA', {
timeZone,
hour12: false,
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
});
// 將年、月、日等零件分別取出
const parts = formatter.formatToParts(date).reduce((acc, cur) => ({
...acc, [cur.type]: cur.value
}), {} as any);
透過這種「拆解後再依需求重組」的方法,在完全不使用肥大函式庫的情況下,也能實現完美的格式化處理。
2. 動態偏移量 (Offset) 提取技巧
時區轉換中最難纏的莫過於像「JST 是 +09:00」這樣的偏移量資訊。如果手動維護對照表,將難以應對日光節約時間 (DST) 等變動。
因此,我們實作了從 timeZoneName: 'shortOffset' 選項中提取瀏覽器持有的最新偏移量資訊,再進行解析與結合的邏輯。
// 取得瀏覽器持有的「當下」時差資訊
const offsetName = new Intl.DateTimeFormat('en-US', {
timeZone,
timeZoneName: 'shortOffset',
}).formatToParts(date).find(p => p.type === 'timeZoneName')?.value;
藉此,我們獲得了自行實作才有的強大優勢:能始終利用作業系統或瀏覽器持有的最新時區數據。
「無所作為」帶來的極致速度
本工具在開啟網頁的瞬間即可使用。
不需要等待肥大的指令碼解析,也沒有對 API 的請求。
透過將瀏覽器原有的能力發揮到極限,我們完成了工程師理想中的終極輕量工具:「不需函式庫」且「零相依性」。
結語
時區轉換工具對我而言,是一個再次確認「瀏覽器標準功能之可能性」的開發案例。
「在疊加函式庫之前,先質疑標準功能。」這份工程師的矜持,成就了本工具如空氣般輕盈的運作感。
讓世界各地的時間就在身邊,而且更加輕快。請務必親自體驗這份速度。