Skip to content

fix: use local dates for CLI date-only values#1361

Merged
TabishB merged 3 commits into
Fission-AI:mainfrom
showms:codex/fix-cli-local-date-semantics
Jul 18, 2026
Merged

fix: use local dates for CLI date-only values#1361
TabishB merged 3 commits into
Fission-AI:mainfrom
showms:codex/fix-cli-local-date-semantics

Conversation

@showms

@showms showms commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Summary

Fix CLI-generated date-only values so they use the effective local time zone of the Node.js process instead of truncating a UTC ISO timestamp.

This affects:

  • archive directory prefixes
  • the created field in newly generated .openspec.yaml metadata

Problem

Both code paths previously generated YYYY-MM-DD with:

new Date().toISOString().split('T')[0]

toISOString() converts the current instant to UTC before the date is extracted. Around local midnight, this can produce a different calendar date from the one observed by the user running the CLI.

For example:

Time zone Current local time UTC instant Previous result
Asia/Shanghai 2026-07-15 00:30 2026-07-14T16:30:00Z 2026-07-14

As a result:

  • a newly created change could record created: 2026-07-14 on local date 2026-07-15
  • an archive created on local date 2026-07-15 could be named 2026-07-14-<change-name>

These are date-only values intended to represent the CLI process's local calendar date, not UTC timestamps.

Changes

  • Add a shared formatLocalDate() utility.
  • Build YYYY-MM-DD from local Date accessors with zero-padding.
  • Use the formatter for archive directory prefixes.
  • Use the formatter for new-change created metadata.
  • Update archive collision test expectations to follow the same local-date rule.
  • Add deterministic regression coverage for both affected CLI paths:
    • a UTC/local date boundary where UTC is 2026-07-14 and the Asia/Shanghai local date is 2026-07-15
    • a non-boundary instant where UTC and local calendar dates are both 2026-01-05
  • Verify zero-padding through the 2026-01-05 expectations.
  • Restore both the fake clock and process time zone after each test.

Scope

This change only affects date-only values generated programmatically by the CLI.

It does not:

  • change full UTC timestamps used elsewhere
  • rename existing archives
  • migrate existing change metadata
  • add a configurable project time zone
  • modify OPSX archive workflows, where the agent constructs the date directly and does not use Date#toISOString()

Validation

  • pnpm run build
  • pnpm exec vitest run test/core/archive.test.ts test/utils/change-utils.test.ts
    • 58 tests passed
  • openspec validate fix-cli-local-date-semantics --strict

Summary by CodeRabbit

  • Bug Fixes
    • Archive folder names now use the executing environment’s local YYYY-MM-DD calendar date (timezone-aware).
    • Newly created change metadata now records created using the local calendar date, including when UTC and local dates differ.
    • Existing archives and previously generated metadata are left unchanged.
  • Tests
    • Added deterministic timezone-aware test coverage for archive naming and created metadata across UTC/local boundaries and when dates match.

@showms
showms requested a review from TabishB as a code owner July 15, 2026 14:06
@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: fba1f2ab-2938-48d5-a8b6-512d25f3c923

📥 Commits

Reviewing files that changed from the base of the PR and between ac54ec4 and 6757c66.

📒 Files selected for processing (2)
  • src/core/archive.ts
  • test/core/archive.test.ts

📝 Walkthrough

Walkthrough

The CLI now formats date-only values from the Node.js process’s local calendar date. Archive directory prefixes and newly created change metadata use the shared formatter, with timezone-boundary regression tests and updated OpenSpec documentation.

Changes

Local CLI date semantics

Layer / File(s) Summary
Local date contract
openspec/changes/fix-cli-local-date-semantics/*
Defines local YYYY-MM-DD behavior for archive names and newly created change metadata, including boundary scenarios and implementation tasks.
Shared formatter integration
src/utils/date.ts, src/core/archive.ts, src/utils/change-utils.ts
Adds formatLocalDate() and uses it for archive directory names and the created field in new .openspec.yaml files.
Timezone boundary regression coverage
test/core/archive.test.ts, test/utils/change-utils.test.ts
Adds deterministic local-date tests using fixed timers and temporary TZ values, with cleanup restoring timers and environment state.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ArchiveCommand
  participant formatLocalDate
  participant ArchiveDirectory
  participant createChange
  participant ChangeMetadata
  ArchiveCommand->>formatLocalDate: Format local calendar date
  formatLocalDate-->>ArchiveCommand: Return YYYY-MM-DD
  ArchiveCommand->>ArchiveDirectory: Create dated archive path
  createChange->>formatLocalDate: Format local calendar date
  formatLocalDate-->>createChange: Return YYYY-MM-DD
  createChange->>ChangeMetadata: Write created field
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly states the main change: switching CLI date-only values to local dates.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
src/utils/date.ts (1)

7-13: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider zero-padding the year to 4 digits.

While current years naturally resolve to 4 digits, explicitly zero-padding the year to 4 digits adheres strictly to the YYYY-MM-DD specification format and builds resilience against edge cases involving smaller year values.

💡 Proposed refactor
 export function formatLocalDate(date: Date = new Date()): string {
-  const year = date.getFullYear();
+  const year = String(date.getFullYear()).padStart(4, '0');
   const month = String(date.getMonth() + 1).padStart(2, '0');
   const day = String(date.getDate()).padStart(2, '0');
 
   return `${year}-${month}-${day}`;
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/utils/date.ts` around lines 7 - 13, Update formatLocalDate to explicitly
zero-pad the computed year to four digits before constructing the YYYY-MM-DD
result, while preserving the existing month and day formatting.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/utils/date.ts`:
- Around line 7-13: Update formatLocalDate to explicitly zero-pad the computed
year to four digits before constructing the YYYY-MM-DD result, while preserving
the existing month and day formatting.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 06fb29e9-b400-458c-89b1-b2dfbcca4a7c

📥 Commits

Reviewing files that changed from the base of the PR and between 0a99f41 and ac54ec4.

📒 Files selected for processing (11)
  • openspec/changes/fix-cli-local-date-semantics/.openspec.yaml
  • openspec/changes/fix-cli-local-date-semantics/design.md
  • openspec/changes/fix-cli-local-date-semantics/proposal.md
  • openspec/changes/fix-cli-local-date-semantics/specs/change-creation/spec.md
  • openspec/changes/fix-cli-local-date-semantics/specs/cli-archive/spec.md
  • openspec/changes/fix-cli-local-date-semantics/tasks.md
  • src/core/archive.ts
  • src/utils/change-utils.ts
  • src/utils/date.ts
  • test/core/archive.test.ts
  • test/utils/change-utils.test.ts

@showms showms closed this Jul 16, 2026
@showms showms reopened this Jul 17, 2026
@TabishB
TabishB added this pull request to the merge queue Jul 18, 2026
Merged via the queue into Fission-AI:main with commit 9acddcd Jul 18, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants