matt-harvey / civil-date-time
PHP的民用日期和时间库
Requires
- php: >=8.1.0
Requires (Dev)
- phpunit/phpunit: ^9.5
README
PHP的民用日期和时间库
动机
民用日期,或民用时间,是指未指定时区的日期和时间。
此类实体不应用于表示时间中的精确、绝对的时刻或时间段。然而,它是一种很好的表示“日历日期”或“时钟时间”概念的方法,正如它在许多日常情境中所使用的。
例如,如果某人在2000年1月1日出生,那么他们通常会每年在1月1日庆祝他们的生日,无论他们当时居住在哪个时区。换句话说,代表他们出生日期的实体“2000年1月1日”,在代表他们的出生日期这一方面,是不受时区限制的。
在软件环境中,这可能很重要,例如,如果我们想向每个用户在他们生日时发送电子邮件,而每个用户可能有一个与他们相关的不同时区。某个用户的时区可能会随时间变化;但他们的出生日期不会。在这里,时区应该与用户相关联——而不是与他们的出生日期相关联。
虽然可以使用标准库的DateTime
或DateTimeImmutable
在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-time
的CivilDate
、CivilTime
和CivilDateTime
相似的LocalDate
、LocalTime
和LocalDateTime
类。它还提供了许多其他日期/时间概念的类,而civil-date-time
没有做——包括ZonedDateTime
作为标准库DateTimeImmutable
的替代品。如果您正在寻找更广泛的日期/时间实用工具集,而不是仅作为标准库的辅助来填补民用日期/时间的空白,您可能会更喜欢它。 - https://github.com/cakephp/chronos提供了一个
Date
类,从概念上讲与civil-date-time
的CivilDate
相似;然而,它扩展了DateTimeImmutable
,因此也携带了来自后者的许多冗余数据和空操作函数。
其他编程语言的民历日期/时间库
贡献
欢迎提交Pull Request、错误报告和建议。请确保单元测试覆盖率得到维护。
您需要安装xdebug
来生成覆盖率报告。
composer test
运行测试套件。