calendar.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. """节日/节点事件日历与预热配置。"""
  2. from __future__ import annotations
  3. from dataclasses import dataclass
  4. from typing import Literal
  5. FestivalKind = Literal["statutory", "non_statutory"]
  6. EventType = Literal["节日/节气", "纪念日", "特定民生热点", "特定天气时段"]
  7. @dataclass(frozen=True)
  8. class FestivalEvent:
  9. """节点事件、类型及预热天数。"""
  10. name: str
  11. event_type: EventType
  12. prewarm_days: int
  13. kind: FestivalKind = "non_statutory"
  14. # 法定节假日:节日活跃期按国务院当年放假区间计算
  15. _STATUTORY = "statutory"
  16. _NON_STATUTORY = "non_statutory"
  17. _FESTIVAL_SOLAR = "节日/节气"
  18. _MEMORIAL = "纪念日"
  19. _LIVELIHOOD = "特定民生热点"
  20. _WEATHER = "特定天气时段"
  21. DEFAULT_FESTIVAL_EVENTS: tuple[FestivalEvent, ...] = (
  22. FestivalEvent("元旦", _FESTIVAL_SOLAR, 10, _STATUTORY),
  23. FestivalEvent("腊八节", _FESTIVAL_SOLAR, 5, _NON_STATUTORY),
  24. FestivalEvent("小年", _FESTIVAL_SOLAR, 7, _NON_STATUTORY),
  25. FestivalEvent("除夕", _FESTIVAL_SOLAR, 10, _NON_STATUTORY),
  26. FestivalEvent("春节", _FESTIVAL_SOLAR, 10, _STATUTORY),
  27. FestivalEvent("元宵节", _FESTIVAL_SOLAR, 7, _NON_STATUTORY),
  28. FestivalEvent("龙抬头", _FESTIVAL_SOLAR, 7, _NON_STATUTORY),
  29. FestivalEvent("妇女节", _FESTIVAL_SOLAR, 5, _NON_STATUTORY),
  30. FestivalEvent("上巳节", _FESTIVAL_SOLAR, 5, _NON_STATUTORY),
  31. FestivalEvent("劳动节", _FESTIVAL_SOLAR, 7, _STATUTORY),
  32. FestivalEvent("母亲节", _FESTIVAL_SOLAR, 5, _NON_STATUTORY),
  33. FestivalEvent("端午节", _FESTIVAL_SOLAR, 7, _STATUTORY),
  34. FestivalEvent("儿童节", _FESTIVAL_SOLAR, 5, _NON_STATUTORY),
  35. FestivalEvent("父亲节", _FESTIVAL_SOLAR, 5, _NON_STATUTORY),
  36. FestivalEvent("建党节", _FESTIVAL_SOLAR, 10, _NON_STATUTORY),
  37. FestivalEvent("建军节", _FESTIVAL_SOLAR, 10, _NON_STATUTORY),
  38. FestivalEvent("七夕节", _FESTIVAL_SOLAR, 5, _NON_STATUTORY),
  39. FestivalEvent("中元节", _FESTIVAL_SOLAR, 5, _NON_STATUTORY),
  40. FestivalEvent("教师节", _FESTIVAL_SOLAR, 5, _NON_STATUTORY),
  41. FestivalEvent("中秋节", _FESTIVAL_SOLAR, 7, _STATUTORY),
  42. FestivalEvent("重阳节", _FESTIVAL_SOLAR, 5, _NON_STATUTORY),
  43. FestivalEvent("国庆节", _FESTIVAL_SOLAR, 7, _STATUTORY),
  44. FestivalEvent("立春", _FESTIVAL_SOLAR, 5, _NON_STATUTORY),
  45. FestivalEvent("雨水", _FESTIVAL_SOLAR, 5, _NON_STATUTORY),
  46. FestivalEvent("惊蛰", _FESTIVAL_SOLAR, 5, _NON_STATUTORY),
  47. FestivalEvent("春分", _FESTIVAL_SOLAR, 5, _NON_STATUTORY),
  48. FestivalEvent("清明", _FESTIVAL_SOLAR, 15, _STATUTORY),
  49. FestivalEvent("谷雨", _FESTIVAL_SOLAR, 5, _NON_STATUTORY),
  50. FestivalEvent("立夏", _FESTIVAL_SOLAR, 5, _NON_STATUTORY),
  51. FestivalEvent("小满", _FESTIVAL_SOLAR, 5, _NON_STATUTORY),
  52. FestivalEvent("芒种", _FESTIVAL_SOLAR, 5, _NON_STATUTORY),
  53. FestivalEvent("夏至", _FESTIVAL_SOLAR, 5, _NON_STATUTORY),
  54. FestivalEvent("小暑", _FESTIVAL_SOLAR, 5, _NON_STATUTORY),
  55. FestivalEvent("大暑", _FESTIVAL_SOLAR, 5, _NON_STATUTORY),
  56. FestivalEvent("立秋", _FESTIVAL_SOLAR, 5, _NON_STATUTORY),
  57. FestivalEvent("处暑", _FESTIVAL_SOLAR, 5, _NON_STATUTORY),
  58. FestivalEvent("白露", _FESTIVAL_SOLAR, 5, _NON_STATUTORY),
  59. FestivalEvent("秋分", _FESTIVAL_SOLAR, 5, _NON_STATUTORY),
  60. FestivalEvent("寒露", _FESTIVAL_SOLAR, 5, _NON_STATUTORY),
  61. FestivalEvent("霜降", _FESTIVAL_SOLAR, 5, _NON_STATUTORY),
  62. FestivalEvent("立冬", _FESTIVAL_SOLAR, 7, _NON_STATUTORY),
  63. FestivalEvent("小雪", _FESTIVAL_SOLAR, 5, _NON_STATUTORY),
  64. FestivalEvent("大雪", _FESTIVAL_SOLAR, 5, _NON_STATUTORY),
  65. FestivalEvent("冬至", _FESTIVAL_SOLAR, 7, _NON_STATUTORY),
  66. FestivalEvent("小寒", _FESTIVAL_SOLAR, 5, _NON_STATUTORY),
  67. FestivalEvent("大寒", _FESTIVAL_SOLAR, 5, _NON_STATUTORY),
  68. FestivalEvent("周总理逝世", _MEMORIAL, 7, _NON_STATUTORY),
  69. FestivalEvent("周总理诞辰", _MEMORIAL, 7, _NON_STATUTORY),
  70. FestivalEvent("七七事变纪念日", _MEMORIAL, 5, _NON_STATUTORY),
  71. FestivalEvent("日本投降", _MEMORIAL, 5, _NON_STATUTORY),
  72. FestivalEvent("毛主席逝世", _MEMORIAL, 30, _NON_STATUTORY),
  73. FestivalEvent("918纪念日", _MEMORIAL, 5, _NON_STATUTORY),
  74. FestivalEvent("毛主席诞辰", _MEMORIAL, 30, _NON_STATUTORY),
  75. FestivalEvent("公祭日", _MEMORIAL, 10, _NON_STATUTORY),
  76. FestivalEvent("台湾光复纪念日", _MEMORIAL, 5, _NON_STATUTORY),
  77. FestivalEvent("全国两会", _LIVELIHOOD, 30, _NON_STATUTORY),
  78. FestivalEvent("315", _LIVELIHOOD, 7, _NON_STATUTORY),
  79. FestivalEvent("高考", _LIVELIHOOD, 10, _NON_STATUTORY),
  80. FestivalEvent("三伏", _WEATHER, 15, _NON_STATUTORY),
  81. FestivalEvent("数九", _WEATHER, 5, _NON_STATUTORY),
  82. )
  83. def festival_events_payload() -> list[dict[str, int | str]]:
  84. return [
  85. {
  86. "name": event.name,
  87. "event_type": event.event_type,
  88. "prewarm_days": event.prewarm_days,
  89. "kind": event.kind,
  90. }
  91. for event in DEFAULT_FESTIVAL_EVENTS
  92. ]