time_plan.py 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. from typing import List, Tuple, Optional
  2. from datetime import datetime, time, date
  3. from threading import Thread, Lock
  4. from enum import Enum
  5. from common.sys_comm import (
  6. LOGDBG, LOGINFO, LOGWARN, LOGERR,
  7. get_utc_time_ms
  8. )
  9. # 时间计划
  10. class TimePlan:
  11. def __init__(self,
  12. time_range: list,
  13. start_date: str,
  14. stop_date: str,
  15. weekdays: Optional[List[int]] = None,
  16. month_days: Optional[List[int]] = None
  17. ):
  18. self.start_date_ = start_date # 开始日期
  19. self.stop_date_ = stop_date # 结束日期
  20. self.time_range_ = time_range # 生效时间
  21. # [{"start_time": "00:00","end_time": "12:00"},{"start_time": "18:00","end_time": "23:59"}, ...]
  22. self.month_days_ = month_days # 每月的生效日期
  23. self.weekdays_ = weekdays # 每周的生效日期
  24. def is_active_now(self, now: Optional[datetime] = None) -> bool:
  25. now = now or datetime.now()
  26. # 起止日期匹配
  27. try:
  28. if not (self.start_date_ <= now.strftime("%Y-%m-%d") <= self.stop_date_):
  29. return False
  30. except ValueError:
  31. return False
  32. # 周日期匹配
  33. match_weekdays: bool = False
  34. if self.weekdays_ is not None and (now.weekday()+1) in self.weekdays_:
  35. match_weekdays = True
  36. # 月日期匹配
  37. match_monthdays: bool = False
  38. if self.month_days_ is not None and now.day in self.month_days_:
  39. match_monthdays = True
  40. if not (match_weekdays or match_monthdays):
  41. return False
  42. # 时间匹配
  43. now_t = now.time()
  44. for period in self.time_range_:
  45. try:
  46. start_t = datetime.strptime(period["start_time"], "%H:%M").time()
  47. end_t = datetime.strptime(period["end_time"], "%H:%M").time()
  48. except ValueError:
  49. LOGDBG("time_range_ invalid format, pass")
  50. continue
  51. if start_t <= end_t:
  52. # 正常区间 (不跨零点)
  53. if start_t <= now_t <= end_t:
  54. return True
  55. else:
  56. # 跨零点区间,例如 22:00 → 16:00
  57. if now_t >= start_t or now_t <= end_t:
  58. return True
  59. # 时间匹配
  60. now_t = now.time()
  61. for period in self.time_range_:
  62. start_t = datetime.strptime(period["start_time"], "%H:%M").time()
  63. end_t = datetime.strptime(period["end_time"], "%H:%M").time()
  64. if start_t <= now_t <= end_t:
  65. return True
  66. return False
  67. def example(self) -> bool:
  68. if self.is_active_now():
  69. return True
  70. else:
  71. return False