7dcb22f573
- 新增 holidays.py 服务:按年获取节假日数据,缓存到 system_config - 区分 holiday(工作日假日)和 workday(调休上班日)两种类型 - is_working_day() 支持调休判断:周末在 workdays 集合中视为工作日 - 启动时自动从 API 刷新当年+明年数据,失败则使用缓存 - 系统设置新增「从 API 刷新」按钮,支局长可手动触发 - 支持 2010-2026 年数据,API 免费免鉴权 Co-Authored-By: Claude <noreply@anthropic.com>
43 lines
1.2 KiB
Python
43 lines
1.2 KiB
Python
from datetime import date, datetime, timezone, timedelta
|
|
|
|
CST = timezone(timedelta(hours=8)) # China Standard Time
|
|
|
|
|
|
def today_cst() -> date:
|
|
"""Get today's date in Asia/Shanghai timezone."""
|
|
return datetime.now(timezone.utc).astimezone(CST).date()
|
|
|
|
|
|
def parse_date(s: str) -> date:
|
|
"""Parse a date string that may be YYYY-MM-DD or a full ISO datetime."""
|
|
return date.fromisoformat(s[:10])
|
|
|
|
|
|
def is_working_day(d: date | None = None, holidays: set[date] | None = None, workdays: set[date] | None = None) -> bool:
|
|
"""Check if a date is a Chinese working day.
|
|
|
|
Returns False for:
|
|
- Saturdays and Sundays (weekday >= 5), UNLESS in the workdays set (调休)
|
|
- Dates in the holidays set (weekday holidays like 春节/国庆)
|
|
|
|
Returns True for:
|
|
- Monday-Friday, unless in holidays set
|
|
- Saturday/Sunday that are in the workdays set (调休 makeup days)
|
|
"""
|
|
d = d or today_cst()
|
|
is_weekend = d.weekday() >= 5
|
|
|
|
# 调休: weekend that becomes a workday
|
|
if is_weekend and workdays and d in workdays:
|
|
return True
|
|
|
|
# Normal weekend
|
|
if is_weekend:
|
|
return False
|
|
|
|
# Weekday holiday
|
|
if holidays and d in holidays:
|
|
return False
|
|
|
|
return True
|