first commit
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
"""Asia/Shanghai 日切与时段桶。时间戳一律 UTC ms 入,上海出。"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
from zoneinfo import ZoneInfo
|
||||
|
||||
_SH = ZoneInfo("Asia/Shanghai")
|
||||
|
||||
|
||||
def _to_shanghai(ts_ms: int) -> datetime:
|
||||
return datetime.fromtimestamp(int(ts_ms) / 1000.0, tz=_SH)
|
||||
|
||||
|
||||
def shanghai_day(ts_ms: int) -> str:
|
||||
"""上海自然日 YYYY-MM-DD。"""
|
||||
return _to_shanghai(ts_ms).strftime("%Y-%m-%d")
|
||||
|
||||
|
||||
def shanghai_bucket(ts_ms: int, bucket_minutes: int = 60) -> int:
|
||||
"""
|
||||
日内时段桶起点(分钟,0–1439)。
|
||||
默认 60 → 0,60,120,...,1380(即小时 0–23)。
|
||||
"""
|
||||
if bucket_minutes <= 0:
|
||||
raise ValueError("bucket_minutes must be > 0")
|
||||
dt = _to_shanghai(ts_ms)
|
||||
minutes = dt.hour * 60 + dt.minute
|
||||
return (minutes // bucket_minutes) * bucket_minutes
|
||||
|
||||
|
||||
def shanghai_bucket_hour(ts_ms: int) -> int:
|
||||
"""0–23 小时桶。"""
|
||||
return shanghai_bucket(ts_ms, 60) // 60
|
||||
|
||||
|
||||
def rolling_day_start(anchor_ymd: str, days: int) -> str:
|
||||
"""锚点日(含)往前 days-1 天的起始 YYYY-MM-DD。"""
|
||||
d = datetime.strptime(anchor_ymd, "%Y-%m-%d").date()
|
||||
start = d - timedelta(days=max(0, days - 1))
|
||||
return start.strftime("%Y-%m-%d")
|
||||
Reference in New Issue
Block a user