Control the clock in tests through an injectable time source so "now" is frozen and timezone behavior is explicit. Use when code reads the wall clock and a flaky or time-dependent test needs deterministic results.
Scanned 9/5/2026
Install to Claude Code
npx -y skills add Amey-Thakur/AI-SKILLS --skill mocking-time --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Mocking Time?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/amey-thakur-mocking-time)More formats (shields.io, HTML) on the badges page.
---
name: mocking-time
description: Control the clock in tests through an injectable time source so "now" is frozen and timezone behavior is explicit. Use when code reads the wall clock and a flaky or time-dependent test needs deterministic results.
---
# Mocking time
Code that calls `Date.now()`, `time.time()`, or `datetime.now()` directly
reads a value that changes every run, so any test over it is a coin flip near
a boundary and silently wrong across a daylight-saving shift. The fix is not
sprinkling sleeps or widening tolerances: it is making time an input you
control, then pinning it to the exact instant the test cares about.
## Method
1. **Inject the clock, never reach for the global.** Pass a time source into
the unit: a `Clock` interface, a `now: () -> datetime` callable, or a
constructor argument. Production wires the real clock, tests wire a fake.
A function that closes over the global module clock cannot be frozen from
the outside.
2. **Freeze now with a purpose-built library.** Use freezegun
(`@freeze_time("2026-03-08T12:00:00Z")`), Sinon fake timers
(`sinon.useFakeTimers`), or `Clock.fixed(instant, zone)` on the JVM. Set
one explicit instant per test so the assertion reads against a literal you
can see, not "roughly today".
3. **Advance time on purpose, do not sleep.** For timeouts, retries, and
debounces, tick the fake forward (`clock.tick(30_000)`,
`frozen.move_to(...)`) and assert the effect fired. A real `sleep(30)`
makes the suite slow and still races; a controlled tick is instant and
exact.
4. **Store and compare in UTC, render in a zone.** Keep every persisted and
compared timestamp in UTC. Convert to a local zone only at display, and
assert on the UTC value so a test that passes in one CI region passes in
all of them.
5. **Pin real timezones for the cases that bite.** Test a US/Pacific spring
DST gap (a wall time of 02:30 that does not exist), a fall overlap (01:30
occurring twice), and a non-hour offset like Asia/Kolkata. Use named IANA
zones (`ZoneInfo("America/New_York")`), never a fixed `-05:00`, so the
rules travel with the data.
6. **Cover the ugly boundaries explicitly.** Add cases for midnight rollover,
month and year ends, February 29, and epoch-second overflow if you touch
32-bit time. These are where off-by-one date math surfaces.
## Litmus tests
- Grep the code under test for `now(`, `today(`, `Date.now`, `time.time`: any
hit that is not the injected source is a hole.
- Does the suite pass with the machine clock set to December 31, 23:59 and
again in a +13 timezone?
- Can you read the expected instant as a literal in each assertion?
## Boundaries
This covers making time deterministic in a test, not scheduling or cron
correctness in production, which needs its own integration coverage. Follow
the clock abstraction a project already has rather than introducing a second
one.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!