fix(cron): preserve exact intervals in list output

This commit is contained in:
Xubin Ren
2026-03-18 04:30:10 +00:00
committed by Xubin Ren
parent 12aa7d7aca
commit 5bd1c9ab8f
2 changed files with 41 additions and 9 deletions

View File

@@ -151,12 +151,14 @@ class CronTool(Tool):
tz = f" ({schedule.tz})" if schedule.tz else ""
return f"cron: {schedule.expr}{tz}"
if schedule.kind == "every" and schedule.every_ms:
secs = schedule.every_ms // 1000
if secs >= 3600:
return f"every {secs // 3600}h"
if secs >= 60:
return f"every {secs // 60}m"
return f"every {secs}s"
ms = schedule.every_ms
if ms % 3_600_000 == 0:
return f"every {ms // 3_600_000}h"
if ms % 60_000 == 0:
return f"every {ms // 60_000}m"
if ms % 1000 == 0:
return f"every {ms // 1000}s"
return f"every {ms}ms"
if schedule.kind == "at" and schedule.at_ms:
dt = datetime.fromtimestamp(schedule.at_ms / 1000, tz=timezone.utc)
return f"at {dt.isoformat()}"
@@ -184,8 +186,7 @@ class CronTool(Tool):
lines = []
for j in jobs:
timing = self._format_timing(j.schedule)
status = "enabled" if j.enabled else "disabled"
parts = [f"- {j.name} (id: {j.id}, {timing}, {status})"]
parts = [f"- {j.name} (id: {j.id}, {timing})"]
parts.extend(self._format_state(j.state))
lines.append("\n".join(parts))
return "Scheduled jobs:\n" + "\n".join(lines)

View File

@@ -38,6 +38,16 @@ def test_format_timing_every_seconds() -> None:
assert CronTool._format_timing(s) == "every 30s"
def test_format_timing_every_non_minute_seconds() -> None:
s = CronSchedule(kind="every", every_ms=90_000)
assert CronTool._format_timing(s) == "every 90s"
def test_format_timing_every_milliseconds() -> None:
s = CronSchedule(kind="every", every_ms=200)
assert CronTool._format_timing(s) == "every 200ms"
def test_format_timing_at() -> None:
s = CronSchedule(kind="at", at_ms=1773684000000)
result = CronTool._format_timing(s)
@@ -113,7 +123,6 @@ def test_list_cron_job_shows_expression_and_timezone(tmp_path) -> None:
)
result = tool._list_jobs()
assert "cron: 0 9 * * 1-5 (America/Denver)" in result
assert "enabled" in result
def test_list_every_job_shows_human_interval(tmp_path) -> None:
@@ -149,6 +158,28 @@ def test_list_every_job_seconds(tmp_path) -> None:
assert "every 30s" in result
def test_list_every_job_non_minute_seconds(tmp_path) -> None:
tool = _make_tool(tmp_path)
tool._cron.add_job(
name="Ninety-second check",
schedule=CronSchedule(kind="every", every_ms=90_000),
message="check",
)
result = tool._list_jobs()
assert "every 90s" in result
def test_list_every_job_milliseconds(tmp_path) -> None:
tool = _make_tool(tmp_path)
tool._cron.add_job(
name="Sub-second check",
schedule=CronSchedule(kind="every", every_ms=200),
message="check",
)
result = tool._list_jobs()
assert "every 200ms" in result
def test_list_at_job_shows_iso_timestamp(tmp_path) -> None:
tool = _make_tool(tmp_path)
tool._cron.add_job(