概述
世界時鐘是一個功能強大的線上工具,專為需要跨時區協作的專業人士、國際旅行者和遠程工作者設計,能夠即時顯示全球主要城市的當地時間。 本工具採用純前端架構,完全在瀏覽器端運行,零網路傳輸,確保數據的絕對隱私和安全性。 提供智能搜尋、實時更新、時間格式切換、本地儲存等專業功能。
🔒 隱私保護承諾
🔒 Privacy Protection Promise
所有時間處理都在您的瀏覽器本地進行,數據不會上傳到任何伺服器,確保您的時區偏好和使用習慣完全安全。
技術架構與核心設計
整體架構設計
Overall Architecture Design
技術層級 | 實作方式 | 設計考量 |
---|---|---|
前端架構 | ES6+ JavaScript + 純DOM操作 | 即時更新、響應式界面、模組化設計 |
時區系統 | Intl.DateTimeFormat API + IANA時區 | 高精度時間轉換、夏令時自動處理 |
資料儲存 | localStorage + JSON序列化 | 用戶偏好持久化、快速載入 |
搜尋引擎 | 實時過濾 + 模糊匹配 | 快速城市查找、智能建議 |
語言系統 | Tool Master 全域語言整合 | 即時雙語切換、本地化格式 |
關鍵功能特性
全球城市支援
Global City Support
涵蓋44個主要城市,包含亞洲、歐洲、美洲、大洋洲和非洲五大洲的重要時區
智能搜尋系統
Intelligent Search System
支援城市名稱即時搜尋,自動篩選下拉選項,Enter鍵快速新增
雙時間格式
Dual Time Format
支援12小時制和24小時制切換,滿足不同用戶的使用習慣
實時自動更新
Real-time Auto Update
每秒自動更新所有時鐘,確保時間顯示的準確性和同步性
響應式設計
Responsive Design
完美適配桌面、平板和手機設備,提供一致的用戶體驗
狀態持久化
State Persistence
自動保存用戶選擇的城市和時間格式偏好到本地儲存
完整程式碼實作
以下是世界時鐘的完整程式碼實作,按功能模組分類展示。點擊卡片標題可展開查看詳細程式碼:
📦 核心世界時鐘類別與城市資料庫
功能:定義全域變數、城市資料庫和主要的狀態管理變數
/**
* World Clock - Core Implementation
* 世界時鐘 - 核心實作
*
* Professional world clock tool with global timezone support
* 專業的全球時區支援世界時鐘工具
*/
// 城市資料庫 / City Database
// 包含44個全球主要城市的時區資訊和多語言名稱
const cities = {
// 亞洲 / Asia
'Asia/Taipei': { zh: '台北', en: 'Taipei', country: { zh: '台灣', en: 'Taiwan' } },
'Asia/Tokyo': { zh: '東京', en: 'Tokyo', country: { zh: '日本', en: 'Japan' } },
'Asia/Seoul': { zh: '首爾', en: 'Seoul', country: { zh: '韓國', en: 'South Korea' } },
'Asia/Hong_Kong': { zh: '香港', en: 'Hong Kong', country: { zh: '香港', en: 'Hong Kong' } },
'Asia/Singapore': { zh: '新加坡', en: 'Singapore', country: { zh: '新加坡', en: 'Singapore' } },
'Asia/Shanghai': { zh: '上海', en: 'Shanghai', country: { zh: '中國', en: 'China' } },
'Asia/Bangkok': { zh: '曼谷', en: 'Bangkok', country: { zh: '泰國', en: 'Thailand' } },
'Asia/Jakarta': { zh: '雅加達', en: 'Jakarta', country: { zh: '印尼', en: 'Indonesia' } },
'Asia/Manila': { zh: '馬尼拉', en: 'Manila', country: { zh: '菲律賓', en: 'Philippines' } },
'Asia/Dubai': { zh: '杜拜', en: 'Dubai', country: { zh: '阿聯', en: 'UAE' } },
// 歐洲 / Europe
'Europe/London': { zh: '倫敦', en: 'London', country: { zh: '英國', en: 'UK' } },
'Europe/Paris': { zh: '巴黎', en: 'Paris', country: { zh: '法國', en: 'France' } },
'Europe/Berlin': { zh: '柏林', en: 'Berlin', country: { zh: '德國', en: 'Germany' } },
'Europe/Rome': { zh: '羅馬', en: 'Rome', country: { zh: '義大利', en: 'Italy' } },
'Europe/Madrid': { zh: '馬德里', en: 'Madrid', country: { zh: '西班牙', en: 'Spain' } },
'Europe/Amsterdam': { zh: '阿姆斯特丹', en: 'Amsterdam', country: { zh: '荷蘭', en: 'Netherlands' } },
'Europe/Zurich': { zh: '蘇黎世', en: 'Zurich', country: { zh: '瑞士', en: 'Switzerland' } },
'Europe/Moscow': { zh: '莫斯科', en: 'Moscow', country: { zh: '俄國', en: 'Russia' } },
// 美洲 / Americas
'America/New_York': { zh: '紐約', en: 'New York', country: { zh: '美國', en: 'USA' } },
'America/Los_Angeles': { zh: '洛杉磯', en: 'Los Angeles', country: { zh: '美國', en: 'USA' } },
'America/Chicago': { zh: '芝加哥', en: 'Chicago', country: { zh: '美國', en: 'USA' } },
'America/Toronto': { zh: '多倫多', en: 'Toronto', country: { zh: '加拿大', en: 'Canada' } },
'America/Vancouver': { zh: '溫哥華', en: 'Vancouver', country: { zh: '加拿大', en: 'Canada' } },
'America/Mexico_City': { zh: '墨西哥城', en: 'Mexico City', country: { zh: '墨西哥', en: 'Mexico' } },
'America/Sao_Paulo': { zh: '聖保羅', en: 'São Paulo', country: { zh: '巴西', en: 'Brazil' } },
'America/Buenos_Aires': { zh: '布宜諾斯艾利斯', en: 'Buenos Aires', country: { zh: '阿根廷', en: 'Argentina' } },
// 大洋洲 / Oceania
'Australia/Sydney': { zh: '雪梨', en: 'Sydney', country: { zh: '澳洲', en: 'Australia' } },
'Australia/Melbourne': { zh: '墨爾本', en: 'Melbourne', country: { zh: '澳洲', en: 'Australia' } },
'Pacific/Auckland': { zh: '奧克蘭', en: 'Auckland', country: { zh: '紐西蘭', en: 'New Zealand' } },
// 非洲 / Africa
'Africa/Cairo': { zh: '開羅', en: 'Cairo', country: { zh: '埃及', en: 'Egypt' } },
'Africa/Johannesburg': { zh: '約翰尼斯堡', en: 'Johannesburg', country: { zh: '南非', en: 'South Africa' } },
};
// 全域狀態變數 / Global State Variables
let selectedCities = []; // 用戶選擇的城市列表
let is24HourFormat = false; // 時間格式偏好 (false: 12小時制, true: 24小時制)
let currentLanguage = 'zh'; // 當前語言設定
let updateInterval; // 時間更新定時器
// DOM 元素引用 / DOM Element References
const citySearch = document.getElementById('citySearch');
const citySelect = document.getElementById('citySelect');
const addCityBtn = document.getElementById('addCityBtn');
const timeFormatToggle = document.getElementById('timeFormatToggle');
const clocksContainer = document.getElementById('clocksContainer');
🌐 全域語言系統整合
功能:整合 Tool Master 全域語言切換系統,支援即時雙語切換
/**
* 設置全域語言監聽器
* Setup global language listener
*
* 這是工具與 Tool Master 語言系統整合的關鍵方法
* This is the key method for tool integration with Tool Master language system
*/
function setupGlobalLanguageListener() {
// 監聽全域語言切換事件 / Listen to global language change events
window.addEventListener('languageChanged', (event) => {
currentLanguage = event.detail.language;
console.log('🌐 語言切換至:', currentLanguage);
updateLanguage();
});
// 處理全域語言系統加載時序問題
// Handle timing issues with global language system loading
const checkGlobalLanguage = () => {
if (window.globalI18n) {
currentLanguage = window.globalI18n.currentLanguage;
updateLanguage();
return true;
}
return false;
};
// 立即檢查,如果沒有就延遲重試
// Immediate check, retry with delay if not available
if (!checkGlobalLanguage()) {
setTimeout(() => {
checkGlobalLanguage();
}, 100);
}
}
/**
* 更新語言顯示
* Update language display
*
* 根據當前語言設定更新所有界面元素
* Update all interface elements based on current language setting
*/
function updateLanguage() {
// 更新所有有語言屬性的元素 / Update all elements with language attributes
document.querySelectorAll('[data-zh][data-en]').forEach(element => {
const text = currentLanguage === 'zh' ? element.getAttribute('data-zh') : element.getAttribute('data-en');
if (element.tagName === 'INPUT' && element.type === 'text') {
element.placeholder = text;
} else {
element.textContent = text;
}
});
// 更新城市選擇器 / Update city selector
populateCitySelect();
// 更新時鐘顯示 / Update clock display
updateClocksDisplay();
}
🔍 城市搜尋與選擇系統
功能:處理城市搜尋、下拉選擇、自動篩選和城市新增功能
/**
* 填充城市選擇下拉選單
* Populate city selection dropdown
*
* 根據當前語言動態生成城市選項,並按字母順序排序
* Dynamically generate city options based on current language and sort alphabetically
*/
function populateCitySelect() {
// 按當前語言排序城市 / Sort cities by current language
const sortedCities = Object.entries(cities).sort((a, b) => {
const nameA = currentLanguage === 'en' ? a[1].en : a[1].zh;
const nameB = currentLanguage === 'en' ? b[1].en : b[1].zh;
return nameA.localeCompare(nameB);
});
// 創建預設選項 / Create default option
const defaultOption = document.createElement('option');
defaultOption.value = '';
defaultOption.textContent = currentLanguage === 'en' ? 'Select city' : '選擇城市';
citySelect.innerHTML = '';
citySelect.appendChild(defaultOption);
// 添加所有城市選項 / Add all city options
sortedCities.forEach(([timezone, data]) => {
const option = document.createElement('option');
option.value = timezone;
const cityName = currentLanguage === 'en' ? data.en : data.zh;
const countryName = currentLanguage === 'en' ? data.country.en : data.country.zh;
option.textContent = `${cityName} (${countryName})`;
citySelect.appendChild(option);
});
}
/**
* 城市搜尋處理
* Handle city search
*
* 實時過濾城市選項,支援模糊匹配和自動選擇
* Real-time filtering of city options with fuzzy matching and auto-selection
*/
function handleCitySearch() {
const searchTerm = citySearch.value.toLowerCase();
const options = citySelect.querySelectorAll('option');
// 顯示/隱藏匹配的選項 / Show/hide matching options
options.forEach(option => {
if (option.value === '') return; // 跳過預設選項
const text = option.textContent.toLowerCase();
option.style.display = text.includes(searchTerm) ? '' : 'none';
});
// 自動選擇第一個匹配的選項 / Auto-select first matching option
const visibleOptions = Array.from(options).filter(option =>
option.value !== '' && option.style.display !== 'none'
);
if (visibleOptions.length > 0) {
citySelect.value = visibleOptions[0].value;
}
}
/**
* 新增選擇的城市
* Add selected city
*
* 驗證並新增城市到用戶列表,防止重複新增
* Validate and add city to user list, prevent duplicate additions
*/
function addSelectedCity() {
const selectedTimezone = citySelect.value;
if (!selectedTimezone) return;
// 檢查是否已經存在 / Check if already exists
if (selectedCities.includes(selectedTimezone)) {
alert(currentLanguage === 'en' ? 'City already added!' : '城市已經新增過了!');
return;
}
// 新增城市並更新顯示 / Add city and update display
selectedCities.push(selectedTimezone);
citySearch.value = '';
citySelect.value = '';
updateClocksDisplay();
saveToLocalStorage();
console.log('✅ 新增城市:', cities[selectedTimezone][currentLanguage]);
}
⏰ 實時時間更新引擎
功能:核心時間計算邏輯,包括時區轉換、時差計算和格式化顯示
/**
* 更新所有時鐘顯示
* Update all clocks display
*
* 遍歷所有已新增的城市,更新其時間顯示
* Iterate through all added cities and update their time display
*/
function updateAllClocks() {
const now = new Date();
const userTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
selectedCities.forEach(timezone => {
updateSingleClock(timezone, now, userTimezone);
});
}
/**
* 更新單個時鐘
* Update single clock
*
* 處理單一城市的時間計算、格式化和時差顯示
* Handle time calculation, formatting, and time difference display for a single city
*/
function updateSingleClock(timezone, now, userTimezone) {
const card = document.querySelector(`[data-timezone="${timezone}"]`);
if (!card) return;
try {
// 計算當地時間 / Calculate local time
// 使用 Intl API 進行精確的時區轉換
const localTime = new Date(now.toLocaleString("en-US", {timeZone: timezone}));
// 時間格式化選項 / Time formatting options
const timeOptions = {
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: !is24HourFormat // 根據用戶偏好選擇12/24小時制
};
// 格式化時間字串 / Format time string
const timeString = localTime.toLocaleTimeString(
currentLanguage === 'en' ? 'en-US' : 'zh-TW',
timeOptions
);
// 日期格式化選項 / Date formatting options
const dateOptions = {
weekday: 'long', // 星期幾
year: 'numeric', // 年份
month: 'long', // 月份
day: 'numeric' // 日期
};
// 格式化日期字串 / Format date string
const dateString = localTime.toLocaleDateString(
currentLanguage === 'en' ? 'en-US' : 'zh-TW',
dateOptions
);
// 計算時差 / Calculate time difference
const userTime = new Date(now.toLocaleString("en-US", {timeZone: userTimezone}));
const timeDiff = Math.round((localTime.getTime() - userTime.getTime()) / (1000 * 60 * 60));
// 生成時差文字 / Generate time difference text
let timeDiffText = '';
if (timeDiff === 0) {
timeDiffText = currentLanguage === 'en' ? 'Same as your time' : '與你的時間相同';
} else if (timeDiff > 0) {
timeDiffText = currentLanguage === 'en' ? `${timeDiff} hours ahead` : `比你快 ${timeDiff} 小時`;
} else {
timeDiffText = currentLanguage === 'en' ? `${Math.abs(timeDiff)} hours behind` : `比你慢 ${Math.abs(timeDiff)} 小時`;
}
// 更新 DOM 顯示 / Update DOM display
card.querySelector('.current-time').textContent = timeString;
card.querySelector('.current-date').textContent = dateString;
card.querySelector('.time-diff').textContent = timeDiffText;
} catch (error) {
console.error('❌ 時鐘更新錯誤:', timezone, error);
}
}
/**
* 開始自動更新
* Start auto-update
*
* 啟動定時器,每秒更新一次所有時鐘
* Start timer to update all clocks every second
*/
function startAutoUpdate() {
if (updateInterval) {
clearInterval(updateInterval);
}
updateInterval = setInterval(updateAllClocks, 1000);
console.log('🔄 自動更新已啟動');
}
🎨 時鐘卡片界面系統
功能:處理時鐘卡片的創建、顯示更新和移除操作
/**
* 更新時鐘顯示區域
* Update clocks display area
*
* 根據選擇的城市列表動態生成時鐘卡片
* Dynamically generate clock cards based on selected cities list
*/
function updateClocksDisplay() {
if (selectedCities.length === 0) {
// 顯示空狀態 / Show empty state
clocksContainer.innerHTML = `
${currentLanguage === 'en' ? 'No cities added' : '還沒有城市'}
${currentLanguage === 'en' ? 'Search and add cities to see their local time' : '搜尋並新增城市來查看當地時間'}
`;
return;
}
// 清空容器並重新生成卡片 / Clear container and regenerate cards
clocksContainer.innerHTML = '';
selectedCities.forEach(timezone => {
const clockCard = createClockCard(timezone);
clocksContainer.appendChild(clockCard);
});
}
/**
* 創建時鐘卡片
* Create clock card
*
* 為指定時區創建完整的時鐘卡片元素
* Create complete clock card element for specified timezone
*/
function createClockCard(timezone) {
const city = cities[timezone];
const card = document.createElement('div');
card.className = 'clock-card';
card.dataset.timezone = timezone;
// 根據當前語言獲取城市和國家名稱 / Get city and country names based on current language
const cityName = currentLanguage === 'en' ? city.en : city.zh;
const countryName = currentLanguage === 'en' ? city.country.en : city.country.zh;
// 生成卡片 HTML 結構 / Generate card HTML structure
card.innerHTML = `
${cityName}
--:--
-
-
`;
return card;
}
/**
* 移除城市
* Remove city
*
* 從選擇列表中移除指定城市並更新顯示
* Remove specified city from selection list and update display
*/
function removeCity(timezone) {
selectedCities = selectedCities.filter(city => city !== timezone);
updateClocksDisplay();
saveToLocalStorage();
const cityName = cities[timezone][currentLanguage];
console.log('🗑️ 移除城市:', cityName);
}
/**
* 切換時間格式
* Toggle time format
*
* 在12小時制和24小時制之間切換
* Toggle between 12-hour and 24-hour format
*/
function toggleTimeFormat() {
is24HourFormat = timeFormatToggle.checked;
updateAllClocks();
saveToLocalStorage();
console.log('🕐 時間格式切換至:', is24HourFormat ? '24小時制' : '12小時制');
}
💾 本地儲存管理系統
功能:處理用戶偏好的持久化儲存和載入
/**
* 儲存到本地存儲
* Save to local storage
*
* 將用戶的城市選擇和時間格式偏好保存到 localStorage
* Save user's city selections and time format preferences to localStorage
*/
function saveToLocalStorage() {
const data = {
selectedCities: selectedCities, // 選擇的城市列表
is24HourFormat: is24HourFormat // 時間格式偏好
};
try {
localStorage.setItem('worldClockData', JSON.stringify(data));
console.log('💾 資料已儲存:', data);
} catch (error) {
console.error('❌ 儲存失敗:', error);
}
}
/**
* 從本地存儲載入
* Load from local storage
*
* 從 localStorage 載入用戶之前的偏好設定
* Load user's previous preference settings from localStorage
*/
function loadFromLocalStorage() {
try {
const data = localStorage.getItem('worldClockData');
if (data) {
const parsed = JSON.parse(data);
// 恢復城市選擇 / Restore city selections
selectedCities = parsed.selectedCities || [];
// 恢復時間格式偏好 / Restore time format preference
is24HourFormat = parsed.is24HourFormat || false;
// 更新 UI 控制項 / Update UI controls
timeFormatToggle.checked = is24HourFormat;
console.log('📂 資料已載入:', parsed);
}
} catch (error) {
console.error('❌ 載入失敗:', error);
// 使用預設值 / Use default values
selectedCities = [];
is24HourFormat = false;
}
}
/**
* 清理資源
* Cleanup resources
*
* 在頁面關閉前清理定時器等資源
* Cleanup timers and other resources before page closes
*/
function cleanup() {
if (updateInterval) {
clearInterval(updateInterval);
console.log('🧹 定時器已清理');
}
}
🚀 工具初始化與事件設定
功能:工具的初始化邏輯、事件監聽器設定和全域方法暴露
/**
* 設置事件監聽器
* Setup event listeners
*
* 為所有 UI 控制項設置必要的事件監聽器
* Setup necessary event listeners for all UI controls
*/
function setupEventListeners() {
// 城市搜尋輸入 / City search input
citySearch.addEventListener('input', handleCitySearch);
// 新增城市按鈕 / Add city button
addCityBtn.addEventListener('click', addSelectedCity);
// 時間格式切換 / Time format toggle
timeFormatToggle.addEventListener('change', toggleTimeFormat);
// Enter 鍵快速新增城市 / Enter key for quick city addition
citySearch.addEventListener('keypress', (e) => {
if (e.key === 'Enter') {
addSelectedCity();
}
});
console.log('🎧 事件監聽器已設置');
}
/**
* 初始化函數
* Initialization function
*
* 工具的主要初始化流程,按正確順序執行所有設置
* Main initialization process, execute all setups in correct order
*/
function init() {
console.log('🚀 世界時鐘初始化開始');
// ⚠️ 重要:語言監聽器必須在其他初始化之前設置
// Important: Language listener must be set up before other initializations
setupGlobalLanguageListener();
// 填充城市選擇器 / Populate city selector
populateCitySelect();
// 設置事件監聽器 / Setup event listeners
setupEventListeners();
// 載入用戶偏好 / Load user preferences
loadFromLocalStorage();
// 更新顯示 / Update display
updateClocksDisplay();
updateAllClocks();
// 啟動自動更新 / Start auto-update
startAutoUpdate();
console.log('✅ 世界時鐘初始化完成');
}
// 公開方法給全域使用 / Expose methods for global use
window.worldClock = {
removeCity: removeCity
};
// 頁面離開時清理資源 / Cleanup resources when page unloads
window.addEventListener('beforeunload', cleanup);
// 啟動工具 / Launch tool
init();
// 全域方法暴露給主視窗使用
window.worldClock = {
removeCity: removeCity
};
// 頁面離開時清理資源
window.addEventListener('beforeunload', cleanup);
// 啟動工具
init();
效能優化技術
⚡ 智能更新策略
⚡ Smart Update Strategy
僅更新實際存在的時鐘卡片,避免不必要的 DOM 操作
🎯 事件委派
🎯 Event Delegation
使用全域事件處理器減少記憶體使用和提升性能
📦 資源管理
📦 Resource Management
頁面離開時自動清理定時器,防止記憶體洩漏
瀏覽器兼容性
瀏覽器 | 最低版本 | 支援程度 |
---|---|---|
Chrome | 24+ | ✅ 完整支援 |
Firefox | 29+ | ✅ 完整支援 |
Safari | 10+ | ✅ 完整支援 |
Edge | 79+ | ✅ 完整支援 |
總結
世界時鐘工具展示了現代 Web 技術在時間處理和國際化方面的強大能力。 通過巧妙運用 Intl API、本地儲存和事件系統,我們創建了一個功能完整、性能優秀的時區管理工具。 該實作方案不僅確保了跨平台兼容性,也為用戶提供了直觀友好的操作體驗。