# app.TestClock — pin every test's clock

> One line in any `.test.osy` file opts the whole project into a pinned test clock: every test and every fixture then starts at that instant instead of the wall clock, so nothing a test asserts depends on the day or hour the suite runs. `TestClock.Set` and `TestClock.Advance` still move it from there.

<!-- id: testing-project-test-clock · area: testing · stability: preview · html: https://osysharp.com/reference/testing/project-test-clock/ -->

## Summary        {#summary}
Without it, a test reads the real clock (or, forked from a fixture, the moment its fixture was seeded — see
[TestClock.Advance and TestClock.Set](https://osysharp.com/reference/testing/clock-advance/)). That is right for most suites, and it is why pinning is **opt-in**: turning it on changes
what every existing test reads as "now". A project whose tests reason about dates — a booking for tomorrow, a
monthly report, a reminder at nine — opts in once:

```osy syntax
app.TestClock = new DateTime(2030, 1, 15, 9, 30, 0);   // in any .test.osy — read as UTC
```

Then `DateTime.UtcNow` in every test body, in every fixture, in a query's `Where(…)`, on the page a test opens and in
the server call a click makes all read 15 January 2030, 09:30 — on every machine, on every day.

## Signature      {#signature}
```osy syntax
app.TestClock = new DateTime(<year>, <month>, <day>);
app.TestClock = new DateTime(<year>, <month>, <day>, <hour>, <minute>, <second>);
```

## Description    {#description}
- **Per project.** Write it once, in any one of the files your `tests` glob collects; it applies to every test file.
- **Pinned, not running.** The clock stands at that instant until a test moves it — `TestClock.Advance(…)` steps it on,
  `TestClock.Set(…)` puts it somewhere else. A fixture that moves it hands its tests the instant it left it at.
- **Fixtures start there too.** A row a `[TestFixture]` stamps with `DateTime.UtcNow` holds the pinned instant, so a
  test forked from it reads a world built at the same moment it reads as "now".
- **In a `.test.osy` only.** In a model file it would pin nothing, so it is refused there. Outside `osy test` it does
  nothing at all: a running app reads the real clock (and `osy clock` moves a running local app's clock — see
  [Moving the running app's clock](https://osysharp.com/reference/local/moving-the-clock/)).
- **Written out.** Year, month and day, then optionally hour, minute and second, as number literals, read as UTC. It is
  read before anything runs, so it cannot be computed.

```osy title="every test starts at the project's instant" run app=project-test-clock
app.TestClock = new DateTime(2030, 1, 15, 9, 30, 0);

[Test]
void now_is_the_projects_instant() {
  Assert.Equal(new DateTime(2030, 1, 15, 9, 30, 0), DateTime.UtcNow);
}

[Test]
void a_test_still_moves_it_on() {
  TestClock.Advance(TimeSpan.FromHours(2));
  Assert.Equal(new DateTime(2030, 1, 15, 11, 30, 0), DateTime.UtcNow);
}
```

## See also       {#see-also}
- [TestClock.Advance and TestClock.Set](https://osysharp.com/reference/testing/clock-advance/) — `TestClock.Set` and `TestClock.Advance`, and every clock they move
- [Fixtures: built once, cloned for every test, and built on each other](https://osysharp.com/reference/testing/fixtures/) — what a test forked from a fixture starts from
- [Moving the running app's clock](https://osysharp.com/reference/local/moving-the-clock/) — moving a running local app's clock with `osy clock`
