fix timezone bug
This commit is contained in:
102
utils/timezone.py
Normal file
102
utils/timezone.py
Normal file
@@ -0,0 +1,102 @@
|
||||
"""
|
||||
台灣時區處理工具模組
|
||||
|
||||
提供一致的時區處理函數,確保系統中所有時間都使用台灣時區(GMT+8)
|
||||
"""
|
||||
|
||||
from datetime import datetime, timezone, timedelta
|
||||
|
||||
# 台灣時區 (GMT+8)
|
||||
TAIWAN_TZ = timezone(timedelta(hours=8))
|
||||
|
||||
def now_taiwan() -> datetime:
|
||||
"""取得當前台灣時間"""
|
||||
return datetime.now(TAIWAN_TZ)
|
||||
|
||||
def now_utc() -> datetime:
|
||||
"""取得當前 UTC 時間(保留 timezone aware)"""
|
||||
return datetime.now(timezone.utc)
|
||||
|
||||
def to_taiwan_time(dt) -> datetime:
|
||||
"""將 datetime 轉換為台灣時間
|
||||
|
||||
Args:
|
||||
dt: datetime 物件(可能是 naive 或 aware)或 date 物件
|
||||
|
||||
Returns:
|
||||
台灣時區的 datetime 物件
|
||||
"""
|
||||
if dt is None:
|
||||
return None
|
||||
|
||||
# 如果是 date 物件,轉換為 datetime
|
||||
from datetime import date
|
||||
if isinstance(dt, date) and not isinstance(dt, datetime):
|
||||
# 這是 date 物件,轉換為 datetime(午夜時間)
|
||||
dt = datetime.combine(dt, datetime.min.time())
|
||||
|
||||
# 如果是 naive datetime,假設為 UTC
|
||||
if dt.tzinfo is None:
|
||||
dt = dt.replace(tzinfo=timezone.utc)
|
||||
|
||||
# 轉換為台灣時間
|
||||
return dt.astimezone(TAIWAN_TZ)
|
||||
|
||||
def to_utc_time(dt: datetime) -> datetime:
|
||||
"""將 datetime 轉換為 UTC 時間
|
||||
|
||||
Args:
|
||||
dt: datetime 物件(可能是 naive 或 aware)
|
||||
|
||||
Returns:
|
||||
UTC 時區的 datetime 物件
|
||||
"""
|
||||
if dt is None:
|
||||
return None
|
||||
|
||||
# 如果是 naive datetime,假設為台灣時間
|
||||
if dt.tzinfo is None:
|
||||
dt = dt.replace(tzinfo=TAIWAN_TZ)
|
||||
|
||||
return dt.astimezone(timezone.utc)
|
||||
|
||||
def format_taiwan_time(dt: datetime, format_str: str = "%Y-%m-%d %H:%M:%S") -> str:
|
||||
"""將 datetime 格式化為台灣時間字符串
|
||||
|
||||
Args:
|
||||
dt: datetime 物件
|
||||
format_str: 格式化字符串
|
||||
|
||||
Returns:
|
||||
格式化後的台灣時間字符串
|
||||
"""
|
||||
if dt is None:
|
||||
return ""
|
||||
|
||||
taiwan_time = to_taiwan_time(dt)
|
||||
return taiwan_time.strftime(format_str)
|
||||
|
||||
def parse_taiwan_time(time_str: str, format_str: str = "%Y-%m-%d %H:%M:%S") -> datetime:
|
||||
"""解析台灣時間字符串為 datetime
|
||||
|
||||
Args:
|
||||
time_str: 時間字符串
|
||||
format_str: 解析格式
|
||||
|
||||
Returns:
|
||||
台灣時區的 datetime 物件
|
||||
"""
|
||||
naive_dt = datetime.strptime(time_str, format_str)
|
||||
return naive_dt.replace(tzinfo=TAIWAN_TZ)
|
||||
|
||||
# 為了向後兼容,提供替代 datetime.utcnow() 的函數
|
||||
def utcnow() -> datetime:
|
||||
"""取得當前 UTC 時間(替代 datetime.utcnow())
|
||||
|
||||
注意:新代碼建議使用 now_taiwan() 或 now_utc()
|
||||
"""
|
||||
return now_utc().replace(tzinfo=None) # 返回 naive UTC datetime 以保持兼容性
|
||||
|
||||
def taiwan_now() -> datetime:
|
||||
"""取得當前台灣時間(naive datetime,用於存儲到資料庫)"""
|
||||
return now_taiwan().replace(tzinfo=None)
|
Reference in New Issue
Block a user