PHP code example of kylekatarnls / carbonite

1. Go to this page and download the library: Download kylekatarnls/carbonite library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

kylekatarnls / carbonite example snippets




use Carbon\Carbon;
use Carbon\Carbonite;

function scanEpoch() {
    switch (Carbon::now()->year) {
        case 1944:
            return 'WW2';
        case 1946:
            return 'War is over';
        case 2255:
            return 'The Discovery is flying!';
    }
}

Carbonite::freeze('1944-05-05');

echo scanEpoch(); // output: WW2

Carbonite::elapse('2 years');

echo scanEpoch(); // output: War is over

Carbonite::jumpTo('2255-01-01 00:00:00');

echo scanEpoch(); // output: The Discovery is flying!

Carbonite::speed(3); // Times passes now thrice as fast
sleep(15); // If 15 seconds passes in the real time

// Then 45 seconds passed in our fake timeline:
echo Carbon::now(); // output: 2255-01-01 00:00:45

// Assuming now is 2005-04-01 15:56:23

Carbonite::freeze(); // Freeze our fake timeline on current moment 2005-04-01 15:56:23

// You run a long function, so now is 2005-04-01 15:56:24
echo Carbon::now(); // output: 2005-04-01 15:56:23
// Time is frozen for any relative time in Carbon

Carbonite::freeze('2010-05-04');

echo Carbon::now()->isoFormat('MMMM [the] Do'); // output: May the 4th

$now = Carbon::now()->addSecond();

echo (int) Carbon::now()->diffInSeconds($now); // output: 0

// because first Carbon::now() is a few microseconds before the second one,
// so the final diff is a bit less than 1 second (for example 0.999262)

Carbonite::freeze();

$now = Carbon::now()->addSecond();

echo Carbon::now()->diffInSeconds($now); // output: 1

// Time is frozen so the whole thing behaves as if it was instantaneous

Carbonite::freeze('2010-05-04', 2); // Go to 2010-05-04 then make the time pass twice as fast.

// Assuming now is 19 October 1977 8pm
Carbonite::freeze();
// Sit in the movie theater
Carbonite::speed(1 / 60); // Now every minute flies away like it's just a second
// 121 minutes later, now is 19 October 1977 10:01pm
// But it's like it's just 8:02:01pm in your timeline
echo Carbon::now()->isoFormat('h:mm:ssa'); // output: 8:02:01pm

// Now it's 19 October 1977 11:00:00pm
Carbonite::jumpTo('19 October 1977 11:00:00pm');
Carbonite::speed(3600); // and it's like every second was an hour
// 4 seconds later, now it's 19 October 1977 11:00:04pm
// it's like it's already 3am the next day
echo Carbon::now()->isoFormat('YYYY-MM-DD h:mm:ssa'); // output: 1977-10-20 3:00:00am

// Assuming now is 2020-03-14 12:00

Carbonite::freeze('2019-12-23'); // Set fake timeline to last December 23th (midnight)
Carbonite::speed(1); // speed = 1 means each second elapsed in real file, elpase 1 second in the fake timeline

// Then we can see what date and time it would be in the fake time line
// if we were let's say March the 16th in real life:

echo Carbonite::fake(Carbon::parse('2020-03-16 14:00')); // output: 2019-12-25 02:00:00
// Cool it would be Christmas (2am) in our fake timeline

Carbonite::speed(2);

echo Carbonite::accelerate(3); // output: 6

Carbonite::speed(5);

echo Carbonite::decelerate(2); // output: 2.5

// Now it's 8:00am
Carbonite::freeze();
echo Carbonite::speed(); // output: 0

// Now it's 8:02am
// but time is frozen
echo Carbon::now()->format('g:i'); // output: 8:00

Carbonite::unfreeze();
echo Carbonite::speed(); // output: 1

// Our timeline restart where it was paused
// so now it's 8:03am
echo Carbon::now()->format('g:i'); // output: 8:01

Carbonite::freeze('2000-06-30');
Carbonite::jumpTo('2000-09-01');
echo Carbon::now()->format('Y-m-d'); // output: 2000-09-01
Carbonite::jumpTo('1999-12-20');
echo Carbon::now()->format('Y-m-d'); // output: 1999-12-20

Carbonite::freeze('2000-01-01');
Carbonite::elapse('1 month');
echo Carbon::now()->format('Y-m-d'); // output: 2000-02-01
Carbonite::elapse(CarbonInterval::year());
echo Carbon::now()->format('Y-m-d'); // output: 2001-02-01
Carbonite::elapse(new DateInterval('P1M3D'));
echo Carbon::now()->format('Y-m-d'); // output: 2001-03-04

Carbonite::freeze('2000-01-01');
Carbonite::rewind('1 month');
echo Carbon::now()->format('Y-m-d'); // output: 1999-12-01
Carbonite::rewind(CarbonInterval::year());
echo Carbon::now()->format('Y-m-d'); // output: 1998-12-01
Carbonite::rewind(new DateInterval('P1M3D'));
echo Carbon::now()->format('Y-m-d'); // output: 1998-10-29

Carbonite::freeze('2000-01-01', 1.5);
Carbonite::do('2020-12-23', static function () {
    echo Carbon::now()->format('Y-m-d H:i:s.u'); // output: 2020-12-23 00:00:00.000000
    usleep(200);
    // Still the same output as time is frozen inside the callback
    echo Carbon::now()->format('Y-m-d H:i:s.u'); // output: 2020-12-23 00:00:00.000000
    echo Carbonite::speed(); // output: 0
});
// Now the speed is 1.5 on 2000-01-01 again
echo Carbon::now()->format('Y-m-d'); // output: 2000-01-01
echo Carbonite::speed(); // output: 1.5

// Assuming now is 17 September 2020 8pm
Carbonite::doNow(static function () {
    echo Carbon::now()->format('Y-m-d H:i:s.u'); // output: 2020-09-17 20:00:00.000000
    usleep(200);
    // Still the same output as time is frozen inside the callback
    echo Carbon::now()->format('Y-m-d H:i:s.u'); // output: 2020-09-17 20:00:00.000000
    echo Carbonite::speed(); // output: 0
});
// Now the speed is 1 again
echo Carbonite::speed(); // output: 1

// Assuming now is 2019-05-24
Carbonite::freeze('2000-01-01');
echo Carbon::now()->format('Y-m-d'); // output: 2000-01-01
echo Carbonite::speed(); // output: 0

Carbonite::release();
echo Carbon::now()->format('Y-m-d'); // output: 2019-05-24
echo Carbonite::speed(); // output: 1

use Carbon\Carbonite;
use Carbon\FactoryImmutable;
use Psr\Clock\ClockInterface;
use Symfony\Component\Clock\DatePoint;

// \Symfony\Component\Clock\Clock is automatically synchronized
// So DatePoint and services linked to it will be mocked

Carbonite::freeze('2000-01-01');

$date = new DatePoint();
echo $date->format('Y-m-d'); // output: 2000-01-01

// Having a service using PSR Clock, you can also test it
// With any Carbonite method by passing Carbonite::getClock()
class MyService
{
    private $clock;

    public function __construct(ClockInterface $clock)
    {
        $this->clock = $clock;
    }
    
    public function getDate()
    {
        return $this->clock->now()->format('Y-m-d');
    }
}

$service = new MyService(Carbonite::getClock());
Carbonite::freeze('2025-12-20');
echo $service->getDate(); // output: 2025-12-20

use Carbon\Carbonite;
use Carbon\FactoryImmutable;

Carbonite::addSynchronizer(function (FactoryImmutable $factory) {
    Timecop::travel($factory->now()->timestamp);
});

use Carbon\BespinTimeMocking;
use Carbon\Carbonite;
use Carbon\CarbonPeriod;
use PHPUnit\Framework\TestCase;

class MyProjectTest extends TestCase
{
    // Will handle attributes on each method before running it
    // and release the time after each test
    use BespinTimeMocking;

    public function testHolidays()
    {
        $holidays = CarbonPeriod::create('2019-12-23', '2020-01-06', CarbonPeriod::EXCLUDE_END_DATE);
        Carbonite::jumpTo('2019-12-22');

        $this->assertFalse($holidays->isStarted());

        Carbonite::elapse('1 day');

        $this->assertTrue($holidays->isInProgress());

        Carbonite::jumpTo('2020-01-05 22:00');

        $this->assertFalse($holidays->isEnded());

        Carbonite::elapse('2 hours');

        $this->assertTrue($holidays->isEnded());

        Carbonite::rewind('1 microsecond');

        $this->assertFalse($holidays->isEnded());
    }
}

use Carbon\BespinTimeMocking;
use Carbon\Carbon;
use Carbon\Carbonite;
use Carbon\Carbonite\Attribute\Freeze;
use Carbon\Carbonite\Attribute\JumpTo;
use Carbon\Carbonite\Attribute\Speed;
use PHPUnit\Framework\TestCase;

class PHP8Test extends TestCase
{
    // Will handle attributes on each method before running it
    // and release the time after each test
    use BespinTimeMocking;

    #[Freeze("2019-12-25")]
    public function testChristmas()
    {
        // Here we are the 2019-12-25, time is frozen.
        self::assertSame('12-25', Carbon::now()->format('m-d'));
        self::assertSame(0.0, Carbonite::speed());
    }

    #[JumpTo("2021-01-01")]
    public function testJanuaryFirst()
    {
        // Here we are the 2021-01-01, but time is NOT frozen.
        self::assertSame('01-01', Carbon::now()->format('m-d'));
        self::assertSame(1.0, Carbonite::speed());
    }

    #[Speed(10)]
    public function testSpeed()
    {
        // Here we start from the real date-time, but during
        // the test, time elapse 10 times faster.
        self::assertSame(10.0, Carbonite::speed());
    }

    #[Release]
    public function testRelease()
    {
        // If no attributes have been used, Bespin::up() will use:
        // Carbonite::freeze('now')
        // But you can still use #[Release] to get a test with
        // real time
    }
}

use Carbon\Carbonite;

function fakeAsync(callable $fn): void {
    Carbonite::freeze();
    $fn();
    Carbonite::release();
}

function tick(int $milliseconds): void {
    Carbonite::elapse("$milliseconds milliseconds");
}

use Carbon\Carbon;

fakeAsync(function () {
    $now = Carbon::now();
    tick(2000);

    echo $now->diffForHumans(); // output: 2 seconds ago
});

#[TestWith([new Freeze('2024-05-25'), '2024-05-24'])]
#[TestWith([new Freeze('2023-01-01'), '2022-12-31'])]
public function testYesterday(string $date): void
{
    self::assertSame($date, Carbon::yesterday()->format('Y-m-d'));
}

#[DataProvider('getDataSet')]
public function testNow(string $date): void
{
    self::assertSame($date, Carbon::now()->format('Y-m-d'));
}

public static function getDataSet(): array
{
    return [
        ['2024-05-25', new Freeze('2024-05-25')],
        ['2023-12-14', new Freeze('2024-05-25')],
    ];
}

#[DataProvider('getDataSet')]
public function testDataProvider(): void
{
    $now = CarbonImmutable::now();
    self::assertSame($now->day, $now->addMonth()->day);
}

public static function getDataSet(): iterable
{
    yield from Carbon::parse('2023-01-01')
        ->daysUntil('2023-01-31')
        ->map(static fn ($date) => [new Freeze($date)]);
}

#[DataProvider('getDataSet')]
public function testDataProvider(string $date, int $days): void
{
    self::assertSame(
        $date,
        Carbon::now()->addDays($days)->format('Y-m-d')
    );
}

public static function getDataSet(): iterable
{
    yield from DataGroup::for(new Freeze('2024-05-25'), [
        ['2024-05-27', 2],
        ['2024-06-01', 7],
        ['2024-06-08', 14],
    ]);

    yield from DataGroup::for(new Freeze('2023-12-30'), [
        ['2023-12-31', 1],
        ['2024-01-06', 7],
        ['2024-02-03', 35],
    ]);

    yield from DataGroup::matrix([
        new Freeze('2024-05-25'),
        new Freeze('2023-12-14'),
    ], [
        'a' => ['2024-05-25'],
        'bb' => ['2023-12-14'],
    ]);
}

#[DataProvider('getDataSet')]
public function testDataProvider(string $text): void
{
    // This test will be run 4 times:
    // - With current time mocked to 2024-05-25 and $text = "abc"
    // - With current time mocked to 2024-05-25 and $text = "def"
    // - With current time mocked to 2023-12-14 and $text = "abc"
    // - With current time mocked to 2023-12-14 and $text = "def"
}

public static function getDataSet(): DataGroup
{
    return DataGroup::matrix([
        new Freeze('2024-05-25'),
        new Freeze('2023-12-14'),
    ], [
        ['abc'],
        ['def'],
    ]);
}

#[DataProvider('getDataSet')]
public function testDataProvider(): void
{
}

public static function getDataSet(): DataGroup
{
    return DataGroup::withVariousDates();
}

#[DataProvider('getDataSet')]
public function testDataProvider(string $text, int $number): void
{
}

public static function getDataSet(): DataGroup
{
    return DataGroup::withVariousDates(
        [
            ['abc', 4],
            ['def', 6],
        ],
        ['America/Chicago', 'Pacific/Auckland'],
        ['2024-12-25', '2024-12-26'],
        ['12:00', '02:30']
    );
}

#[DataProvider('getDataSet')]
public function testDataProvider(): void
{
    // Will run 5 times, each time with now randomly picked between
    // 2024-06-01 00:00 and 2024-09-20 00:00
    // For instance: 2024-07-16 22:45:12.251637
}

public static function getDataSet(): DataGroup
{
    return DataGroup::between('2024-06-01', '2024-09-20', 5);
}

#[DataProvider('getDataSet')]
public function testDataProvider(string $letter): void
{
    // Will run with $letter = 'a' and now picked randomly
    // Will run with $letter = 'b' and now picked randomly
    // Will run with $letter = 'c' and now picked randomly
}

public static function getDataSet(): DataGroup
{
    return DataGroup::between('2024-06-01', '2024-09-20', ['a', 'b', 'c']);
}

use Carbon\Carbonite;
use Carbon\Carbonite\Attribute\UpInterface;

#[\Attribute]
final class AtUserCreation implements UpInterface
{
    public function __construct(private string $username) {}

    public function up() : void
    {
        // Let's assume as an example that the code below is how to get
        // user creation as a Carbon or DateTime from a username in your app.
        $creationDate = User::where('Name', $username)->first()->created_at;
        Carbonite::freeze($creationDate);
    }
}

#[AtUserCreation('Robin')]
public function testUserAge(): void
{
    Carbon::sleep(3);
    $ageInSeconds = (int) User::where('Name', $username)->first()->created_at->diffInSeconds();

    self::assertSame(3, $ageInSeconds);
}