Skip to content

Clock Strategies — Overview ​

Every strategy produces the same ITimeProvider<TDate> shape — only how clock.utcNow()/clock.localNow() computes "now", and whether the provider's timers fire synchronously, changes. System comes from createTimeProvider.for(plugin) in @time-provider/core; Fixed, Manual, and Sequential come from the same call in @time-provider/core/deterministic — see Mental Model for why they're split.

Strategy"now" comes fromTimers fireTypical use
Systemthe real system clockasynchronously, via real native timersProduction
Fixeda single instant, forevernever (time never advances)Deterministic single-instant tests
Manualthe last value set via moveBy()synchronously, in-line, when advanced dueSimulations, timer/retry logic tests
Sequentialthe next instant in a predefined listsynchronously, in-line, as instants are consumedTests asserting on changing timestamps
ts
// production
import { createTimeProvider } from "@time-provider/core";
import { plugin } from "@time-provider/plugin-native";

createTimeProvider.for(plugin).create(); // system (the only strategy this entry point builds)
ts
// tests
import { createTimeProvider } from "@time-provider/core/deterministic";
import { plugin } from "@time-provider/plugin-native/deterministic";

createTimeProvider.for(plugin).asFixed().withFixedTime("2026-01-01T00:00Z").create();
createTimeProvider.for(plugin).asManual().withInitialTime("2026-01-01T00:00Z").create();
createTimeProvider
  .for(plugin)
  .asSequential()
  .withSequentialTime("2026-01-01T00:01Z")
  .withSequentialTime("2026-01-01T00:02Z")
  .create();

Every builder (including the system one) accepts .withTimezone(tz) / .withHostTimezone() / .withDefaultTimezone() before .create(), for plugins whose date library supports real local time — see Timezones & Local Time.

Play with each strategy interactively in the Playground.