gzhegow / calendar
此包最新版本(1.2.0)没有可用的许可证信息。
1.2.0
2024-09-01 00:44 UTC
Requires
- php: ^7.2
- ext-json: *
README
这是什么
在PHP中处理日期简直就是地狱。每个操作都需要三到四行代码来转换日期,每个操作都可能抛出异常,每个操作在PHPStorm中都会亮起警告...
这个包旨在使日期操作更加方便。此外,您还可以查看如何合理地继承PHP中内置的糟糕功能,以进行管理或添加自己的功能。
美好的旧时光
一开始,你只是使用Date类,并确信只需“正确操作”。
然后你了解了Immutable,意识到复杂性翻倍,直到你弄清楚何时选择哪个。你开始将一个类转换为另一个,并会遇到精心设置的陷阱,例如异常和PHP版本兼容性问题。
然后你了解了Laravel框架,它在其核心使用了Carbon包,初始化时花费了60毫秒。你想摆脱它,却无法做到。然后你才能做到)
当你最终摆脱了它时,你希望API中的日期格式能被前端轻松解析,而且不需要配置整个symfony/serializer
。你开始从现有类中继承,并意识到一半的函数仍然返回内置对象,并且你的序列化被忽略了。
不幸的是,日期不仅涉及操作,还涉及在内部存储状态,并且经常在小数秒上出错。要编写稳定的代码,需要非常小心。
这是一个关于面向对象编程是另一场灾难的故事...有时你需要像JavaScript一样操作——增加对象的功能,使用组合...同时要理解组合将你从数据结构中解耦,并绑定到行为上。总的来说,每天都像是在跳一场狂欢舞。
安装
composer require gzhegow/calendar;
示例
<?php use Gzhegow\Calendar\Lib; use Gzhegow\Calendar\Calendar; require_once __DIR__ . '/vendor/autoload.php'; // > настраиваем PHP ini_set('memory_limit', '32M'); // > настраиваем обработку ошибок error_reporting(E_ALL); set_error_handler(function ($errno, $errstr, $errfile, $errline) { if (error_reporting() & $errno) { throw new \ErrorException($errstr, -1, $errno, $errfile, $errline); } }); set_exception_handler(function ($e) { var_dump(Lib::php_dump($e)); var_dump($e->getMessage()); var_dump(($e->getFile() ?? '{file}') . ': ' . ($e->getLine() ?? '{line}')); die(); }); // > создаем календарь $calendar = new Calendar(); // > можно изменить классы дат на свои собственные реализации // \Gzhegow\Calendar\Type::setInstance(new \Gzhegow\Calendar\Type()); // > создаем дату $tests[ '_calendar_date' ] = $calendar->parseDateTime($datetime = 'now', $formats = null, $timezoneIfParsed = null); Lib::assert_true('is_a', [ $tests[ '_calendar_date' ], DateTime::class ]); // > создаем/распознаем дату $tests[ '_calendar_date_immutable' ] = $calendar->parseDateTimeImmutable($datetime = 'now', $formats = null, $timezoneIfParsed = null); Lib::assert_true('is_a', [ $tests[ '_calendar_date_immutable' ], DateTimeImmutable::class ]); // > проводим действия над датой, чтобы убедится что Immutable работает $tests[ '_calendar_date_immutable_add' ] = $tests[ '_calendar_date_immutable' ]->add(new \DateInterval('P1D')); $tests[ '_calendar_date_immutable_sub' ] = $tests[ '_calendar_date_immutable' ]->sub(new \DateInterval('P1D')); $tests[ '_calendar_date_immutable_modify' ] = $tests[ '_calendar_date_immutable' ]->modify('+ 10 hours'); Lib::assert_true('is_a', [ $tests[ '_calendar_date_immutable_add' ], DateTimeImmutable::class ]); Lib::assert_true('is_a', [ $tests[ '_calendar_date_immutable_sub' ], DateTimeImmutable::class ]); Lib::assert_true('is_a', [ $tests[ '_calendar_date_immutable_modify' ], DateTimeImmutable::class ]); if ($tests[ '_calendar_date_immutable_add' ] === $tests[ '_calendar_date_immutable_sub' ]) throw new \RuntimeException(); if ($tests[ '_calendar_date_immutable_sub' ] === $tests[ '_calendar_date_immutable_modify' ]) throw new \RuntimeException(); if ($tests[ '_calendar_date_immutable_add' ] === $tests[ '_calendar_date_immutable_modify' ]) throw new \RuntimeException(); // > создает дату "сейчас", просто alias для _calendar_date($date) $tests[ '_calendar_now' ] = $calendar->now($timezone = null); $tests[ '_calendar_now_immutable' ] = $calendar->nowImmutable($timezone = null); Lib::assert_true('is_a', [ $tests[ '_calendar_now' ], DateTime::class ]); Lib::assert_true('is_a', [ $tests[ '_calendar_now_immutable' ], DateTimeImmutable::class ]); // > создает/распознает временную зону $tests[ '_calendar_timezone' ] = $calendar->parseDateTimeZone($timezone = 'UTC'); Lib::assert_true('is_a', [ $tests[ '_calendar_timezone' ], DateTimeZone::class ]); Lib::assert_true(function () use ($tests) { return 'UTC' === $tests[ '_calendar_timezone' ]->getName(); }); // > создает/распознает интервал $tests[ '_calendar_interval' ] = $calendar->parseDateInterval($interval = 'P0D', $formats = null); Lib::assert_true('is_a', [ $tests[ '_calendar_interval' ], DateInterval::class ]); Lib::assert_true(function () use ($tests) { return 'P0D' === $tests[ '_calendar_interval' ]->jsonSerialize(); }); // > возвращает разницу между датами $now = $calendar->nowImmutable(); $past = $now->modify('- 10 hours'); $tests[ '_calendar_diff' ] = $calendar->diff($now, $past, $absolute = false); // : ?DateInterval; Lib::assert_true('is_a', [ $tests[ '_calendar_diff' ], DateInterval::class ]); Lib::assert_true(function () use ($tests) { return 'PT10H' === $tests[ '_calendar_diff' ]->jsonSerialize(); }); var_dump(json_encode($tests, JSON_PRETTY_PRINT)); // string(730) "{ // "_calendar_date": "2024-05-09T19:47:39.074+03:00", // "_calendar_date_immutable": "2024-05-09T19:47:39.074+03:00", // "_calendar_date_immutable_add": "2024-05-10T19:47:39.074+03:00", // "_calendar_date_immutable_sub": "2024-05-08T19:47:39.074+03:00", // "_calendar_date_immutable_modify": "2024-05-10T05:47:39.074+03:00", // "_calendar_now": "2024-05-09T19:47:39.074+03:00", // "_calendar_now_immutable": "2024-05-09T19:47:39.074+03:00", // "_calendar_timezone": "UTC", // "_calendar_interval": "P0D", // "_calendar_diff": "PT10H" // }" $dump = []; foreach ( $tests as $i => $test ) { $dump[ $i ] = Lib::php_dump($test); } var_dump($dump); // array(13) { // ["_calendar_date"]=> // string(48) "{ object(Gzhegow\Calendar\Struct\DateTime # 8) }" // ["_calendar_date_immutable"]=> // string(57) "{ object(Gzhegow\Calendar\Struct\DateTimeImmutable # 9) }" // ["_calendar_date_immutable_add"]=> // string(58) "{ object(Gzhegow\Calendar\Struct\DateTimeImmutable # 10) }" // ["_calendar_date_immutable_sub"]=> // string(58) "{ object(Gzhegow\Calendar\Struct\DateTimeImmutable # 11) }" // ["_calendar_date_immutable_modify"]=> // string(57) "{ object(Gzhegow\Calendar\Struct\DateTimeImmutable # 7) }" // ["_calendar_now"]=> // string(49) "{ object(Gzhegow\Calendar\Struct\DateTime # 12) }" // ["_calendar_now_immutable"]=> // string(58) "{ object(Gzhegow\Calendar\Struct\DateTimeImmutable # 13) }" // string(58) "{ object(Gzhegow\Calendar\Struct\DateTimeImmutable # 15) }" // ["_calendar_timezone"]=> // string(53) "{ object(Gzhegow\Calendar\Struct\DateTimeZone # 16) }" // ["_calendar_interval"]=> // string(53) "{ object(Gzhegow\Calendar\Struct\DateInterval # 17) }" // ["_calendar_diff"]=> // string(53) "{ object(Gzhegow\Calendar\Struct\DateInterval # 20) }" // }