← Back to PRs

#15784: fix: timestamp parsing should convert seconds to milliseconds

by murasame-desu-ai open 2026-02-13 21:50 View on GitHub →
stale size: S
## Summary Fixes #15724 This PR fixes a critical bug in `parseAbsoluteTimeMs()` where Unix timestamps (seconds) were incorrectly treated as milliseconds, causing timestamps to be off by 1000x. ## Root Cause The `parseAbsoluteTimeMs()` function is supposed to return milliseconds (as its name indicates), but when the input is a pure numeric string (Unix timestamp in seconds), it was returned as-is without conversion. **Example:** - Input: `1771005600` (2026-02-13 18:00:00 UTC in seconds) - Expected: `1771005600000` ms → 2026-02-13 - Actual (before fix): `1771005600` ms → 1970-01-21 ❌ ## Solution Convert numeric input by multiplying by 1000 to convert seconds to milliseconds: ```typescript // Before return Math.floor(n); // After return Math.floor(n * 1000); // Convert Unix timestamp (seconds) to milliseconds ``` ISO 8601 strings already work correctly because `Date.parse()` returns milliseconds. ## Testing Added comprehensive test suite in `src/cron/parse.test.ts`: - ✅ Unix timestamp conversion (seconds → milliseconds) - ✅ ISO 8601 formats (full, date-only, with/without timezone) - ✅ Edge cases (empty, whitespace, negative, zero, very large numbers) - ✅ Regression test for issue #15724 **Key test:** ```typescript const unixSeconds = 1771005600; // 2026-02-13T18:00:00.000Z const result = parseAbsoluteTimeMs(String(unixSeconds)); expect(result).toBe(1771005600000); // Milliseconds expect(new Date(result!).toISOString()).toBe("2026-02-13T18:00:00.000Z"); ``` ## Impact **Fixed:** - Absolute timestamp scheduling with `--at` now works correctly for Unix timestamps **Unaffected:** - Relative scheduling (`--every`, `--interval`) continues to work - ISO 8601 format continues to work (was already correct) ## Breaking Change ⚠️ **Potential breaking change:** If anyone was passing milliseconds as numeric strings (undocumented behavior), they need to either: - Use ISO 8601 format instead (recommended) - Divide their input by 1000 to convert to seconds However, this was never documented, and the function name clearly indicates it expects/returns milliseconds. ## Checklist - [x] Bug fix (non-breaking change which fixes an issue) - [x] Tests added/updated - [ ] Documentation updated (if needed) - [x] Related issue linked (#15724) <!-- greptile_comment --> <h2>Greptile Overview</h2> <h3>Greptile Summary</h3> This change updates `parseAbsoluteTimeMs()` to treat purely numeric inputs as Unix timestamps in **seconds** and convert them to milliseconds (`n * 1000`). A new Vitest suite (`src/cron/parse.test.ts`) covers Unix timestamps, ISO-8601 variants, trimming/invalid inputs, and a regression for #15724. `parseAbsoluteTimeMs()` is used throughout the cron CLI and cron schedule normalization/validation paths, so this fix directly affects `--at` absolute scheduling and any schedule fields that flow through that parser. <h3>Confidence Score: 4/5</h3> - This PR looks safe to merge with one user-facing validation message inconsistency to fix. - The parsing change is small and well-targeted, and the added tests align with the new behavior. The main issue found is an existing validation error message that now contradicts the accepted input formats (ISO-only wording), which can mislead users but does not break runtime behavior. - src/cron/validate-timestamp.ts (error message wording vs accepted formats) <sub>Last reviewed commit: 5935d40</sub> <!-- greptile_other_comments_section --> <sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub> <!-- /greptile_comment -->

Most Similar PRs