diff --git a/astrbot/core/cron/manager.py b/astrbot/core/cron/manager.py index 5b2c6ee9e..aa11bb601 100644 --- a/astrbot/core/cron/manager.py +++ b/astrbot/core/cron/manager.py @@ -196,7 +196,9 @@ class CronJobManager: def _get_next_run_time(self, job_id: str): aps_job = self.scheduler.get_job(job_id) - return aps_job.next_run_time if aps_job else None + if not aps_job or aps_job.next_run_time is None: + return None + return aps_job.next_run_time.astimezone(timezone.utc) async def _run_job(self, job_id: str) -> None: job = await self.db.get_cron_job(job_id) diff --git a/astrbot/dashboard/routes/cron.py b/astrbot/dashboard/routes/cron.py index af26c6525..8417c970c 100644 --- a/astrbot/dashboard/routes/cron.py +++ b/astrbot/dashboard/routes/cron.py @@ -1,5 +1,5 @@ import traceback -from datetime import datetime +from datetime import datetime, timezone from quart import jsonify, request @@ -26,8 +26,12 @@ class CronRoute(Route): def _serialize_job(self, job) -> dict: data = job.model_dump() if hasattr(job, "model_dump") else job.__dict__ for k in ["created_at", "updated_at", "last_run_at", "next_run_time"]: - if isinstance(data.get(k), datetime): - data[k] = data[k].isoformat() + v = data.get(k) + if isinstance(v, datetime): + # Attach UTC + if v.tzinfo is None: + v = v.replace(tzinfo=timezone.utc) + data[k] = v.isoformat() # expose note explicitly for UI (prefer payload.note then description) payload = data.get("payload") or {} data["note"] = payload.get("note") or data.get("description") or ""