solodkiy/brick-date-time

日期和时间库

资助包维护!
BenMorel

103.0.0 2024-05-03 22:16 UTC

README

一组强大的不可变类,用于处理日期和时间。

Build Status Coverage Status Latest Stable Version Total Downloads License

简介

该库在PHP的本地日期时间类之上构建了一个广泛的API,并添加了如LocalDateLocalTimeYearMonthMonthDay等缺失的概念。

这些类遵循ISO 8601标准来表示日期和时间概念。

此组件遵循Java的JSR 310(日期和时间API)规范的一个重要部分。不过,由于技术或实际原因存在一些差异,因此不要期望类和方法名称完全匹配。

所有类都是不可变的,可以安全地传递而不会受到影响。

安装

此库可以通过Composer安装

composer require solodkiy/brick-date-time

要求

此库需要PHP 8.1或更高版本。

关于此分支

虽然此库仍在开发中,但经过充分测试,应该足够稳定,可以在生产环境中使用。

新功能

  • UtcDateTime
  • Instant::toUtcDateTime()方法
  • LocalDateTime::fromSqlFormat()方法
  • LocalDateTime::toSqlFormat()方法
  • ZonedDateTime::fromSqlFormat()方法
  • ZonedDateTime::toSqlFormat()方法
  • ZonedDateTime::toUtcDateTime()方法
  • ZonedDateTime::toNativeFormat()方法
  • ZonedDateTime::toUtcSqlFormat()方法

与brick/date-time的兼容性

概述

主要类

以下类/枚举表示日期和时间概念

  • DayOfWeek:一周中的某天,如星期一(枚举)
  • Duration:以秒和纳秒为单位的持续时间
  • Instant:时间点,具有纳秒精度
  • Interval:两个时间点之间的时间段
  • LocalDate:一个独立的日期,如2014-08-31
  • LocalDateRange:一个包含本地日期的范围,如2014-01-01/2014-12-31
  • LocalDateTime:不带时区的日期和时间,如2014-08-31T10:15:30
  • LocalTime:一个独立的日期,如10:15:30
  • Month:一年中的某月,如一月(枚举)
  • MonthDay:一个月份和一天的组合,不带年份,如--12-31
  • Period:基于日期的时间量,如'2年,3个月和4天'
  • TimeZoneOffset:基于偏移量的时区,如+01:00
  • TimeZoneRegion:基于区域的时区,如Europe/London
  • Year:公历中的某年
  • YearMonth:年和月的组合,如2014-08
  • ZonedDateTime:带时区的日期和时间,如2014-08-31T10:15:30+01:00。此类在概念上等同于本地的DateTime
  • UtcDateTime:带UTC时区的日期和时间,如2014-08-31T10:15:30Z。此类是ZonedDateTime的子类

这些类属于Brick\DateTime命名空间。

时钟

所有对象都从Clock实现读取当前时间。以下是一些可用的实现:

  • SystemClock返回系统时间;它是默认时钟
  • FixedClock:返回预配置的时间
  • OffsetClock:向另一个时钟添加偏移量
  • ScaleClock:通过缩放因子使另一个时钟快进

这些类属于Brick\DateTime\Clock命名空间。

在您的应用程序中,您很可能永远不会接触默认设置,总是使用默认时钟

use Brick\DateTime\LocalDate;
use Brick\DateTime\TimeZone;

echo LocalDate::now(TimeZone::utc()); // 2017-10-04

然而,在您的测试中,您可能需要将当前时间设置为在已知条件下测试您的应用程序。为此,您可以显式地将一个Clock实例传递给now()方法

use Brick\DateTime\Clock\FixedClock;
use Brick\DateTime\Instant;
use Brick\DateTime\LocalDate;
use Brick\DateTime\TimeZone;

$clock = new FixedClock(Instant::of(1000000000));
echo LocalDate::now(TimeZone::utc(), $clock); // 2001-09-09

或者,您还可以更改所有日期时间类的默认时钟。除非提供显式的时钟,否则所有如now()之类的函数都将使用您提供的默认时钟

use Brick\DateTime\Clock\FixedClock;
use Brick\DateTime\DefaultClock;
use Brick\DateTime\Instant;
use Brick\DateTime\LocalDate;
use Brick\DateTime\TimeZone;

DefaultClock::set(new FixedClock(Instant::of(1000000000)));
echo LocalDate::now(TimeZone::utc()); // 2001-09-09

DefaultClock::reset(); // do not forget to reset the clock to the system clock!

此外,还有一些有用的快捷方法,可以借鉴timecop,在您的测试中使用时钟

  • freeze()将时间冻结到特定的时刻
  • travelTo()跳转到时间中的Instant,但允许时间从那里继续前进
  • travelBy()通过Duration在时间中移动,这可能是向前(正数)或向后(负数)
  • scale()使时间以给定的速度移动

将时间冻结到特定点

use Brick\DateTime\DefaultClock;
use Brick\DateTime\Instant;

DefaultClock::freeze(Instant::of(2000000000));

$a = Instant::now(); sleep(1);
$b = Instant::now();

echo $a, PHP_EOL; // 2033-05-18T03:33:20Z
echo $b, PHP_EOL; // 2033-05-18T03:33:20Z

DefaultClock::reset();

跳转到特定的时间点

use Brick\DateTime\DefaultClock;
use Brick\DateTime\Instant;

DefaultClock::travelTo(Instant::of(2000000000));
$a = Instant::now(); sleep(1);
$b = Instant::now();

echo $a, PHP_EOL; // 2033-05-18T03:33:20.000342Z
echo $b, PHP_EOL; // 2033-05-18T03:33:21.000606Z

DefaultClock::reset();

使时间以给定的速度移动

use Brick\DateTime\DefaultClock;
use Brick\DateTime\Instant;

DefaultClock::travelTo(Instant::of(2000000000));
DefaultClock::scale(60); // 1 second becomes 60 seconds

$a = Instant::now(); sleep(1);
$b = Instant::now();

echo $a, PHP_EOL; // 2033-05-18T03:33:20.00188Z
echo $b, PHP_EOL; // 2033-05-18T03:34:20.06632Z

DefaultClock::reset();

如您所见,您甚至可以将travelTo()scale()方法组合起来。

请在每个测试之后都非常小心地重置默认时钟!如果您使用PHPUnit,可以在tearDown()方法中做这件事。

异常

以下异常可能会抛出:

  • 当执行非法操作时抛出Brick\DateTime\DateTimeException
  • parse()无效的字符串表示时抛出Brick\DateTime\Parser\DateTimeParseException

Doctrine映射

您可以在您的Doctrine实体中使用brick/date-time类型,使用brick/date-time-doctrine包。

贡献

在提交拉取请求之前,您可以使用以下工具检查代码。如果以下任何工具报告了任何问题,您的CI构建将失败。

首先,安装依赖项

composer install

单元测试

运行PHPUnit测试

vendor/bin/phpunit

静态分析

运行Psalm静态分析

vendor/bin/psalm --no-cache

编码风格

在单独的文件夹中安装Easy Coding Standard

composer install --working-dir=tools/ecs

运行编码风格分析检查

tools/ecs/vendor/bin/ecs check --config tools/ecs/ecs.php

或直接修复发现的问题

tools/ecs/vendor/bin/ecs check --config tools/ecs/ecs.php --fix

Rector自动重构

在单独的文件夹中安装Rector

composer install --working-dir=tools/rector

运行自动重构

tools/rector/vendor/bin/rector --config tools/rector/rector.php