0.0.1
This commit is contained in:
56
app/utils/time_tool.py
Normal file
56
app/utils/time_tool.py
Normal file
@@ -0,0 +1,56 @@
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from pydantic import BaseModel, field_serializer
|
||||
CN_TZ = timezone(timedelta(hours=8))
|
||||
|
||||
|
||||
def now_cn() -> datetime:
|
||||
"""
|
||||
获取中国时区的当前时间
|
||||
返回带有中国时区信息的 datetime 对象
|
||||
"""
|
||||
return datetime.now(CN_TZ)
|
||||
|
||||
def parse_time(val: str | int, is_end: bool = False) -> datetime:
|
||||
"""
|
||||
将传入的字符串或时间戳解析为中国时区的 datetime,用于数据库查询时间比较。
|
||||
支持格式:
|
||||
- "YYYY-MM-DD"
|
||||
- "YYYY-MM-DD HH:mm:ss"
|
||||
- 10 位时间戳(秒)
|
||||
- 13 位时间戳(毫秒)
|
||||
"""
|
||||
dt_cn: datetime
|
||||
|
||||
if isinstance(val, int) or (isinstance(val, str) and val.isdigit()):
|
||||
ts = int(val)
|
||||
# 根据量级判断是秒还是毫秒
|
||||
if ts >= 10**12:
|
||||
dt_cn = datetime.fromtimestamp(ts / 1000, CN_TZ)
|
||||
else:
|
||||
dt_cn = datetime.fromtimestamp(ts, CN_TZ)
|
||||
else:
|
||||
try:
|
||||
dt_cn = datetime.strptime(val, "%Y-%m-%d").replace(tzinfo=CN_TZ)
|
||||
if is_end:
|
||||
dt_cn = dt_cn.replace(hour=23, minute=59, second=59, microsecond=999999)
|
||||
except ValueError:
|
||||
try:
|
||||
dt_cn = datetime.strptime(val, "%Y-%m-%d %H:%M:%S").replace(tzinfo=CN_TZ)
|
||||
except ValueError:
|
||||
raise ValueError("时间格式错误,支持 'YYYY-MM-DD' 或 'YYYY-MM-DD HH:mm:ss' 或 10/13位时间戳")
|
||||
|
||||
# 与 ORM 配置保持一致(use_tz=False),返回本地时区的“朴素”时间
|
||||
return dt_cn.replace(tzinfo=None)
|
||||
|
||||
|
||||
# 自动把 datetime 序列化为 13位时间戳的基类
|
||||
class TimestampModel(BaseModel):
|
||||
"""自动把 datetime 序列化为 13位时间戳的基类"""
|
||||
|
||||
model_config = {"arbitrary_types_allowed": True}
|
||||
|
||||
@field_serializer("*", when_used="json", check_fields=False) # "*" 表示作用于所有字段
|
||||
def serialize_datetime(self, value):
|
||||
if isinstance(value, datetime):
|
||||
return int(value.timestamp()*1000) # 转成 13 位 int 时间戳
|
||||
return value
|
||||
Reference in New Issue
Block a user