time_plan.py 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  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. if self.weekdays_ is not None and now.weekday() not in self.weekdays_:
  34. return False
  35. # 月日期匹配
  36. if self.month_days_ is not None and now.day not in self.month_days_:
  37. return False
  38. # 时间匹配
  39. now_t = now.time()
  40. for period in self.time_range_:
  41. try:
  42. start_t = datetime.strptime(period["start_time"], "%H:%M").time()
  43. end_t = datetime.strptime(period["end_time"], "%H:%M").time()
  44. except ValueError:
  45. LOGDBG("time_range_ invalid format, pass")
  46. continue
  47. if start_t <= end_t:
  48. # 正常区间 (不跨零点)
  49. if start_t <= now_t <= end_t:
  50. return True
  51. else:
  52. # 跨零点区间,例如 22:00 → 16:00
  53. if now_t >= start_t or now_t <= end_t:
  54. return True
  55. # 时间匹配
  56. now_t = now.time()
  57. for period in self.time_range_:
  58. start_t = datetime.strptime(period["start_time"], "%H:%M").time()
  59. end_t = datetime.strptime(period["end_time"], "%H:%M").time()
  60. if start_t <= now_t <= end_t:
  61. return True
  62. return False
  63. def example(self) -> bool:
  64. if self.is_active_now():
  65. return True
  66. else:
  67. return False