# Clock

Every notion of "now" and every delay in Effect flows through the `Clock`
service. Schedules, `Effect.sleep`, `Effect.timeout`, and retries all ask the
`Clock` what time it is and to wait — none of them touch `Date.now` or
`setTimeout` directly. That single indirection is what makes time in Effect
deterministic and testable: swap the live clock for a `TestClock` and you control
the passage of time exactly.

```ts
import { Clock, Effect } from "effect"

// Measure how long a piece of work takes, reading time from the Clock service.
const timed = Effect.gen(function* () {
  const start = yield* Clock.currentTimeMillis
  yield* doWork
  const end = yield* Clock.currentTimeMillis
  yield* Effect.log(`work took ${end - start}ms`)
})

declare const doWork: Effect.Effect<void>
```

`Clock.currentTimeMillis` and `Clock.currentTimeNanos` are effects that yield the
current time at millisecond or nanosecond precision. Reaching for `Date.now()`
would read the wall clock directly, bypassing the runtime and making the code
untestable — always read time through `Clock`. (For a richer, typed timestamp see
[DateTime](https://effect.plants.sh/data-types/datetime-and-duration/) and `DateTime.now`, which itself
reads the `Clock`.)

## Sleeping

`Effect.sleep` suspends the current fiber for a duration. It is interruptible and
implemented on top of the `Clock`, so it cooperates with concurrency and with the
`TestClock`:

```ts
import { Effect } from "effect"

const program = Effect.gen(function* () {
  yield* Effect.log("starting")
  yield* Effect.sleep("2 seconds") // accepts any Duration.Input
  yield* Effect.log("two seconds later")
})
```

Unlike a blocking `setTimeout`, a sleeping fiber consumes no thread and can be
interrupted — if the surrounding scope is cancelled mid-sleep, the wait ends
immediately. See [Concurrency](https://effect.plants.sh/concurrency/) for how fibers and interruption fit
together.

## Accessing the full service

The accessors above cover most needs. When you want the whole service — for
example to call the synchronous `currentTimeMillisUnsafe()` inside a tight,
already-effectful loop — read the `Clock` reference or use `Clock.clockWith`:

```ts
import { Clock, Effect } from "effect"

const program = Effect.gen(function* () {
  const clock = yield* Clock.Clock
  // Synchronous read; only valid because we already hold the service.
  return clock.currentTimeMillisUnsafe()
})
```

## Controlling time in tests

The real value of routing time through a service shows up in tests. With
`@effect/vitest`, `it.effect` runs your effect against a `TestClock` whose time
only advances when you tell it to. `TestClock.adjust` moves the clock forward and
runs anything scheduled to fire on or before the new time — so a five-second
sleep "completes" the instant you advance the clock five seconds, with no real
waiting.

```ts
import { assert, describe, it } from "@effect/vitest"
import { Effect, Ref } from "effect"
import { TestClock } from "effect/testing"

describe("polling", () => {
  it.effect("ticks once per interval", () =>
    Effect.gen(function* () {
      const ticks = yield* Ref.make(0)

      // Fork a worker that increments a counter every second, forever.
      yield* Ref.update(ticks, (n) => n + 1).pipe(
        Effect.delay("1 second"),
        Effect.forever,
        Effect.forkChild
      )

      // No real time passes — we drive the clock by hand.
      yield* TestClock.adjust("1 second")
      assert.strictEqual(yield* Ref.get(ticks), 1)

      yield* TestClock.adjust("3 seconds")
      assert.strictEqual(yield* Ref.get(ticks), 4)
    }))
})
```

The same technique verifies retry backoff, cron jobs, and timeouts in
microseconds rather than real wall-clock time. To advance to an absolute moment
instead of by a delta, use `TestClock.setTime(epochMillis)`.
**Fork before you adjust:** A worker that sleeps must be running on its own fiber *before* you call
  `TestClock.adjust`, or there will be nothing waiting for the clock to reach.
  Fork it with `Effect.forkChild`, then adjust the clock; the woken work runs
  before `adjust` returns.

`TestClock` is its own module with more (`make`, `layer`, `withLive`,
`testClockWith`); the page above is just the common case. For the full reference,
see [TestClock](https://effect.plants.sh/testing/testclock/).

## Reference

The `Clock` module is small: three effect-level accessors and the service itself.
Everything below imports from the core `effect` package.

### Clock.currentTimeMillis

An `Effect<number>` that succeeds with the current time in milliseconds since the
Unix epoch, read from the active `Clock`. This is the everyday way to ask "what
time is it?".

```ts
import { Clock, Effect } from "effect"

const program = Effect.gen(function* () {
  const ms = yield* Clock.currentTimeMillis
  return ms
  // => 1748563200000 (a Unix epoch timestamp in ms)
})
```

### Clock.currentTimeNanos

An `Effect<bigint>` that succeeds with the current time in nanoseconds. Use it
when millisecond resolution is too coarse — for high-precision benchmarking or
ordering events that happen within the same millisecond.

```ts
import { Clock, Effect } from "effect"

const program = Effect.gen(function* () {
  const ns = yield* Clock.currentTimeNanos
  return ns
  // => 1748563200000000000n (a bigint of nanoseconds)
})
```

### Clock.clockWith

`clockWith(f)` accesses the active `Clock` service and runs your function `f`
with it. Reach for it when you need the full interface — for example to call the
unsafe synchronous accessors — inside a single effect.

```ts
import { Clock, Effect } from "effect"

// A custom timed helper built directly on the Clock service.
const timeWith = <A, E, R>(self: Effect.Effect<A, E, R>) =>
  Clock.clockWith((clock) =>
    Effect.gen(function* () {
      const start = clock.currentTimeMillisUnsafe()
      const result = yield* self
      const elapsed = clock.currentTimeMillisUnsafe() - start
      return [result, elapsed] as const
    })
  )

const program = timeWith(Effect.succeed(42))
// => [42, 0]  (value paired with elapsed milliseconds)
```

### Clock.Clock

The service reference itself. `Clock` is a `Context.Reference`, so a live
implementation backed by the runtime's wall clock is always available — you never
have to provide it in production. Yield it to obtain the full service interface.

```ts
import { Clock, Effect } from "effect"

const program = Effect.gen(function* () {
  const clock = yield* Clock.Clock
  return clock.currentTimeMillisUnsafe()
  // => 1748563200000
})
```

The `Clock` interface has these members:

- **`currentTimeMillis: Effect<number>`** — current time in milliseconds, as an
  effect.
- **`currentTimeNanos: Effect<bigint>`** — current time in nanoseconds, as an
  effect.
- **`sleep(duration: Duration): Effect<void>`** — suspend for a `Duration`. (Note
  this takes a fully-constructed `Duration`; `Effect.sleep` is the friendlier
  entry point that accepts any `Duration.Input` like `"2 seconds"`.)
- **`currentTimeMillisUnsafe(): number`** — synchronous, non-effectful
  millisecond read. Only valid once you already hold the service.
- **`currentTimeNanosUnsafe(): bigint`** — synchronous, non-effectful nanosecond
  read.

```ts
import { Clock, Duration, Effect } from "effect"

const program = Effect.gen(function* () {
  const clock = yield* Clock.Clock
  const ms = clock.currentTimeMillisUnsafe() // => 1748563200000
  const ns = clock.currentTimeNanosUnsafe() // => 1748563200000000000n
  yield* clock.sleep(Duration.seconds(1)) // suspends 1s (via the Clock)
  return { ms, ns }
})
```

### Sleeping & timeouts build on the Clock

You rarely call `clock.sleep` directly. The `Effect` operators for delaying and
bounding work — `Effect.sleep`, `Effect.delay`, and `Effect.timeout` — are all
implemented in terms of the active `Clock`, which is exactly why they become
instantaneous and deterministic under `TestClock`. Each accepts any
`Duration.Input`.

```ts
import { Effect } from "effect"

const program = Effect.gen(function* () {
  // Suspend the fiber for a duration.
  yield* Effect.sleep("500 millis")

  // Delay an effect before it runs.
  yield* Effect.log("later").pipe(Effect.delay("1 second"))

  // Bound an effect; fails with a timeout if it does not finish in time.
  const result = yield* slowWork.pipe(Effect.timeout("5 seconds"))
  return result
})

declare const slowWork: Effect.Effect<string>
```

See [Schedule](https://effect.plants.sh/scheduling/schedule/) for repeating and retrying on a
clock-driven cadence.

---

Time, like every other capability in Effect, is just a service — which is what
lets [schedules](https://effect.plants.sh/scheduling/schedule/) and
[retries](https://effect.plants.sh/scheduling/repetition-and-retry/) be tested as easily as pure
functions. For controlling the clock in tests, see
[TestClock](https://effect.plants.sh/testing/testclock/) and the broader [Testing](https://effect.plants.sh/testing/) guide.