cn_holiday.py 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. """中国节假日日历只读服务"""
  2. from __future__ import annotations
  3. from datetime import date, timedelta
  4. from typing import Any, Dict, List, Optional
  5. from sqlalchemy.orm import Session
  6. from app.models.cn_holiday import SysCnHolidayDay
  7. def is_rest_day(db: Session, d: date) -> bool:
  8. """查表判定是否休息日;无行则按周六日回退。"""
  9. row: Optional[SysCnHolidayDay] = (
  10. db.query(SysCnHolidayDay).filter(SysCnHolidayDay.day_date == d).first()
  11. )
  12. if row is None:
  13. return d.weekday() >= 5
  14. if row.is_rest_day is not None:
  15. return int(row.is_rest_day) == 1
  16. return int(row.day_type or 0) in (1, 2, 3)
  17. def list_day_flags(db: Session, start: date, end: date) -> List[Dict[str, Any]]:
  18. """返回 [start, end] 闭区间每日标志;缺行用周末回退补齐。"""
  19. if end < start:
  20. return []
  21. rows = (
  22. db.query(SysCnHolidayDay)
  23. .filter(SysCnHolidayDay.day_date >= start, SysCnHolidayDay.day_date <= end)
  24. .all()
  25. )
  26. by_date = {r.day_date: r for r in rows}
  27. out: List[Dict[str, Any]] = []
  28. cur = start
  29. while cur <= end:
  30. row = by_date.get(cur)
  31. if row is not None:
  32. rest = (
  33. int(row.is_rest_day) == 1
  34. if row.is_rest_day is not None
  35. else int(row.day_type or 0) in (1, 2, 3)
  36. )
  37. out.append(
  38. {
  39. "dayDate": cur.isoformat(),
  40. "dayType": int(row.day_type),
  41. "isRestDay": rest,
  42. "dayName": row.day_name,
  43. }
  44. )
  45. else:
  46. is_weekend = cur.weekday() >= 5
  47. out.append(
  48. {
  49. "dayDate": cur.isoformat(),
  50. "dayType": 1 if is_weekend else 0,
  51. "isRestDay": is_weekend,
  52. "dayName": None,
  53. }
  54. )
  55. cur += timedelta(days=1)
  56. return out