Together with Marcel Pociot and our colleagues at Beyond Code and Spatie, I'm currently building Flare, a paid service which will be revealed at Laracon EU. Together with the service we'll release a package that will change the way you will work with Laravel. To stay in the loop subscribe to our mailinglist at https://flareapp.io

A package to control the flow of time

Original – by Freek Van der Herten – 2 minute read

Imagine you're building that your app can notify your user, but you don't want to send more than one notification in a timeframe of five seconds. How are you going to test the time aspect? Do you have to create a test that takes five minutes?

Luckily the answer is "no". If you're using the popular Carbon library, you can set the value that the library considers "now". You can do this using Carbon::setTestNow($now) where $now is a instance of Carbon\Carbon.

In the test suites of my projects and package I often added code like this:

protected function setNow(string $time, $format = 'Y-m-d H:i:s')
{
    $now = Carbon::createFromFormat($format, $time);

    Carbon::setTestNow($now);
}

protected function progressSeconds(int $seconds)
{
    $newNow = now()->addSeconds($seconds);

    Carbon::setTestNow($newNow);
}

protected function progressMinutes(int $minutes)
{
    $newNow = now()->addMinutes($minutes);

    Carbon::setTestNow($newNow);
}

protected function progressHours(int $hours)
{
    $newNow = now()->addHours($hours);

    Carbon::setTestNow($newNow);
}

Because I was tired of coding this over and over again, I decided to a new small, handy package called spatie/test-time. Using the package, you can freeze the time with:

// time will not progress anymore

TestTime::freeze();

Alternatively, you can pass in a carbon instance that will be used as the current time.

TestTime::freeze($carbonInstance);

There's also no need to add separate functions like progressSeconds, progressMinutes and so on... You can progress the time with any of the carbon functions starting with add or sub.

TestTime::addMinute();

TestTime::subHours(5);

// you can also chain calls
TestTime::addMonth(3)->addYear();

Here's an example where I used it in a real world project:

Happy tinkering with the time!

Stay up to date with all things Laravel, PHP, and JavaScript.

Follow me on Twitter. I regularly tweet out programming tips, and what I myself have learned in ongoing projects.

Every two weeks I send out a newsletter containing lots of interesting stuff for the modern PHP developer.

Expect quick tips & tricks, interesting tutorials, opinions and packages. Because I work with Laravel every day there is an emphasis on that framework.

Rest assured that I will only use your email address to send you the newsletter and will not use it for any other purposes.

Roman Pronskiy liked on 12th July 2019
Enzo Notario liked on 10th July 2019
Loris Leiva retweeted on 10th July 2019
Loris Leiva liked on 10th July 2019
ArielSalvadorDev liked on 10th July 2019
Mazedul Islam Khan liked on 9th July 2019
Matt Kingshott 🔮 liked on 9th July 2019
Evert Arnould liked on 9th July 2019
Iftekher Sunny liked on 9th July 2019
Iftekher Sunny retweeted on 9th July 2019
Fullstack Developer liked on 9th July 2019
𝗈𝗌𝗆𝖾𝗅𝗅 liked on 9th July 2019
Bruno CHIREZ liked on 9th July 2019
Chris Kankiewicz liked on 9th July 2019
Bas de Groot liked on 9th July 2019
Cyril de Wit liked on 9th July 2019
Mark Topper liked on 9th July 2019