matt-harvey/civil-date-time

PHP的民用日期和时间库

v0.2.1 2022-05-14 21:17 UTC

This package is auto-updated.

Last update: 2024-09-16 02:21:14 UTC


README

Github actions Build Latest Stable Version Total Downloads Latest Unstable Version License PHP Version Require

PHP的民用日期和时间库

动机

民用日期,或民用时间,是指未指定时区的日期和时间。

此类实体不应用于表示时间中的精确、绝对的时刻或时间段。然而,它是一种很好的表示“日历日期”或“时钟时间”概念的方法,正如它在许多日常情境中所使用的。

例如,如果某人在2000年1月1日出生,那么他们通常会每年在1月1日庆祝他们的生日,无论他们当时居住在哪个时区。换句话说,代表他们出生日期的实体“2000年1月1日”,在代表他们的出生日期这一方面,是不受时区限制的。

在软件环境中,这可能很重要,例如,如果我们想向每个用户在他们生日时发送电子邮件,而每个用户可能有一个与他们相关的不同时区。某个用户的时区可能会随时间变化;但他们的出生日期不会。在这里,时区应该与用户相关联——而不是与他们的出生日期相关联。

虽然可以使用标准库的DateTimeDateTimeImmutable在PHP中表示民用日期和时间,但这并不理想,因为它需要关于如何解释附加到此类对象上的时区信息的带外约定。(应该仅仅忽略时区数据吗?应该将日期时间转换为UTC然后忽略其时区吗?或者应该将非UTC的DateTime视为表示民用日期无效?)

一个专门设计的类,通过设计省略时区信息,允许干净、直接地表示民用日期、时间和日期时间对。

有关民用日期、时间和日期时间的其他具体用例,请参阅此评论,该评论与为Go提出的类似库相关。

安装

composer require matt-harvey/civil-date-time

注意,此库仍处于预v1状态,任何版本中都可能有破坏性更改。(尽管,我通常会避免在补丁版本发布中进行破坏性更改。)

用法

提供了三个类

  • CivilDate
  • CivilTime
  • CivilDateTime

这些中的每一个都是不可变的:如CivilDate::addDays()这样的方法总是返回新实例,而不是修改现有实例。

民用日期

use MattHarvey\CivilDateTime\CivilDate;

// 15 March 2022
new CivilDate(2022, 3, 15);

// or...
CivilDate::fromIsoDateStamp('2022-03-15');

// format - signature mirrors \DateTime::format
CivilDate::fromIsoDateStamp('2022-03-15')->format('D j M Y'); // 'Sat 15 Mar 2022'

// convenience method for ISO format
CivilDate::fromIsoDateStamp('2022-03-15')->toIsoDateStamp(); // 2022-03-15
// or just
CivilDate::fromIsoDateStamp('2022-03-15')->__toString(); // 2022-03-15

// converting from standard library \DateTimeInterface to CivilDate
// e.g., the moment that is 1:30pm in UTC on 22 Jan. 2021, falls on 23 January 2021 in Sydney
$dateTime = new DateTimeImmutable('2021-01-22 13:30:01+0');
$sydney = new DateTimeZone('Australia/Sydney');
CivilDate::forMomentInTimezone($dateTime, $sydney); // 23 January 2021

// immutable addition/subtraction of days
CivilDate::fromIsoDateStamp('2022-03-15')->addDays(3); // 18 March 2022
CivilDate::fromIsoDateStamp('2022-03-15')->addDays(-3); // 12 March 2022

// difference in days
$dayA = CivilDate::fromIsoDateStamp('2010-03-05');
$dayB = CivilDate::fromIsoDateStamp('2010-04-05');
CivilDate::diffDays($dayB, $dayA); // 31
CivilDate::diffDays($dayA, $dayB); // -31

// comparison
$dayB->laterThan($dayA); // true

// extracting components
$dayA->getYear(); // 2010
$dayA->getMonth(); // 3
$dayA->getDay(); // 5

民用时间

use MattHarvey\CivilDateTime\CivilTime;

$civilTime = new CivilTime(22, 11, 18);                // 10:11:18 p.m.
CivilTime::from24HoursStamp('22:11:18');               // 10:11:18 p.m.
CivilTime::from12HourClock(10, 11, 18, CivilTime::PM); // 10:11:18 p.m.

$civilTime->get24Hour();                               // 22
$civilTime->get12Hour();                               // 10
$civilTime->getMinute();                               // 11
$civilTime->getSecond();                               // 18
$civilTime->getAmPm();                                 // 'pm'

$civilTime->to24HourStamp();                           // '22:11:18'

$civilTimeB = new CivilTime(22, 11, 19);
$civilTimeB->laterThan($civilTime);                    // true

民用日期/时间

use MattHarvey\CivilDateTime\CivilTime;
use MattHarvey\CivilDateTime\CivilDate;
use MattHarvey\CivilDateTime\CivilDateTime;

$civilDate = new CivilDate(2022, 3, 15);
$civilTime = new CivilTime(22, 11, 18);
$civilDateTime = new CivilDateTime($civilDate, $civilTime); // 10:11:18 p.m. on 15 Mar. 2022
CivilDateTime::fromIsoDateTimeStamp('2022-03-15T22:11:18');

$sydney = new DateTimeZone('Australia/Sydney');
$civilDateTime = new DateTimeImmutable('2021-06-26 20:34:05+10');
CivilDateTime::forMomentInTimezone($dateTime, $sydney); // 26 Jun. 2021, 8:34:05pm

// convert back
$civilDateTime->toDateTimeImmutable('Australia/Sydney'); // 26 Jun. 2021, 8:34:05pm, Australia/Sydney
// or
$civilDateTime->toDateTimeImmutable('Australia/Perth');  // 26 Jun. 2021, 8:34:05pm, Australia/Perth

其他PHP库中的民用日期/时间

  • https://github.com/brick/date-time提供了与civil-date-timeCivilDateCivilTimeCivilDateTime相似的LocalDateLocalTimeLocalDateTime类。它还提供了许多其他日期/时间概念的类,而civil-date-time没有做——包括ZonedDateTime作为标准库DateTimeImmutable的替代品。如果您正在寻找更广泛的日期/时间实用工具集,而不是仅作为标准库的辅助来填补民用日期/时间的空白,您可能会更喜欢它。
  • https://github.com/cakephp/chronos提供了一个Date类,从概念上讲与civil-date-timeCivilDate相似;然而,它扩展了DateTimeImmutable,因此也携带了来自后者的许多冗余数据和空操作函数。

其他编程语言的民历日期/时间库

贡献

欢迎提交Pull Request、错误报告和建议。请确保单元测试覆盖率得到维护。

您需要安装xdebug来生成覆盖率报告。

composer test运行测试套件。