PHPackages                             firehed/clock - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. firehed/clock

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

firehed/clock
=============

PSR-20 Clock implementation

1.0.0(2y ago)0779[1 PRs](https://github.com/Firehed/psr-clock/pulls)1MITPHPPHP ^8.1

Since Mar 26Pushed 2y ago1 watchersCompare

[ Source](https://github.com/Firehed/psr-clock)[ Packagist](https://packagist.org/packages/firehed/clock)[ RSS](/packages/firehed-clock/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (1)Dependencies (8)Versions (3)Used By (1)

Clock
=====

[](#clock)

A [PSR-20](https://www.php-fig.org/psr/psr-20/) Clock implementation, with time configuration and movement support for use in unit tests.

[![Test](https://github.com/Firehed/psr-clock/actions/workflows/test.yml/badge.svg)](https://github.com/Firehed/psr-clock/actions/workflows/test.yml)[![Static analysis](https://github.com/Firehed/psr-clock/actions/workflows/static-analysis.yml/badge.svg)](https://github.com/Firehed/psr-clock/actions/workflows/static-analysis.yml)[![Lint](https://github.com/Firehed/psr-clock/actions/workflows/lint.yml/badge.svg)](https://github.com/Firehed/psr-clock/actions/workflows/lint.yml)[![codecov](https://camo.githubusercontent.com/8d2eefa24e7dd7d76c5d0c3be5994623996dd83ef2882b7623c0003bce7021d8/68747470733a2f2f636f6465636f762e696f2f67682f466972656865642f7073722d636c6f636b2f67726170682f62616467652e7376673f746f6b656e3d59486d4b7033507a7746)](https://codecov.io/gh/Firehed/psr-clock)

Installation
------------

[](#installation)

```
composer require firehed/clock

```

Usage
-----

[](#usage)

Generally speaking, `ClockInterface` is only useful when paired with Dependency Injection. This allows unit tests to provide a test clock set to a specific point in time, where the actual application is wired to use a wall clock and follows real time.

### Wall Clock

[](#wall-clock)

A wall clock will return the current system time any time `->now()` is called. It advances normally and behaves identically to calling `time()` or `new DateTimeImmutable()` directly would.

**This is what you should use in actual application code.**

```
use Firehed\Clock\Clock;

$clock = new Clock();
```

Important

A clock in "wall clock" mode cannot be moved, and will throw an exception if you attempt to do so.

### Test Clock

[](#test-clock)

A test clock will return a specified time, and can be manually moved. It will *not* advance automatically as actual wall time progresses (e.g. is unaffected by `sleep()`, etc). This is intended for use in test cases, such as:

- Validating or adjusting date ranges in queries
- Ensuring that expiration behavior works as expected
- Verifying rate-limiting behavior

Basically, if you'd normally have to use `sleep()` to check something, you can instead move the test clock by a specificed amount or to a specified time and continue the test case *as if* that time had passed. This can result in tests that run faster and more reliably, without having to fuss with "give or take a second" logic.

```
use Firehed\Clock\Clock;

$clock = new Clock($timeOrOffset);

// ...

$clock->moveTo($otherTimeOrOffset);
```

The behavior of `$timeOrOffset` and `$otherTimeOrOffset` is as follows:

Type`__construct` Behavior`moveTo()` behavior`DateTimeInterface`The clock will be fixed to the specified timeThe clock will move to the specified time`DateInterval`The clock will be fixed to the system time *when construct is called*, plus the offsetThe clock will advance by the offset from its initial fixed time`string` that starts with `P`The string will be parsed as a `DateInterval` and behave as aboveSame`string`The clock will be fixed to an equivalent of `strtotime(string)`Same`int` or `float`The value will be interpreted as a Unix timestamp and fixed to that timeSameAnything elseA `TypeError` will be thrownSameWarning

`float` values can *and often do* lose precision at timestamps near the current time. If your test needs sub-second behavior, prefer any of the more-specific formats.

Unixtime strings avoid floating point precision issues. These are `@` followed by the timestamp; e.g. `'@1234567890.987654'`

The library does **not** make guarantees about subsequent calls to -&gt;now() on a test clock being the same or different `DateTimeImmutable` instances. However, they are guaranteed to be in reference to the same point in time.

Tip

If you only care about relative movement, a test clock can be set up as `new Clock('now')`. You may also use only small values near the Unix epoch (e.g. `0`, `20`); if your application uses `ClockInterface` consistently it should still work, and run as if the current time was in 1970.

#### Moving the clock backwards

[](#moving-the-clock-backwards)

Relative time changes always use `DateTimeImmutable->add()` or the equivalent internally.

To move the clock backwards:

- Pass a `DateInterval` where `invert` is set to `1`
- Pass any absolute timestamp equivalent before the currently-set value

### Time Zones

[](#time-zones)

This library does not currently aim to handle any time zone specifics, and will default to the system configuration. If your needs include specific behavior regarding time zones, be sure to provide values that include time zone information.

Contributing
------------

[](#contributing)

Please report any bugs or feature requests on GitHub. Be aware that this is considered *mostly* feature-complete, so feature requests may be declined.

###  Health Score

26

—

LowBetter than 43% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity16

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity51

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

783d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/354842?v=4)[Eric Stern](/maintainers/Firehed)[@Firehed](https://github.com/Firehed)

---

Top Contributors

[![Firehed](https://avatars.githubusercontent.com/u/354842?v=4)](https://github.com/Firehed "Firehed (2 commits)")

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP\_CodeSniffer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/firehed-clock/health.svg)

```
[![Health](https://phpackages.com/badges/firehed-clock/health.svg)](https://phpackages.com/packages/firehed-clock)
```

###  Alternatives

[lcobucci/clock

Yet another clock abstraction

796190.9M114](/packages/lcobucci-clock)[symfony/clock

Decouples applications from the system clock

431168.9M205](/packages/symfony-clock)[eventsauce/eventsauce

A pragmatic event sourcing library for PHP with a focus on developer experience.

8632.1M47](/packages/eventsauce-eventsauce)[ecotone/ecotone

Supporting you in building DDD, CQRS, Event Sourcing applications with ease.

558549.8k17](/packages/ecotone-ecotone)[mcp/sdk

Model Context Protocol SDK for Client and Server applications in PHP

1.4k423.9k30](/packages/mcp-sdk)[flow-php/etl

PHP ETL - Extract Transform Load - Abstraction

374468.4k51](/packages/flow-php-etl)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
