PHPackages                             snicco/testable-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. snicco/testable-clock

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

snicco/testable-clock
=====================

v1.10.1(1y ago)019.7k7LGPL-3.0-onlyPHPPHP ^7.4|^8.0

Since Apr 17Pushed 1y ago1 watchersCompare

[ Source](https://github.com/snicco/testable-clock)[ Packagist](https://packagist.org/packages/snicco/testable-clock)[ RSS](/packages/snicco-testable-clock/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (1)Versions (35)Used By (7)

TestableClock - PHP7.4 compatible clock abstraction
===================================================

[](#testableclock---php74-compatible-clock-abstraction)

[![codecov](https://camo.githubusercontent.com/a99e6ec528fffd1664e95534f9a09a4a09d2afe62799ff0d8774dc22d8453f6c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f436f7665726167652d3130302532352d73756363657373)](https://codecov.io/gh/snicco/snicco)[![Psalm Type-Coverage](https://camo.githubusercontent.com/c12cfed65c7da16501f7a84e7861b8c4757fc30e9dc00bb2983783dbb3f3f84c/68747470733a2f2f73686570686572642e6465762f6769746875622f736e6963636f2f736e6963636f2f636f7665726167652e7376673f)](https://shepherd.dev/github/snicco/snicco)[![Psalm level](https://camo.githubusercontent.com/c5e90ffcf3a5aa1f78f93bddde5db7627b114329393aa87697df8cedc7f5391a/68747470733a2f2f73686570686572642e6465762f6769746875622f736e6963636f2f736e6963636f2f6c6576656c2e7376673f)](https://psalm.dev/)[![PhpMetrics - Static Analysis](https://camo.githubusercontent.com/364ffb28ea219affd0fed2e99cc046bac0bf41da3f1d3814e0cbe4a4bb54c994/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5068704d6574726963732d5374617469635f416e616c797369732d326561343466)](https://snicco.github.io/snicco/phpmetrics/TestableClock/index.html)[![PHP-Versions](https://camo.githubusercontent.com/241a10d25aa09d5e8a82ebd2b55780a63dd43736d958d4004c3166e650874aca/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d253545372e34253743253545382e30253743253545382e312d626c7565)](https://camo.githubusercontent.com/241a10d25aa09d5e8a82ebd2b55780a63dd43736d958d4004c3166e650874aca/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d253545372e34253743253545382e30253743253545382e312d626c7565)

The **TestableClock** component of the [**Snicco** project](https://github.com/snicco/snicco) decouples code from `DateTimeImmutable` so that its properly testable.

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

[](#installation)

```
composer require snicco/testable-clock
```

Usage
-----

[](#usage)

Instead of using `DateTimeImmutable` and `time()` directly in your code you use the [`Clock` interface](src/Clock.php).

```
use Snicco\Component\TestableClock\Clock;
use Snicco\Component\TestableClock\SystemClock;
use Snicco\Component\TestableClock\TestClock;

class IsTrialExpired {

    private  Clock $clock;

    public function __construct(Clock $clock) {
        $this->clock = $clock;
    }

    public function __invoke(object $trial) {
        return $trial->expiresAt > $this->clock->currentTimestamp();
    }

}

// In production code
$clock = SystemClock::fromUTC();

// or
$clock = new SystemClock(new DateTimeZone('Europe/Berlin'));

$is_trial_expired = new IsTrialExpired($clock)

// In test code
$test_clock = new TestClock();

$is_trial_expired = new IsTrialExpired($test_clock)
```

The [`TestClock`](src/TestClock.php) stays frozen, meaning it will always return the same timestamp.

You can advance the clock, or go back in time.

```
use Snicco\Component\TestableClock\TestClock;

$clock = new TestClock();

$time_0 = $clock->currentTimestamp();

var_dump(time() === $time_0); // true

sleep(10);

$time_01 = $clock->currentTimestamp();

var_dump($time_01 === $time_0); // true
var_dump(time() === $time_01); // false

$clock->travelIntoFuture(10);

$time_02 = $clock->currentTimestamp();

var_dump(time() === $time_02); // true

$time_03 = $clock->travelIntoPast(10);

var_dump($time_03 === $time_01); // true
```

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

[](#contributing)

This repository is a read-only split of the development repo of the [**Snicco** project](https://github.com/snicco/snicco).

[This is how you can contribute](https://github.com/snicco/snicco/blob/master/CONTRIBUTING.md).

Reporting issues and sending pull requests
------------------------------------------

[](#reporting-issues-and-sending-pull-requests)

Please report issues in the [**Snicco** monorepo](https://github.com/snicco/snicco/blob/master/CONTRIBUTING.md##using-the-issue-tracker).

Security
--------

[](#security)

If you discover a security vulnerability, please follow our [disclosure procedure](https://github.com/snicco/snicco/blob/master/SECURITY.md).

###  Health Score

36

—

LowBetter than 82% of packages

Maintenance35

Infrequent updates — may be unmaintained

Popularity20

Limited adoption so far

Community14

Small or concentrated contributor base

Maturity65

Established project with proven stability

 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

Every ~27 days

Recently: every ~1 days

Total

33

Last Release

616d ago

Major Versions

v1.10.0 → v2.0.0-beta.12024-09-01

v1.10.1 → v2.0.0-beta.72024-09-04

### Community

Maintainers

![](https://www.gravatar.com/avatar/d659a021c9077ceb60e6ab1ea4287b9f209edb97e93bceceb7fb539d8302e894?d=identicon)[calvinalkan](/maintainers/calvinalkan)

---

Top Contributors

[![snicco-bot](https://avatars.githubusercontent.com/u/101470239?v=4)](https://github.com/snicco-bot "snicco-bot (25 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

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

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

###  Alternatives

[crankycyclops/m2-module-discount-code-url

Allows discount codes to be applied to a browser session automatically via a query string or URL path.

4112.3k](/packages/crankycyclops-m2-module-discount-code-url)[fritzmg/contao-news-related

Simple Contao 4+ bundle for setting related news directly.

113.8k](/packages/fritzmg-contao-news-related)[terabin/flarum-ext-sitemap

Generate a Sitemap for Flarum automatically

103.0k1](/packages/terabin-flarum-ext-sitemap)

PHPackages © 2026

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