第 23 課 · 進階 · 19 分鐘

Python datetime 日期與時間

準確處理日曆日期和簡單的時間間隔。

datetime日期運算timedeltaISO 日期

牛奶盒上寫著「週五前用完」,可週五不是一個天數。日期有自己的算術。日曆上的日期和時間上的某一刻,差在哪裡?

datetime 模組把日曆日期、時鐘時間和時間間隔分開。初學階段先掌握 date 和 timedelta。只有當資料確實表示不同地區共同觀察的某一瞬間時,才需要引入時區。 你還會區分日期與時刻、解析 ISO 文字,並避免把一個月當成 30 天。

建立一個日期

date(year, month, day) 會驗證參數,並回傳不可變的日期物件。isoformat() 生成可排序的 YYYY-MM-DD 形式。需要拆分年月日時,可以直接存取 year、month 和 day。

from datetime import date
start = date(2026, 1, 15)
print(start.isoformat())
print(start.year, start.month, start.day)

一個日曆日期

加上 timedelta

timedelta 表示一段時長。把它加到日期上會回傳新日期,原物件不變。兩個日期相減會得到一個 timedelta,可以用 days 屬性讀取天數。

from datetime import date, timedelta
start = date(2026, 1, 30)
end = start + timedelta(days=3)
print(end.isoformat())
print((end - start).days)

時長與日期差

格式化成讀者能看懂的形式

strftime 按格式模式生成字串。數字日期用 %Y、%m 和 %d。月份名和星期名依賴區域設定,輸出必須到處一致時優先使用數字格式。

from datetime import date
day = date(2026, 10, 27)
print(day.strftime("%Y/%m/%d"))
print(day.isoformat())

穩定的數字格式

日期不是時刻

date 只儲存日曆上的一天,沒有時區。datetime 儲存時鐘讀數;只有帶時區的 datetime 才能表示不同地區共同觀察的某一瞬間。不要把無時區 datetime 和帶時區 datetime 相減;先判斷資料到底是日期還是時刻。

from datetime import date, datetime, timezone
day = date(2026, 10, 28)
moment = datetime(2026, 10, 28, 12, 0, tzinfo=timezone.utc)
print(day.isoformat())
print(moment.isoformat())
print(moment.tzinfo is not None)

日曆日與帶時區的時刻

先解析 ISO 文字,再做運算

fromisoformat 接受 YYYY-MM-DD 形狀,拒絕含糊的日/月順序。不要從 28/10/2026 這樣的字串猜順序;向資料源確認格式並顯式解析。在邊界捕獲 ValueError,並報告壞值。

from datetime import date
for raw in ["2026-10-28", "28/10/2026"]:
    try:
        parsed = date.fromisoformat(raw)
        print(parsed.year, parsed.month, parsed.day)
    except ValueError:
        print("not ISO:", raw)

先驗證形狀,再使用日期

一個月不是 30 天

timedelta 計算的是固定天數,不是日曆月。1 月 31 日加 30 天會落到 3 月,而不是 2 月 28 日。如果規則是「一個日曆月」,要用顯式的月份計算或維護良好的日期庫,不要寫成 30 天。

from datetime import date, timedelta
start = date(2026, 1, 31)
print((start + timedelta(days=30)).isoformat())
print((start + timedelta(days=59)).isoformat())

固定天數與日曆月

本課要點

  • date(y, m, d) 建立一個經過驗證的日曆日期。
  • timedelta(days=n) 表示一段時長。
  • 日期加 timedelta 會回傳新的日期物件。
  • 輸出不能依賴區域設定時,用數字形式的 strftime 模式。
  • 運算前先選 date 或帶時區的 datetime;timedelta 表示固定時長。

常見錯誤

  • 在儲存日期時使用含糊的日/月順序。
  • 試圖原地修改日期;date 物件不可變。
  • 還沒分清日期和時刻,就急著添加時區。
  • 把無時區和帶時區的 datetime 相減,還期待有意義的結果。
輪到你

建立 date(2026, 12, 31),加一天,並用 ISO 格式列印兩個日期。

動手試試

改改變數、先預測輸出,再執行程式碼。第一次點擊「執行程式碼」時會下載 Python 執行時,可能需要幾秒鐘。

瀏覽器內 Python本機執行 · 無需帳號
首次執行會從 CDN 下載 Pyodide。修改後點擊「執行程式碼」。

練習本課

12 道題,作答後立即看到解釋。

查看 12 道題答案開始練習
← pathlib 路徑assert 測試 →