本文 AI 產出,尚未審核

Python 日期與時間(Datetime)——UNIX Timestamp 完全指南


簡介

在現代程式開發中,時間的表示與處理是不可或缺的需求。無論是日誌紀錄、資料庫儲存、API 互通,或是排程系統,都必須以一致且精確的方式描述「什麼時候」發生了什麼事。
最常見且跨平台的時間表示方式之一,就是 UNIX Timestamp(亦稱 Epoch 時間),它以「自 1970 年 1 月 1 日 00:00:00(UTC)以來的秒數」作為基礎,簡潔、易於比較與傳輸。

對於 Python 開發者而言,熟練掌握 datetime 模組與 UNIX Timestamp 之間的相互轉換,能讓你在處理時區、格式化、以及跨語言的時間交換時更加得心應手。本篇文章將從概念說明、實作範例、常見陷阱、最佳實踐,一路帶你深入了解並活用 UNIX Timestamp。


核心概念

1. 什麼是 UNIX Timestamp?

  • 定義:自 1970‑01‑01 00:00:00 UTC 起算的「秒」數(或毫秒、微秒)。
  • 特性
    • 單一整數值,方便儲存與比較。
    • 與時區無關,所有系統皆以 UTC 為基準。
    • 常見於資料庫(如 MySQL 的 TIMESTAMP)、JSON API、日志檔等。

2. Python datetimetimestamp() / fromtimestamp()

Python 的 datetime 物件提供兩個重要方法:

方法 功能 範例
datetime.timestamp() aware(具時區)或 naive(無時區)datetime 轉為 UNIX Timestamp(float) dt.timestamp()
datetime.fromtimestamp(ts, tz=None) 依據 Timestamp 建立 datetimetz 為可選的時區資訊 datetime.fromtimestamp(1697040000, tz=timezone.utc)

注意:若 datetimenaivetimestamp() 會以本機(系統)時區為基準,可能導致不預期的結果;建議在進行轉換前先將其 本地化(localize)為 aware 物件。

3. 時區(Timezone)概念

  • UTC(Coordinated Universal Time)是唯一的全球標準時間。
  • 本地時區(如 Asia/Taipei)是相對於 UTC 的偏移量。
  • 在 Python 中,可使用 datetime.timezone(固定偏移)或第三方套件 pytzzoneinfo(Python 3.9+)處理 IANA 時區資料。

程式碼範例

以下示範 5 個實用範例,涵蓋從 Timestamp 取得 datetime、時區轉換、毫秒與微秒的處理、以及常見的 JSON 序列化需求。

1️⃣ 取得當前 UNIX Timestamp(秒)

from datetime import datetime, timezone

# 取得 UTC 時間的 datetime 物件
now_utc = datetime.now(timezone.utc)

# 直接轉為 Timestamp(float,單位:秒)
timestamp_sec = now_utc.timestamp()
print(f"Current UNIX timestamp (seconds): {timestamp_sec}")

重點:使用 timezone.utc 產生 aware datetime,避免本機時區影響。


2️⃣ 從 Timestamp 轉回本地時間(含時區資訊)

from datetime import datetime, timezone, timedelta

# 假設已知的 Timestamp(秒)
ts = 1697040000  # 2023-10-11 00:00:00 UTC

# 轉為 UTC datetime
dt_utc = datetime.fromtimestamp(ts, tz=timezone.utc)

# 轉為台北時區 (UTC+8)
taipei_tz = timezone(timedelta(hours=8))
dt_taipei = dt_utc.astimezone(taipei_tz)

print(f"UTC time   : {dt_utc.isoformat()}")
print(f"Taipei time: {dt_taipei.isoformat()}")

3️⃣ 處理毫秒或微秒的 Timestamp

from datetime import datetime, timezone

# 以毫秒為單位的 Timestamp(常見於 JavaScript)
ms_ts = 1697040000123

# 先除以 1000 取得秒數(float),再轉換
dt = datetime.fromtimestamp(ms_ts / 1000, tz=timezone.utc)

print(f"Timestamp (ms) -> datetime: {dt.isoformat()}")

# 若要取得微秒(Python float 支援),直接使用除以 1_000_000
us_ts = 1697040000123456
dt_us = datetime.fromtimestamp(us_ts / 1_000_000, tz=timezone.utc)
print(f"Timestamp (µs) -> datetime: {dt_us.isoformat()}")

4️⃣ 使用 zoneinfo(Python 3.9+)管理 IANA 時區

from datetime import datetime
from zoneinfo import ZoneInfo   # Python 3.9 之後內建

# 取得台北時區的現在時間
now_taipei = datetime.now(ZoneInfo("Asia/Taipei"))
print(f"Now in Taipei: {now_taipei.isoformat()}")

# 轉為 UTC Timestamp
ts = now_taipei.timestamp()
print(f"Corresponding UTC timestamp: {ts}")

提醒zoneinfo 直接讀取系統的時區資料庫,無需額外安裝套件。


5️⃣ JSON 序列化與反序列化(Timestamp 為數字)

import json
from datetime import datetime, timezone

def datetime_to_timestamp(dt: datetime) -> float:
    """將 aware datetime 轉成 UNIX timestamp(秒)"""
    return dt.timestamp()

def timestamp_to_datetime(ts: float) -> datetime:
    """將 timestamp 轉回 UTC aware datetime"""
    return datetime.fromtimestamp(ts, tz=timezone.utc)

# 範例資料
payload = {
    "event": "user_login",
    "time": datetime_to_timestamp(datetime.now(timezone.utc))
}

# 序列化為 JSON(timestamp 以數字形式保存)
json_str = json.dumps(payload)
print(f"JSON payload: {json_str}")

# 讀回時轉回 datetime
data = json.loads(json_str)
event_time = timestamp_to_datetime(data["time"])
print(f"Event time (UTC): {event_time.isoformat()}")

常見陷阱與最佳實踐

陷阱 可能的結果 解決方案
使用 naive datetime 直接呼叫 .timestamp() 依本機時區產生錯誤的秒數 先將 datetime 本地化replace(tzinfo=timezone.utc) 或使用 pytz/zoneinfo
忘記考慮閏秒 某些極端情況下時間差錯誤 1 秒 大多數應用可忽略;若需精確時間同步,使用 NTP/datetimefold 參數
毫秒/微秒混用 產生非預期的日期(少了 3~6 位數) 統一單位:在程式內部固定使用秒(float),或明確除以 1000/1_000_000
時區資料庫過期 時區偏移錯誤(如夏令時間變更) 定期更新系統時區資料,或使用 tzdata 套件(pip install tzdata
JSON 序列化時遺失時區資訊 只留下本地時間字串,無法還原 使用 timestamp(數字)或 ISO 8601 帶時區的字串(datetime.isoformat()

推薦的最佳實踐

  1. 全程使用 aware datetime:在產生、傳遞、儲存時間時,都保留時區資訊。
  2. 統一使用 UTC:除非前端或使用者介面需要本地時間,否則在後端以 UTC 為唯一基準。
  3. 避免硬編碼時區偏移:使用 zoneinfo / pytz 取得 IANA 時區,確保夏令時間自動調整。
  4. 在序列化時選擇數字 Timestamp:JSON、MessagePack、Protobuf 等二進位協議皆支援。
  5. 單元測試時間相關功能:使用 freezegundatetime.mock 固定時間,驗證轉換邏輯。

實際應用場景

場景 為何需要 UNIX Timestamp 示例程式碼摘要
日誌系統 便於跨機器、跨語言的時間排序 log_time = datetime.now(timezone.utc).timestamp()
資料庫儲存 BIGINT 可直接存儲秒數,索引效能佳 INSERT INTO events (ts) VALUES (%s)
API 互通(前端 JavaScript) 前端使用 Date.now()(毫秒),後端直接接受秒/毫秒 前端 fetch('/api', {body: JSON.stringify({ts: Date.now()})})
排程系統(Celery、Airflow) 以 Timestamp 計算延遲、重試時間 eta = datetime.fromtimestamp(ts, tz=timezone.utc)
金融交易 高頻交易需毫秒甚至微秒級別的時間戳 trade_ts = time.time()(返回 float 秒)

總結

  • UNIX Timestamp 是跨平台、跨語言的時間基礎,適合儲存、比較與傳輸。
  • 在 Python 中,datetime.timestamp()datetime.fromtimestamp() 是核心 API,配合 aware datetimezoneinfo(或 pytz)即可安全處理時區。
  • 常見陷阱多與 naive datetime單位不一致時區資料過期 有關,遵守 全程使用 UTC、保留時區資訊 的原則,可大幅降低錯誤。
  • 透過本文的 5 個範例,你已能從取得當前 Timestamp、進行毫秒/微秒處理、到 JSON 序列化完整掌握實務需求。

掌握了 UNIX Timestamp 的使用,你的 Python 應用將在時間管理上更加精準、可靠且易於維護。祝你在未來的專案中玩轉時間,寫出更穩定的程式碼!