115 lines
3.4 KiB
Python
115 lines
3.4 KiB
Python
from datetime import datetime, timezone, timedelta
|
||
from dateutil import parser, tz
|
||
|
||
'''
|
||
2025-02-09T15:45:00+00:00 采用的是 ISO 8601 国际标准日期时间格式,具体特点如下:
|
||
|
||
日期部分:YYYY-MM-DD(年-月-日),例如2025-02-09表示2025年2月9日。
|
||
时间部分:HH:mm:ss(时:分:秒),例如15:45:00表示下午3点45分0秒。
|
||
分隔符:日期与时间之间用字母T连接,表明这是一个完整的时间点。
|
||
时区偏移:末尾的+00:00表示该时间基于协调世界时(UTC),即零时区。若使用Z替代+00:00(如2025-02-09T15:45:00Z),也符合ISO 8601标准,两者等价
|
||
|
||
北京时间格式
|
||
2025-02-09T15:45:00+08:00
|
||
|
||
'''
|
||
BG_TZ = tz.gettz('Asia/Shanghai')
|
||
UTC_TZ = tz.gettz('UTC')
|
||
|
||
def parse_utc_time(query_time: str) -> datetime:
|
||
'''
|
||
接受 任意格式的字符串,如果解析出来不带时区,则用 replace 添加 +00:00 时区
|
||
如果解析出来已经有时区,则用 astimezone 转换成UTC时间
|
||
'''
|
||
|
||
# 解析时间字符串
|
||
dt: datetime = parser.parse(query_time)
|
||
if dt.tzinfo is None:
|
||
dt = dt.replace(tzinfo=UTC_TZ)
|
||
else:
|
||
dt = dt.astimezone(UTC_TZ)
|
||
|
||
return dt
|
||
|
||
def parse_beijing_time(query_time: str) -> datetime:
|
||
'''
|
||
接受 任意格式的字符串,如果解析出来不带时区,则用 replace 添加 +08:00 时区
|
||
如果解析出来已经有时区,则用 astimezone 转换成北京时间
|
||
|
||
也就是任意合法的时间字符串,最后都解析成 北京 时间
|
||
|
||
'''
|
||
|
||
# 解析时间字符串
|
||
dt: datetime = parser.parse(query_time)
|
||
if dt.tzinfo is None:
|
||
dt = dt.replace(tzinfo=BG_TZ)
|
||
else:
|
||
dt = dt.astimezone(tz=BG_TZ)
|
||
|
||
return dt
|
||
|
||
|
||
def to_utc_time(dt: datetime) -> datetime:
|
||
'''
|
||
将一个北京时间的时间点,转换成utc
|
||
'''
|
||
utc_time = dt.astimezone(UTC_TZ)
|
||
return utc_time
|
||
|
||
|
||
def to_beijing_time(dt: datetime) -> datetime:
|
||
'''
|
||
将一个 utc 的时间点,转换成北京时间
|
||
'''
|
||
beijing_time = dt.astimezone(tz=BG_TZ)
|
||
return beijing_time
|
||
|
||
|
||
def to_time_range(dt: datetime, delta: float) -> tuple[datetime, datetime]:
|
||
'''
|
||
将一个时间点,转换成 start/end 时间段
|
||
有些查询按照一个时间点查不到,用时间段保证能成功
|
||
|
||
delta 单位是秒
|
||
'''
|
||
start_time = dt - timedelta(seconds=delta)
|
||
end_time = dt + timedelta(seconds=delta)
|
||
|
||
return (start_time, end_time)
|
||
|
||
def parse_beijing_date_range(query_date: str) -> tuple[datetime, datetime]:
|
||
'''
|
||
将一个日期字符串,转换成 start/end 时间段,传进来的日期被认为是北京时间
|
||
日期字符串格式:YYYY-MM-DD
|
||
'''
|
||
start_time = parse_beijing_time(query_date)
|
||
end_time = start_time + timedelta(days=1)
|
||
|
||
return (start_time, end_time)
|
||
|
||
|
||
def get_day_start(dt: datetime.date) -> datetime:
|
||
'''
|
||
获取 某一天的 00:00:00
|
||
这一天可以是北京时间,也可以是 utc 时间
|
||
'''
|
||
return dt.replace(hour=0, minute=0, second=0, microsecond=0)
|
||
|
||
|
||
def get_day_end(dt: datetime.date) -> datetime:
|
||
'''
|
||
获取 某一天的 23:59:59
|
||
这一天可以是北京时间,也可以是 utc 时间
|
||
'''
|
||
return dt.replace(hour=23, minute=59, second=59, microsecond=0)
|
||
|
||
def get_date_from_time(time: str) -> str:
|
||
'''
|
||
将一个时间点,转换成日期
|
||
'''
|
||
dt = parse_beijing_time(time)
|
||
return str(dt.date())
|
||
|
||
|