first commit

This commit is contained in:
dekun
2026-08-01 10:33:19 +08:00
commit d9a34d4f20
72 changed files with 5499 additions and 0 deletions
+41
View File
@@ -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(即小时 023)。
"""
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:
"""023 小时桶。"""
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")