跨語言開發時,日期時間格式化模式字元差異極大 (如 yyyy vs YYYY vs %Y),導致日誌、API、資料庫遷移頻頻出錯。本文匯總主流 8 語言的格式化語法、標準/自定義模式、時區處理、線程安全特性,提供可直接複製的速查表與最佳實踐建議。
| 語義 | Java (SimpleDateFormat / DateTimeFormatter) | C# (.NET) | JavaScript (手寫/date-fns) | PHP (date) | Ruby (strftime) | Python (strftime) | Go (time.Format) | Rust (chrono) |
|---|---|---|---|---|---|---|---|---|
| 年 (4位) | yyyy / yyyy | yyyy | YYYY / yyyy | Y | %Y | %Y | 2006 | %Y |
| 年 (2位) | yy | yy | YY / yy | y | %y | %y | 06 | %y |
| 月 (數字 1-12) | M | M | M | n | %-m | %-m | 1 | %-m |
| 月 (兩位) | MM | MM | MM | m | %m | %m | 01 | %m |
| 月 (縮寫) | MMM | MMM | MMM | M | %b | %b | Jan | %b |
| 月 (全名) | MMMM | MMMM | MMMM | F | %B | %B | January | %B |
| 日 (1-31) | d | d | d | j | %-d | %-d | 2 | %-d |
| 日 (兩位) | dd | dd | dd | d | %d | %d | 02 | %d |
| 時 24h (0-23) | H | H | H | G | %H | %H | 15 | %H |
| 時 24h 兩位 | HH | HH | HH | H | %H | %H | 03 | %H |
| 時 12h (1-12) | h | h | h | g | %I | %I | 3 | %I |
| 分 | m | m | m | i | %M | %M | 04 | %M |
| 秒 | s | s | s | s | %S | %S | 05 | %S |
| 毫秒/微秒 | SSS / SSSSSS | fff / ffffff | SSS / SSSSSS | u / v | %L / %N | %f | .000 / .000000 | %.3f / %.6f |
| AM/PM | a | tt | a / A | A / a | %p | %p | PM | %p |
| 時區偏移 | Z / XXX | zzz / K | Z / XX | O / P | %z / %:z | %z | -0700 / -07:00 | %z / %:z |
| ISO 8601 | ISO_INSTANT / yyyy-MM-dd'T'HH:mm:ssXXX | o / s | toISOString() | c | %Y-%m-%dT%H:%M:%S%z | %Y-%m-%dT%H:%M:%S%z | time.RFC3339 | %+ / RFC3339 |
SimpleDateFormat:非線程安全,月份 M、分鐘 m 易混淆。DateTimeFormatter:不可變、線程安全、預定義 ISO_LOCAL_DATE_TIME 等常量。yyyy vs YYYY:YYYY 是週年 (Week-based year),跨年週會導致年份錯誤,**永遠用 yyyy**。DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"):標準/自定義格式字串統一。d(短日期) D(長日期) t(短時間) T(長時間) f(完整日期短時間) F(完整日期長時間) g(通用短) G(通用長) u(通用可排序 UTC) U(完整 UTC)。DateTime.UtcNow 直接取得 UTC,避免時區轉換 Bug。Date 無格式化方法,toLocaleString() 受瀏覽器/地區設定影響不可靠。date-fns (函數式、樹搖優化) 或 dayjs (Moment.js 兼容 API、體積小) 或 luxon (Intl API 封裝、不可變)。date-fns 模式:yyyy MM dd HH mm ss SSS 與 Java DateTimeFormatter 高度一致。date("Y-m-d H:i:s"):字元區分大小寫 (Y 年、y 兩位年),m 月、i 分 易混。DateTime 物件導向 API:$dt->format('Y-m-d'),支援時區 new DateTimeZone('Asia/Taipei')。Time.now.strftime("%Y-%m-%d %H:%M:%S"):標準 C strftime 格式,% 前綴。Time 含完整時間、Date 僅日期,DateTime 兼具。%w 索引。datetime.now().strftime("%Y-%m-%d %H:%M:%S"):同 C strftime。f"{dt:%Y-%m-%d %H:%M:%S}" 更簡潔。pendulum / arrow 庫提供更人性化 API 與時區支援。time.Now().Format("2006-01-02 15:04:05") — 必須記住 2006-01-02 15:04:05 (月日時分秒年) 這個魔法參考時間,而非佔位符。time.RFC3339, time.RFC1123, time.Kitchen。chrono::Local::now().format("%Y-%m-%d %H:%M:%S").to_string():標準 strftime 兼容。DateTime<Utc>, DateTime<Local>, DateTime<FixedOffset> 編譯期保證正確。2024-01-15T14:30:45+08:00 (含時區偏移) 或 2024-01-15T06:30:45Z (UTC)。所有語言標準庫皆支援零配置解析/生成。TIMESTAMP WITH TIME ZONE (PostgreSQL) / DATETIMEOFFSET (SQL Server) / TIMESTAMP + 應用層約定 UTC (MySQL)。SerializationFeature.WRITE_DATES_AS_TIMESTAMPS=false), Newtonsoft.Json (DateFormatHandling.IsoDateFormat), Serde (with_timezone) 統一輸出 ISO 8601。# Java (jshell)
java.time.LocalDateTime.now().format(java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
# C# (csi / dotnet script)
DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
# JavaScript (Node + date-fns)
require('date-fns').format(new Date(), 'yyyy-MM-dd HH:mm:ss')
# PHP (php -a)
date('Y-m-d H:i:s')
# Ruby (irb)
Time.now.strftime("%Y-%m-%d %H:%M:%S")
# Python (python3)
from datetime import datetime; datetime.now().strftime("%Y-%m-%d %H:%M:%S")
# Go (go run)
package main; import ("fmt"; "time"); func main() { fmt.Println(time.Now().Format("2006-01-02 15:04:05")) }
# Rust (cargo + chrono)
chrono::Local::now().format("%Y-%m-%d %H:%M:%S").to_string()
日期時間格式化看似瑣碎,實則是跨系統數據一致性的基石。記住三個鐵律:1. 內部處理用強類型時間物件,不玩字串;2. 外部交換統一 ISO 8601 + 時區;3. 遷移舊代碼時優先替換格式化/解析邊界層。收藏本速查表,下次跨語言對接時間字段時,再也不用在文檔間來回跳轉。