Codectionary / Developer documentation / Java

Testable Time with Clock

Supply the current time as a dependency so date-dependent logic can be tested consistently.

What it is and why to use it

Code that reads the real current date is harder to test near midnight or across time zones. Clock supplies an instant and zone through an object. Passing it into a method lets production use a system clock while a test uses a fixed instant.

How it works

Clock.fixed always returns the chosen instant. LocalDate.now(clock) converts that instant into a date using the clock’s zone. The same instant can correspond to different local dates, so this example deliberately uses UTC for deterministic output.

Common mistakes and limitations

A fixed clock does not advance as real time passes. Passing a clock is ineffective if a helper ignores it and calls a no-argument now method. Choose a business zone deliberately instead of assuming UTC is right for every application.

Try it and keep learning

Save the complete example below as Main.java. With a JDK supporting Java 17, compile using javac --release 17 Main.java, then run java Main from the same directory. These examples need only the standard library and fixed input; they do not require packages, files or network access.

Syntax

Clock clock = Clock.fixed(instant, ZoneOffset.UTC);

Examples

Testable Time with Clock

Complete Main.java example — Java 17 or later, without preview features.

import java.time.Clock;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneOffset;

public class Main {
  static LocalDate dueDate(Clock clock) {
    return LocalDate.now(clock).plusDays(7);
  }

  public static void main(String[] args) {
    Clock clock = Clock.fixed(Instant.parse("2024-06-01T10:00:00Z"), ZoneOffset.UTC);
    System.out.println(LocalDate.now(clock));
    System.out.println(dueDate(clock));
  }
}
  1. Instant.parse identifies an exact point on the timeline and UTC supplies the zone.
  2. LocalDate.now(clock) consistently returns June 1, 2024, regardless of when this program runs.
  3. dueDate adds seven calendar days and returns June 8. A test can change the supplied clock to exercise date boundaries without changing the computer’s clock.
  4. Expected output: 2024-06-01 2024-06-08

Best practices

  • Inject the clock into date-dependent logic.
  • Use a consistent explicit zone in tests.

Runtime & versions

Java Virtual Machine. Feature availability depends on the language and runtime version used by your project; consult the official reference below.

Java Language Specification

Specifications & further reading