Skip to content

Standardize all output timestamps to ISO 8601#243

Open
umair-ably wants to merge 1 commit intomainfrom
fixTimestamps
Open

Standardize all output timestamps to ISO 8601#243
umair-ably wants to merge 1 commit intomainfrom
fixTimestamps

Conversation

@umair-ably
Copy link
Copy Markdown
Collaborator

Summary

  • Human-readable output: Control API commands (apps, keys, integrations, channel rules) were using toLocaleString() for timestamps, producing locale-dependent formats (e.g., 3/31/2026, 12:00:00 PM in the US, 31/3/2026 elsewhere). This was ambiguous — D/M/Y vs M/D/Y depends on the user's system locale. Now all human-readable timestamps use ISO 8601 (2022-01-01T00:00:00.000Z), matching what data-plane commands (channels, rooms, logs) already used.
  • JSON output: Several commands leaked raw epoch milliseconds in --json output by spreading SDK/API objects without converting timestamps. Other commands already converted to ISO strings, creating inconsistency. Now all JSON timestamp fields are ISO 8601 strings.
  • Input unchanged: --start and --end flags still accept ISO 8601, Unix milliseconds, and relative formats (1h, 30m, 2d).

Why

Two formats in one CLI is confusing for users and breaks scripting assumptions. The D/M/Y vs M/D/Y ambiguity in toLocaleString() meant the same command could produce different output on different machines. For JSON consumers, mixing epoch millis and ISO strings meant parsers had to handle both formats depending on which command they called.

ISO 8601 is unambiguous, machine-parseable, and already what most of our commands used — this change makes the rest consistent.

What changed

Core fixControlBaseCommand.formatDate() changed from toLocaleString() to toISOString(). This single-line change fixes human-readable output for 12+ commands.

JSON output fixes — Added ISO conversion for timestamps leaking as epoch millis via object spreads in:

  • apps list, auth keys create/get/list
  • channels history
  • integrations create/get/update

Tests — Added ISO 8601 format assertions to 9 test files, and added missing created/modified mock data where needed.

Out of scopestats-display.ts intentionally shows local time alongside UTC in the live dashboard for wall-clock correlation. That's a different use case and left as-is.

Test plan

  • pnpm prepare builds successfully
  • pnpm exec eslint . — 0 errors
  • pnpm test:unit — 2197 passed, 0 failed
  • New ISO format assertions verify both JSON and human-readable output

🤖 Generated with Claude Code

@vercel
Copy link
Copy Markdown

vercel bot commented Mar 31, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
cli-web-cli Ready Ready Preview, Comment Mar 31, 2026 1:52pm

Request Review

@claude-code-ably-assistant
Copy link
Copy Markdown

Walkthrough

This PR standardizes all CLI output timestamps to ISO 8601 format. Control API commands (apps, keys, integrations, channel rules) were using toLocaleString(), which produces locale-dependent output (e.g., 3/31/2026 in the US vs 31/3/2026 elsewhere). JSON output from several commands was also leaking raw epoch milliseconds. Both are now consistently ISO 8601 strings, matching what data-plane commands already used.

Changes

Area Files Summary
Commands src/commands/apps/list.ts, src/commands/auth/keys/create.ts, src/commands/auth/keys/get.ts, src/commands/auth/keys/list.ts Convert timestamp fields to ISO strings in JSON output instead of spreading raw API objects
Commands src/commands/channels/history.ts Convert timestamp field to ISO string in JSON output
Commands src/commands/integrations/create.ts, src/commands/integrations/get.ts, src/commands/integrations/update.ts Convert created/modified epoch ms fields to ISO strings in JSON output
Base Class src/control-base-command.ts Change formatDate() from toLocaleString() to toISOString() — fixes human-readable timestamps for all 12+ Control API commands in one line
Tests test/unit/commands/apps/, test/unit/commands/auth/keys/, test/unit/commands/channels/history.test.ts Add ISO 8601 format assertions; add missing created/modified mock data
Tests test/unit/commands/integrations/create.test.ts, get.test.ts, update.test.ts Add ISO format assertions for integration timestamp fields

Review Notes

  • Behavioral change: Human-readable output format changes from locale-dependent (e.g., 3/31/2026, 12:00:00 PM) to ISO 8601 (e.g., 2026-03-31T12:00:00.000Z) for all Control API commands. This is intentional but visible to users.
  • JSON output change: Commands that previously emitted epoch milliseconds in --json output now emit ISO strings. Any scripts/integrations parsing these fields will see a format change.
  • Core fix is minimal: The control-base-command.ts change is a single-line swap (toLocaleString()toISOString()), low risk.
  • Out of scope: stats-display.ts deliberately retains local time for wall-clock correlation in the live dashboard — not changed.
  • No new dependencies.

Copy link
Copy Markdown

@claude-code-ably-assistant claude-code-ably-assistant bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Summary

This PR is a focused, clean consistency fix. The changes are correct and well-scoped.

What was checked

  • src/control-base-command.tsformatDate() change from toLocaleString() to toISOString()
  • All 7 command files with JSON timestamp conversions
  • Timestamp types in src/services/control-api.ts (confirmed created/modified are number, not optional — no null-safety concern)
  • buildPaginationNext in channels/history.ts — correctly uses raw numeric timestamp before conversion; buildPaginationNext already converts it to ISO internally
  • All remaining commands checked for un-converted timestamps in JSON paths — none found

One minor test observation

Several test files use the regex /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z$/ where the . between seconds and milliseconds is unescaped (should be \.). This will match any character in that position. It won't cause false positives in practice, but worth tightening if passing through this area again. The apps/list.test.ts change uses exact toBe() comparison which is strictly correct.

This doesn't warrant a change request.

Overall

The fix is correct. The formatDate() single-line change handles human-readable output for 12+ commands, and the per-command JSON path changes handle spread cases where raw epoch ms would have leaked through. No architectural concerns, no error handling gaps, no missed commands. Approved.

@sacOO7
Copy link
Copy Markdown
Contributor

sacOO7 commented Mar 31, 2026

Seems, ISO timestamp is well addressed across all commands. Only few inconsistencies found for spaces

  1. src/utils/spaces-output.tsMemberOutput.lastEvent.timestamp (raw epoch number)
  2. src/utils/spaces-output.tsLockOutput.timestamp (raw epoch number)
  3. src/commands/rooms/messages/history.ts:168 — raw message.timestamp (Date object)
  4. src/commands/rooms/messages/subscribe.ts:103 — raw message.timestamp (Date object)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants