9
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

CarbonのSetTestNowの仕様変更

Posted at

Carbon::setTestNow()で現在時刻を固定し、Carbon::now()で固定した値になっているかを確かめる以下のようなテストがあります。

<?php

namespace Tests\Unit;

use Carbon\Carbon;
use PHPUnit\Framework\TestCase;

class Test extends TestCase
{
    public function test()
    {
        $now = new Carbon('2020-05-12T10:00:00+09:00');
        Carbon::setTestNow($now);

        self::assertSame(
            $now->format('Y-m-d H:i:s'),
            Carbon::now()->format('Y-m-d H:i:s')
        );
    }
}

つい最近まではこのコードで問題なかったのですが、最近のCarbonでは失敗してしまいます。

Failed asserting that two strings are identical.
Expected :'2020-05-12 10:00:00'
Actual   :'2020-05-12 01:00:00'

原因となっているのはこちらの仕様変更です。
https://github.com/briannesbitt/Carbon/issues/2481

内容としては「setTestNow()では時間だけを固定し、タイムゾーンは固定しない」ようにするというものです。

上記テストコードではsetTestNow()で現在時刻を固定する時はAsia/Tokyoでタイムゾーンを設定していますが、Carbon::now()で現在時刻を取得する時はタイムゾーンを設定していないためCarbonのデフォルトであるUTCが適用され、時刻のズレが発生しています。
また、assertSame()で比較するときはタイムゾーンの情報が失われているため、デバッグ時にも気付くのが大変です。
タイムゾーンの情報を含めた出力をすると以下のようになります。

<?php

namespace Tests\Unit;

use Carbon\Carbon;
use PHPUnit\Framework\TestCase;

class Test extends TestCase
{
    public function test()
    {
        $now = new Carbon('2020-05-12T10:00:00+09:00');
        Carbon::setTestNow($now);
        dd(
            $now->format('Y-m-d\TH:i:sP'),
            Carbon::now()->format('Y-m-d\TH:i:sP')
        );
    }
}
PHPUnit 9.5.10 by Sebastian Bergmann and contributors.

 "2020-05-12T10:00:00+09:00"
 "2020-05-12T01:00:00+00:00"

解決策としては、Carbon::setTestNow()で設定したタイムゾーンと同じタイムゾーンでCarbon::now()を呼び出せばOKです。

<?php

namespace Tests\Unit;

use Carbon\Carbon;
use PHPUnit\Framework\TestCase;

class Test extends TestCase
{
    public function test()
    {
        $now = new Carbon('2020-05-12T10:00:00+09:00');
        Carbon::setTestNow($now);

        self::assertSame(
            $now->format('Y-m-d H:i:s'),
            Carbon::now('Asia/Tokyo')->format('Y-m-d H:i:s') // タイムゾーンを揃える
        );
    }
}
9
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?