本文 AI 產出,尚未審核

Python 日期與時間(Datetime)——時間格式化(strftimestrptime

簡介

在日常開發中,日期與時間的呈現與解析是最常見的需求之一。無論是產生報表、寫入檔名、或是與外部系統交換資料,都必須把 datetime 物件轉成特定字串格式,或把字串重新轉回 datetime。Python 提供的 strftime格式化)與 strptime解析)正是為此而設計的兩個核心函式。掌握它們不僅能讓程式碼更易讀,也能避免因時區、字串不符而產生的錯誤。

本篇文章將從概念說明、實作範例、常見陷阱與最佳實踐,最後帶出實務應用,幫助 初學者到中階開發者 快速上手並寫出可靠的時間格式化程式碼。


核心概念

1. datetime.strftime – 把 datetime 物件格式化成字串

strftime 會根據提供的 格式字串(format string)輸出對應的日期時間文字。格式字串由一組「指令」組成,每個指令以 % 開頭,例如:

指令 說明 範例
%Y 四位數年份 2025
%m 兩位數月份(01‑12) 07
%d 兩位數日期(01‑31) 09
%H 24 小時制小時(00‑23) 14
%M 分鐘(00‑59) 35
%S 秒數(00‑59) 07
%a 簡寫星期(Mon) Tue
%A 完整星期(Monday) Tuesday
%b 簡寫月份(Jan) Jul
%B 完整月份(January) July
%p AM/PM 標記(Locale 依賴) PM

小技巧:在 Jupyter Notebook 或 REPL 中,datetime.datetime.now().strftime("%c") 能直接顯示系統預設的完整日期時間字串,快速測試格式。

2. datetime.strptime – 把符合格式的字串解析datetime 物件

strptime 的使用方式與 strftime 相反:先給定字串,再給定相同的格式字串,Python 會依照格式把字串轉成 datetime。若字串與格式不符,會拋出 ValueError

注意strptime 只接受 完整 的日期時間資訊;如果格式中缺少某個欄位,會以預設值(如 1900-01-01)填補。


程式碼範例

以下示範 5 個實用情境,皆以 datetime 標準庫為例,程式碼使用 python 語法標記。

範例 1:基本的日期時間格式化

from datetime import datetime

now = datetime.now()
# 2025-07-09 14:35:07
formatted = now.strftime("%Y-%m-%d %H:%M:%S")
print(formatted)

說明%Y-%m-%d %H:%M:%S 為常見的「ISO‑like」格式,適合寫入資料庫或日誌檔。

範例 2:自訂檔名中的時間戳記

from datetime import datetime

log_file = f"log_{datetime.now().strftime('%Y%m%d_%H%M%S')}.txt"
print(log_file)   # 例如:log_20250709_143507.txt

說明:使用 strftime 產生不含分隔符的字串,讓檔名在檔案系統中保持排序性。

範例 3:解析使用者輸入的日期字串

from datetime import datetime

user_input = "2025/07/09 14:35"
# 注意:格式必須與字串完全對應
dt = datetime.strptime(user_input, "%Y/%m/%d %H:%M")
print(dt)   # 2025-07-09 14:35:00

說明strptime 會自動把缺少的秒數補成 0,但若字串缺少分鐘或小時,會拋出錯誤。

範例 4:處理不同語系的月份名稱

import locale
from datetime import datetime

# 設定為台灣中文
locale.setlocale(locale.LC_TIME, "zh_TW.UTF-8")

s = "2025年七月09日"
dt = datetime.strptime(s, "%Y年%B%d日")
print(dt)   # 2025-07-09 00:00:00

說明%B 代表完整月份名稱,必須配合正確的 locale 才能正確解析。

範例 5:將 UTC 時間字串轉成本地時間

from datetime import datetime, timezone, timedelta

utc_str = "2025-07-09T06:35:07Z"
utc_dt = datetime.strptime(utc_str, "%Y-%m-%dT%H:%M:%SZ")
utc_dt = utc_dt.replace(tzinfo=timezone.utc)

# 以台北時區 (+08:00) 轉換
taipei = timezone(timedelta(hours=8))
local_dt = utc_dt.astimezone(taipei)
print(local_dt.strftime("%Y-%m-%d %H:%M:%S %Z"))
# 2025-07-09 14:35:07 UTC+08:00

說明:先用 strptime 解析成「沒有時區」的 datetime,再手動加上 timezone.utc,最後使用 astimezone 轉換至本地時區。


常見陷阱與最佳實踐

陷阱 說明 最佳實踐
格式不匹配 strptime 的格式字串必須完全對應輸入字串,少一個 % 或空格都會拋 ValueError 在接受使用者輸入前,先 正規表達式 檢查或使用 try/except 捕捉錯誤。
時區遺失 datetime 物件若未設定 tzinfo,會被視為「本地時間」或「天真時間」,在跨時區運算時容易出錯。 儘量使用 aware datetime(帶時區)或 pytz/zoneinfo 處理時區。
平台差異的 locale 不同作業系統的 locale 名稱可能不同,導致 %b%B 解析失敗。 在程式啟動時 檢查 locale 是否成功設定,必要時提供 fallback。
%y1900 年的衝突 %y 只接受兩位數年份,Python 會根據 1969‑2068 的範圍自動推算。 若需要明確的世紀資訊,使用 %Y(四位數),避免歧義。
字串長度與空白 strftime 會把空白字元原樣輸出,解析時若字串多餘空白會失敗。 使用 .strip() 清理輸入,或在格式字串中明確加入空白。

最佳實踐小結

  1. 統一使用 ISO 8601%Y-%m-%dT%H:%M:%S%z)作為跨系統的交換格式。
  2. 建立常用格式常數,如 RFC_2822 = "%a, %d %b %Y %H:%M:%S %z",減少硬編碼。
  3. 使用 try/except 捕捉 ValueError,並回傳友善的錯誤訊息給使用者。
  4. 在需要時明確指定時區,避免「天真」時間造成的錯誤。

實際應用場景

  1. 日誌檔(Log)標記
    • 產生 log_20250709_143507.txt,讓檔案自動依時間排序。
  2. 資料庫時間欄位
    • 使用 strftime("%Y-%m-%d %H:%M:%S") 產生 MySQL DATETIME 格式字串。
  3. API 日期參數
    • 多數 RESTful API 規範要求 ISO 8601,故需 datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ")
  4. 報表產出
    • datetime 轉成「民國年」或「中文月份」供 PDF、Excel 使用,需配合 locale 與自訂格式。
  5. 排程系統
    • 讀取使用者輸入的「2025/07/09 14:35」字串,透過 strptime 轉成 datetime,再交給 APSchedulercron 排程。

總結

  • strftimestrptime 是 Python 處理 日期時間字串 的兩把關鍵工具。
  • 了解 格式指令時區概念、以及 locale 影響,才能寫出正確且跨平台的程式。
  • 常見的陷阱包括格式不匹配、時區遺失與 locale 差異,透過 例外處理統一使用 ISO 8601明確設定時區 可大幅降低錯誤風險。
  • 在日誌、資料庫、API、報表與排程等實務場景中,適時使用 strftime/strptime 能提升程式可讀性與維護性。

掌握了這些概念與技巧後,你就能自信地在任何 Python 專案中處理時間格式化,讓日期時間不再是開發的絆腳石,而是提升系統可靠性的利器。祝你寫程式愉快!