PHPackages                             shyru/timedilation - 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. [Testing &amp; Quality](/categories/testing)
4. /
5. shyru/timedilation

ActiveLibrary[Testing &amp; Quality](/categories/testing)

shyru/timedilation
==================

Mocking time() for PHPUnit

0.1.1(13y ago)112.3kMITPHPPHP &gt;=5.3.0

Since Mar 3Pushed 13y ago1 watchersCompare

[ Source](https://github.com/Shyru/TimeDilation)[ Packagist](https://packagist.org/packages/shyru/timedilation)[ Docs](http://github.com/Shyru/TimeDilation)[ RSS](/packages/shyru-timedilation/feed)WikiDiscussions master Synced 2mo ago

READMEChangelogDependencies (1)Versions (3)Used By (0)

TimeDilation/TimeMachine - mocking time() for PHPUnit
=====================================================

[](#timedilationtimemachine---mocking-time-for-phpunit)

TimeDilation/TimeMachine helps you when you need to test time()-constrained code in PHPUnit. It only works for PHP 5.3 namespaced classes/code.

[![Build Status](https://camo.githubusercontent.com/1e9c28ba144a3fe6dd4b952a7621b5c79044f6a8e15518ef808f228b1c3bf6a2/68747470733a2f2f7472617669732d63692e6f72672f53687972752f54696d6544696c6174696f6e2e706e67)](https://travis-ci.org/Shyru/TimeDilation)

Usage
-----

[](#usage)

Write your unit tests in the namespace TimeDilation and use the methods of TimeMachine to mock time. Basic Example:

```
namespace TimeDilation;

class TestTime extends PHPUnit_Framework_TestCase
{
	function testBasics()
	{
		$now="2028-08-29 17:28:49";
		TimeMachine::setNow($now);
		$this->assertEquals($now,date("Y-m-d H:i:s"));
		sleep(1);
		$this->assertEquals("2028-08-29 17:28:50",date("Y-m-d H:i:s"));
		TimeMachine::freeze();
		sleep(1);
		$this->assertEquals("2028-08-29 17:28:50",date("Y-m-d H:i:s"));
		TimeMachine::fastForward(10);
		$this->assertEquals("2028-08-29 17:29:00",date("Y-m-d H:i:s"));
	}
}
```

Testing a class that uses time():

```
namespace IO\Util;

/**
 * Provides buffering of arbitrary data and flushing to registered consumers
 * in an interval that is bigger than the bufferTime.
 */
class Buffer
{
    private $bufferTime;
    private $buffer;
    private $callbacks;
    private $lastFlush;

    /**
     * Constructs a new buffer.
     *
     * @param int $_bufferTime The buffer time in seconds.
     */
    function __construct($_bufferTime=10)
    {
        $this->bufferTime=$_bufferTime;
        $this->lastFlush=time();
    }

    /**
     * Registers a new consumer callback that should be called
     * whenever at least 10 seconds passed since the last time the data was flushed.
     *
     * @param callable $_callback The callback that should be called to receive the flushed data
     */
    function registerConsumer($_callback)
    {
        $this->callbacks[]=$_callback;
    }

    /**
     * Append some data to the buffer.
     * If the last flush of data was more then bufferTime seconds ago, the buffer will be flushed to all registered
     * consumers.
     *
     * @param mixed $_data The data that should be buffered.
     */
    function append($_data)
    {
        $this->buffer[]=$_data;
        if ($this->lastFlush+$this->bufferTimecallbacks as $callback)
            {
                call_user_func($callback,$this->buffer);
            }
            $this->buffer=array();
            $this->lastFlush=time();
        }
    }

}
```

If you wanted to write a Unit-Test for the above Buffer class the Unit-Test would at least take a second to complete because that would be the minimum buffer time. If you wanted to test with the default buffer time the test would take at least 10 seconds essentially just waiting. With TimeDilation/TimeMachine the class could be tested as follows:

```
namespace TimeDilation;

TimeMachine::infectNamespace("IO\\Util"); //infect the namespace so that we can control time
require_once(__DIR__."/Buffer.php");

class BufferTest extends \PHPUnit_Framework_TestCase
{

    function testAppendAndFlushing()
    {
        $flushContainer=new \stdClass;
        $flushContainer->data=array();
        $buffer=new \IO\Util\Buffer();
        $buffer->registerConsumer(function($_data) use ($flushContainer) {
            $flushContainer->data=$_data;
        });

        $buffer->append("TimeMachine");
        TimeMachine::fastForward(4); //fast forward time by 4 seconds
        $buffer->append("rocks");
        TimeMachine::fastForward(7); //fast forward time by 7 seconds
        $buffer->append("the world!");
        //since we forwarded time more than 10 seconds our consumer should now have been called,
        //lets check this
        $this->assertEquals(3,count($flushContainer->data));
        $this->assertEquals("TimeMachine",$flushContainer->data[0]);
        $this->assertEquals("rocks",$flushContainer->data[1]);
        $this->assertEquals("the world!",$flushContainer->data[2]);
    }
}
```

Thanks to TimeMachine this test will execute in a fraction of a second allthough the complete class is tested the class does not need to be modified to support fancy time-mocking. I think you can easily come up with more/better examples on where this could be useful.

Since this is still very young code there may very well be some bugs hidden. If you find something not working correctly, add an issue or propose a fix through a fork and pull-request!

Caveats
-------

[](#caveats)

- It only works for PHP 5.3 namespaced classes/code.
- Does not work with DateTime class of php.

Roadmap
-------

[](#roadmap)

- Implement time-warping. (Override sleep() and usleep() so that they return immediatly but time is forwarded as much as the sleep should have lasted)
- Research ways of mocking DateTime class.

###  Health Score

28

—

LowBetter than 54% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity23

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity49

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

Every ~3 days

Total

2

Last Release

4821d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/1b235747c088b9483088295988e707651792a6c5b51c1723d22018d683ffca16?d=identicon)[Shyru](/maintainers/Shyru)

---

Top Contributors

[![Shyru](https://avatars.githubusercontent.com/u/957556?v=4)](https://github.com/Shyru "Shyru (10 commits)")

---

Tags

phpunitmockingmocktime

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/shyru-timedilation/health.svg)

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

###  Alternatives

[dg/bypass-finals

Removes final keyword from source code on-the-fly and allows mocking of final methods and classes

56426.3M456](/packages/dg-bypass-finals)[php-mock/php-mock-phpunit

Mock built-in PHP functions (e.g. time()) with PHPUnit. This package relies on PHP's namespace fallback policy. No further extension is needed.

1718.2M399](/packages/php-mock-php-mock-phpunit)[donatj/mock-webserver

Simple mock web server for unit testing

1382.5M80](/packages/donatj-mock-webserver)[blastcloud/guzzler

Supercharge your app or SDK with a testing library specifically for Guzzle.

272419.3k35](/packages/blastcloud-guzzler)[elliotchance/concise

Concise is test framework for using plain English and minimal code, built on PHPUnit.

45223.8k4](/packages/elliotchance-concise)[nunomaduro/mock-final-classes

Allows mocking of final methods and classes in PHP.

113854.3k23](/packages/nunomaduro-mock-final-classes)

PHPackages © 2026

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