在 Linux 系統管理中,時間設定看似簡單,卻經常是系統日誌對不上、排程工作(cron)跑錯時間、SSL 憑證驗證失敗、叢集節點時間不同步等問題的根源。本篇文章完整說明 Linux date 時間系統的架構,並示範如何用 timedatectl 校正時區、啟用 NTP 自動校時,以及用 hwclock 把時間正確寫入硬體時鐘(RTC),避免重開機後時間又跑掉。
一、觀念釐清:系統時鐘 vs 硬體時鐘
在動手之前,必須先了解 Linux 有「兩個時鐘」:
| 名稱 | 說明 |
|---|---|
| 系統時鐘 (System Clock) |
由 Linux 核心維護,開機後才存在,系統關機後就消失,重開機時需要重新設定 |
| 硬體時鐘 (Hardware Clock / RTC) |
主機板上由電池供電的時鐘晶片,即使電腦關機、斷電也會持續走動,開機時系統會讀取 RTC 來設定系統時鐘 |
兩者預設會互相同步,但也可能因為電池沒電、時區設定錯誤、雙系統(Windows/Linux)搭配等原因產生落差,這也是本文要特別說明「寫入硬體時鐘」的原因。
現代主流發行版(CentOS 7+、Ubuntu 16.04+、Debian 9+ 等)都使用 systemd 的 timedatectl 工具來統一管理時間,取代了舊有的 date、hwclock、ntpdate 各自為政的方式。以下教學以 systemd 為主,並補充傳統指令供對照。
二、查看目前時間狀態
timedatectl
# 或簡寫
timedatectl status
輸出範例:
Local time: Tue 2026-08-18 14:32:10 CST
Universal time: Tue 2026-08-18 06:32:10 UTC
RTC time: Tue 2026-08-18 06:32:09
Time zone: Asia/Taipei (CST, +0800)
System clock synchronized: yes
NTP service: active
RTC in local TZ: no
重點欄位說明:
- Local time:本地時間(依時區顯示)
- Universal time:UTC 標準時間
- RTC time:硬體時鐘目前的時間
- Time zone:目前設定的時區
- System clock synchronized:系統時間是否已與 NTP 校時伺服器同步
- RTC in local TZ:硬體時鐘是否採用「本地時間」而非 UTC(強烈建議設為 no,理由後述)
三、設定時區(Time Zone)
3.1 查詢可用時區清單
timedatectl list-timezones
只想找台灣/亞洲相關:
timedatectl list-timezones | grep -i taipei
timedatectl list-timezones | grep -i asia
3.2 設定時區
台灣請使用 Asia/Taipei:
sudo timedatectl set-timezone Asia/Taipei
設定完成後,用 timedatectl 或 date 確認:
date
timedatectl
3.3 傳統方式(舊版系統 / 無 systemd 環境)
# 建立 /etc/localtime 軟連結指向對應時區檔
sudo ln -sf /usr/share/zoneinfo/Asia/Taipei /etc/localtime
# Debian/Ubuntu 系可搭配 dpkg-reconfigure 互動式設定
sudo dpkg-reconfigure tzdata
也可以檢查 /etc/timezone(Debian 系)是否已正確寫入:
cat /etc/timezone
四、手動設定日期與時間
若沒有網路、或需要手動校正,可以用 timedatectl set-time:
# 格式:YYYY-MM-DD HH:MM:SS
sudo timedatectl set-time "2026-08-18 14:35:00"
⚠️ 注意:若已啟用 NTP 自動校時(見下一節),set-time 會失敗,需要先關閉 NTP 同步:
sudo timedatectl set-ntp false
sudo timedatectl set-time "2026-08-18 14:35:00"
也可以只改日期或只改時間:
sudo date -s "2026-08-18" # 只改日期
sudo date -s "14:35:00" # 只改時間
sudo date -s "2026-08-18 14:35:00" # 日期+時間一起改
五、啟用 NTP 自動校時(強烈建議)
手動對時容易產生誤差,正式環境建議一律啟用 NTP(Network Time Protocol)自動校時。
5.1 使用 systemd-timesyncd(輕量、預設內建)
# 啟用自動校時
sudo timedatectl set-ntp true
# 確認狀態
timedatectl timesync-status
設定校時伺服器(視需要調整,台灣可用 NTP Pool 或國家實驗研究院時間伺服器):
sudo nano /etc/systemd/timesyncd.conf
範例內容:
[Time]
NTP=tock.stdtime.gov.tw time.stdtime.gov.tw
FallbackNTP=0.tw.pool.ntp.org 1.tw.pool.ntp.org
修改後重啟服務:
sudo systemctl restart systemd-timesyncd
sudo systemctl status systemd-timesyncd
5.2 使用 chrony(伺服器環境更常用、精度較高)
許多發行版(RHEL/CentOS/Rocky Linux 預設)使用 chrony 取代 timesyncd。
安裝:
# RHEL / CentOS / Rocky
sudo dnf install chrony -y
# Debian / Ubuntu
sudo apt install chrony -y
設定校時來源:
sudo nano /etc/chrony.conf
加入或修改:
server tock.stdtime.gov.tw iburst
server time.stdtime.gov.tw iburst
啟動並設為開機自動啟動:
sudo systemctl enable --now chronyd
檢查同步狀態:
chronyc tracking
chronyc sources -v
chronyc sources 輸出中,^* 開頭代表目前實際使用的校時來源,^+ 是候選來源。
六、將時間寫入硬體時鐘(RTC)
這是很多教學會漏掉、但實務上很重要的一步:確保系統時間校正後,也同步寫回硬體時鐘,避免重開機後又跑掉。
6.1 查看硬體時鐘目前時間
sudo hwclock --show
# 或
sudo hwclock -r
6.2 將「系統時間」寫入硬體時鐘
當你確認系統時間(date 顯示的時間)已經正確後,執行:
sudo hwclock --systohc
# 等同於
sudo hwclock -w
這個指令會把當前系統時鐘的時間,寫入主機板的 RTC 晶片。
6.3 反向操作:將硬體時鐘時間讀回系統
若信任硬體時鐘、想拿它來設定系統時間(開機時系統其實預設就會做這件事):
sudo hwclock --hctosys
# 等同於
sudo hwclock -s
6.4 使用 timedatectl 一步到位
其實在啟用 NTP 同步後,systemd 會自動定期將校正好的系統時間寫入 RTC,不需要手動執行 hwclock --systohc。但若你是手動對時、或關閉了 NTP,就務必手動執行一次 hwclock --systohc,否則重開機後時間又會跑掉。
七、RTC 是否使用 UTC 或本地時間
這是最容易被忽略、卻常常造成「Windows/Linux 雙系統時間差 8 小時」問題的關鍵設定。
- Linux 慣例:硬體時鐘建議儲存 UTC 時間,開機時再依系統時區換算成本地時間顯示。
- Windows 慣例:預設硬體時鐘儲存的是本地時間。
若你的機器是 Windows / Linux 雙系統,兩邊對 RTC 的認知不同,就會出現時間對不上(通常差時區的時數,例如台灣會差 8 小時)的狀況。
7.1 確認目前設定
timedatectl
看 RTC in local TZ 這一行:
no:RTC 使用 UTC(Linux 慣例,建議保持)yes:RTC 使用本地時間(通常是為了與 Windows 相容)
7.2 若需要讓 RTC 改用本地時間(雙系統相容用)
sudo timedatectl set-local-rtc 1
若要改回標準的 UTC 模式:
sudo timedatectl set-local-rtc 0
💡 建議:純 Linux 伺服器環境一律保持 UTC(
set-local-rtc 0,也就是預設值);只有在雙系統桌機、且不想改 Windows 登錄檔設定時,才考慮切成本地時間模式。
(補充:若想讓 Windows 也改用 UTC 儲存 RTC,可在 Windows 端修改機碼,讓雙方都用 UTC,這是更推薦的做法,但需要系統管理權限修改登錄檔,此處不展開。)
八、完整設定流程總結(Cheat Sheet)
以下整理一套「從零開始設定一台新主機時間」的標準流程:
# 1. 確認目前狀態
timedatectl
# 2. 設定時區為台灣
sudo timedatectl set-timezone Asia/Taipei
# 3. 啟用 NTP 自動校時
sudo timedatectl set-ntp true
# 4.(可選,若用 chrony)確認同步狀態
chronyc tracking
chronyc sources -v
# 5. 確認系統時間已同步
timedatectl status | grep "synchronized"
# 6. 確保硬體時鐘也已寫入正確時間
sudo hwclock --systohc
# 7. 確認 RTC 使用 UTC(伺服器建議值)
sudo timedatectl set-local-rtc 0
# 8. 最終確認
timedatectl
sudo hwclock --show
九、常見問題 FAQ
通常是系統時間校正後沒有寫回硬體時鐘(RTC)。手動改完時間務必執行 sudo hwclock --systohc,把系統時間寫入 RTC,否則下次開機系統會讀取 RTC 的舊時間覆蓋回去。
代表 NTP 自動校時已啟用,系統不允許手動改時間。先執行 sudo timedatectl set-ntp false 關閉自動校時,再用 set-time 手動設定即可。
一般桌機或不要求高精度的環境,systemd 內建的 timesyncd 就已足夠且免安裝。若是正式伺服器、資料庫、叢集節點等對時間精度要求較高的場景,建議改用 chrony,同步速度快且精度更高。
因為 Linux 預設硬體時鐘(RTC)儲存的是 UTC 時間,而 Windows 預設儲存的是本地時間,兩邊認知不同就會出現時區時數的落差。可用 sudo timedatectl set-local-rtc 1 讓 Linux 的 RTC 改用本地時間與 Windows 相容。
多半是對外網路或防火牆封鎖了 NTP 使用的 UDP 123 埠,導致無法連線校時伺服器。可用 timedatectl timesync-status 查看詳細同步狀態,並確認防火牆規則是否允許 NTP 對外連線。
這是典型的主機板 CMOS 電池沒電症狀,常見於老舊機器。硬體時鐘因為沒有電力維持,關機後時間就會歸零或跳回出廠日期,建議更換 CMOS 電池(通常是 CR2032 鈕扣電池)即可解決。
容器預設會共用宿主機的系統時鐘,請先確認宿主機時間本身正確。時區部分可透過掛載 /etc/localtime 或在啟動容器時加上環境變數,例如 docker run -e TZ=Asia/Taipei 來指定容器內的時區。
十、小結
時間管理的核心指令是 timedatectl,涵蓋查詢、改時區、啟用/關閉 NTP、手動設時間。精度要求高的伺服器環境建議用 chrony;桌機/一般環境用內建的 systemd-timesyncd 即可。手動改時間或關閉 NTP 後,別忘了執行 sudo hwclock --systohc 把時間寫回硬體時鐘,否則重開機後會跑掉。雙系統環境要特別注意 RTC 是儲存 UTC 還是本地時間,這是造成「差 8 小時」問題的根源。
希望這篇整理能幫助大家一次搞懂 Linux date 時間設定的來龍去脈,從 timedatectl 校正時區、NTP/chrony 自動校時,到 hwclock 寫入硬體時鐘,建立起一套完整且不易出錯的標準作業流程。
