innmind/time-continuum

操作时间的库

3.4.1 2023-09-17 14:31 UTC

README

Build Status codecov Type Coverage

此库允许您精确到毫秒地处理时间。目的在于对日期的每个组件都进行明确的处理,这就是为什么所有的php 魔法字符串 都被转换成了对象。

它还提供了接口,以便您可以为您单元测试创建模拟,当然,这只有在您在代码中使用 Clock 的实现而不是直接实例化日期时才有帮助。

所有对象都是不可变的。

安装

composer install innmind/time-continuum

使用

use Innmind\TimeContinuum\{
    Earth\Clock,
    PointInTime,
};
use Innmind\Immutable\Maybe;

$clock = new Clock;
$now = $clock->now(); // return an instance of PointInTime
echo $now->toString(); //2016-10-11T12:17:30+02:00

$epoch = $clock->at('1970-01-01T00:00:00.000000Z'); // Maybe<PointInTime>

这里我们引用了两个时间点,第一个是我们调用 now 时精确到毫秒的准确时刻,第二个是纪元时间(您可以通过 $epoch->milliseconds() 验证它,它返回 0)。

at() 方法接受任何由 \DateTimeImmutable 允许的字符串。

时区

假设您想在应用程序中仅使用 Europe/Paris 时区,但不知道每个环境是否都有相同的配置(例如,在您的机器和CI之间),您可以强制使用您将工作的时区如下

use Innmind\TimeContinuum\Earth\{
    Clock,
    Timezone\Europe\Paris,
};

$clock = new Clock(new Paris);

echo $clock->now()->timezone()->toString(); //+02:00 (when DST applied), otherwise +01:00

如果您通过方法参数提供了一个时间点但不知道其时区,您可以通过以下方式更改它

use Innmind\TimeContinuum\{
    PointInTime,
    Earth\Timezone\Europe\Paris
};

function foo(PointInTime $point)
{
    $point = $point->changeTimezone(new Paris);
}

注意:不要忘记将值重新分配给变量,因为所有对象都是不可变的。

时间旅行

use Innmind\TimeContinuum\Earth\Period\{
    Year,
    Month,
    Minute,
    Millisecond,
};

$point = $clock
    ->now()
    ->goBack(
        (new Year(1))
            ->add(new Month(2))
            ->add(new Minute(24))
            ->add(new Millisecond(500))
    );

这里我们回到1年前,2个月,24分钟和半秒前。相同的对象用于 goForward()

注意:来自 Innmind\TimeContinuum\Earth\Period 命名空间的对象将在超出组件边界时转换值。例如,new Millisecond(121500) 将产生以下结果:milliseconds() === 500seconds() === 1minutes() === 2

为了简化一些常见的操作,此库包含了一些辅助器,例如 EndOfDay,可以像这样使用

use Innmind\TimeContinuum\Earth\Move\EndOfDay;

$endOfDay = new EndOfDay;
$endOfDay($clock->now()); // will return 2018-04-28 23:59:59.999

查看所有 辅助器 以帮助您穿越时空。

已过期间

有时我们想知道在代码中一个任务耗时多久,我们最终使用 microtime(true) * 1000。这里您可以使用更 优雅 的方式来完成它(并且是一个单元测试友好的方式)

$start = $clock->now();
//run some code...
$duration = $clock
    ->now()
    ->elapsedSince($start)
    ->milliseconds();

如果您想要一个更易理解的持续时间,如果它在秒以上,您可以重用 new Millisecond($duration)

日期格式化

为了格式化一个 PointInTime,您需要创建一个实现 Format 的类。这样做是为了确保日期格式始终有一个名称(并防止您在代码库中到处使用 魔法字符串)。

所有描述为 \DateTime 常量的格式都已经作为格式提供。

重要:在这里,ISO8601 真正遵守ISO格式,与 \DateTime::ISO8601 相比。