apache / apache/rocketmq-dashboard
[Studio][Bug] Alert rule 最近触发时间 renders the UTC timestamp as browser-local time
- Dominant language
- Java
- Stars
- 1.4k
- Forks
- 683
- Avg merge
- 2d 14h
- Merged PRs (30d)
- 58
Description
**Problem**
On `/ops/alerts` (and `/ops/business-alerts`), the **最近触发时间** column for a fired rule shows the UTC clock value as if it were the viewer's local wall clock.
**Evidence**
The backend stamps `lastTriggered` with `ZoneOffset.UTC` and no offset suffix:
- `NativeAlertProcessor.java:143` — `LocalDateTime eventTime = LocalDateTime.ofInstant(collectedAt, ZoneOffset.UTC);`
- `NativeAlertProcessor.java:165` — `alertRepository.markRuleTriggered(rule.getId(), eventTime.toString());` writes e.g. `2026-08-23T23:30:00` into `rmq_alert_rule.last_triggered` (`NativeAlertEvaluationService.java:92` does the same).
The rule page then renders it with `formatDateTime` (`web/src/pages/ops/alerts.tsx:699`), which parses offset-less ISO strings with `new Date(...)`, i.e. as **browser-local** time (`web/src/utils/format.ts`). A rule that fired at 23:30 UTC renders as 23:30 in every timezone, and a UTC+8 browser shows a "last triggered" up to 8 hours in the future of the actual event.
The sibling system-alert page already handles this correctly: `web/src/pages/ops/systemAlerts.tsx` renders `alert.time`/`acknowledgedAt` (same offset-less UTC `LocalDateTime` serialization) via `formatUtcDateTime`, and `formatUtcDateTime` documents the exact contract: "Alert APIs serialize UTC LocalDateTime values without an offset, so normal Date parsing would incorrectly treat them as browser-local timestamps."
**Impact**
- Wrong wall-clock display of the last trigger time on every non-UTC browser (the dashboard's primary audience uses UTC+8).
- The header counter `近24小时触发` (`alerts.tsx:406-408`, `new Date(r.lastTriggered).getTime() > dayAgo`) computes the 24h window in mixed timezones, so freshly fired rules can be counted as older than 24h (or future timestamps inflate the count).
**Expected behavior**
`lastTriggered` is parsed as UTC and rendered in the viewer's timezone, matching the system alerts page.
**Related work**
- #3995 covers audit-log timestamps (different page/backend, same offset-less-UTC family).
- #2763 (closed) fixed padding normalization inside the same `formatUtcDateTime` utility — a distinct defect from the local-vs-UTC interpretation covered here.
- PR #3770 is a feature (notification deliveries export), unrelated.
**PR**
Fix: #4175
Contributor guide
No contributing guide indexed for this repository
Research direction
Review web/src/pages/ops/alerts.tsx around lines 406-408 and 699, then compare web/src/utils/format.ts and web/src/pages/ops/systemAlerts.tsx. Verify that lastTriggered is interpreted as UTC for display and for the 24-hour counter, with behavior matching the system-alert page; PR #4175 is already referenced as the fix.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, typescript
- Domain
- backend, frontend
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 20/100