Ver Fonte

修改定时任务时间

xueyiming há 1 mês atrás
pai
commit
cb9ff2e37f
1 ficheiros alterados com 14 adições e 7 exclusões
  1. 14 7
      examples/demand/web_api.py

+ 14 - 7
examples/demand/web_api.py

@@ -9,6 +9,7 @@ import sys
 from datetime import datetime, timedelta
 from datetime import datetime, timedelta
 from pathlib import Path
 from pathlib import Path
 from typing import Any, Literal, Optional
 from typing import Any, Literal, Optional
+from zoneinfo import ZoneInfo
 
 
 from fastapi import FastAPI, HTTPException
 from fastapi import FastAPI, HTTPException
 from pydantic import BaseModel
 from pydantic import BaseModel
@@ -51,10 +52,13 @@ DEMAND_SCHEDULER_ENABLED: bool = os.getenv("DEMAND_SCHEDULER_ENABLED", "1").stri
 
 
 DEMAND_SCHEDULER_START_HOUR: int = 2
 DEMAND_SCHEDULER_START_HOUR: int = 2
 
 
+# 定时任务统一使用北京时间,避免服务器时区(如 UTC)带来的偏差
+BEIJING_TZ = ZoneInfo("Asia/Shanghai")
+
 
 
 def _get_today_time_window(now: datetime) -> tuple[datetime, datetime]:
 def _get_today_time_window(now: datetime) -> tuple[datetime, datetime]:
     """返回今天的 [start, end) 时间窗口(本地时区)。"""
     """返回今天的 [start, end) 时间窗口(本地时区)。"""
-    start_of_today = datetime(year=now.year, month=now.month, day=now.day)
+    start_of_today = datetime(year=now.year, month=now.month, day=now.day, tzinfo=now.tzinfo)
     end_of_today = start_of_today + timedelta(days=1)
     end_of_today = start_of_today + timedelta(days=1)
     return start_of_today, end_of_today
     return start_of_today, end_of_today
 
 
@@ -99,6 +103,9 @@ def _today_has_status_0_or_1(cluster_name: str, platform_type: str, now: datetim
     - 若存在 status 为 0 或 1 的记录,则跳过
     - 若存在 status 为 0 或 1 的记录,则跳过
     """
     """
     start_of_today, end_of_today = _get_today_time_window(now)
     start_of_today, end_of_today = _get_today_time_window(now)
+    # MySQL DATETIME 一般按无时区存储,这里使用北京时间对应的“本地时间”窗口做过滤
+    start_of_today_naive = start_of_today.replace(tzinfo=None)
+    end_of_today_naive = end_of_today.replace(tzinfo=None)
     return mysql_db.exists(
     return mysql_db.exists(
         "demand_task",
         "demand_task",
         where=(
         where=(
@@ -111,8 +118,8 @@ def _today_has_status_0_or_1(cluster_name: str, platform_type: str, now: datetim
         where_params=(
         where_params=(
             str(cluster_name)[:32],
             str(cluster_name)[:32],
             str(platform_type)[:32],
             str(platform_type)[:32],
-            start_of_today,
-            end_of_today,
+            start_of_today_naive,
+            end_of_today_naive,
         ),
         ),
     )
     )
 
 
@@ -126,7 +133,7 @@ async def demand_scheduled_run_once() -> None:
     if not DEMAND_SCHEDULE_CLUSTER_PLATFORM_LIST:
     if not DEMAND_SCHEDULE_CLUSTER_PLATFORM_LIST:
         return
         return
 
 
-    now = datetime.now()
+    now = datetime.now(BEIJING_TZ)
     for item in DEMAND_SCHEDULE_CLUSTER_PLATFORM_LIST:
     for item in DEMAND_SCHEDULE_CLUSTER_PLATFORM_LIST:
         cluster_name = item.get("cluster_name")
         cluster_name = item.get("cluster_name")
         platform_type = item.get("platform_type")
         platform_type = item.get("platform_type")
@@ -204,11 +211,11 @@ async def _start_demand_scheduler() -> None:
         print("[scheduler] apscheduler 未安装,跳过定时任务启动")
         print("[scheduler] apscheduler 未安装,跳过定时任务启动")
         return
         return
 
 
-    scheduler = AsyncIOScheduler()
+    scheduler = AsyncIOScheduler(timezone=BEIJING_TZ)
     # 02:00 - 23:30:每 30 分钟一次
     # 02:00 - 23:30:每 30 分钟一次
     scheduler.add_job(
     scheduler.add_job(
         func=_demand_scheduler_job,
         func=_demand_scheduler_job,
-        trigger=CronTrigger(hour=f"{DEMAND_SCHEDULER_START_HOUR}-23", minute="0,30"),
+        trigger=CronTrigger(hour=f"{DEMAND_SCHEDULER_START_HOUR}-23", minute="0,30", timezone=BEIJING_TZ),
         id="demand_scheduler_job_main",
         id="demand_scheduler_job_main",
         replace_existing=True,
         replace_existing=True,
         max_instances=1,
         max_instances=1,
@@ -217,7 +224,7 @@ async def _start_demand_scheduler() -> None:
     # 24:00(即下一天 00:00):每天一次
     # 24:00(即下一天 00:00):每天一次
     scheduler.add_job(
     scheduler.add_job(
         func=_demand_scheduler_job,
         func=_demand_scheduler_job,
-        trigger=CronTrigger(hour="0", minute="0"),
+        trigger=CronTrigger(hour="0", minute="0", timezone=BEIJING_TZ),
         id="demand_scheduler_job_midnight",
         id="demand_scheduler_job_midnight",
         replace_existing=True,
         replace_existing=True,
         max_instances=1,
         max_instances=1,