flying/date 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

flying/date

Composer 安装命令:

composer require flying/date

包简介

DateTime generator with support for adjusting current time

README 文档

README

DateTime generator with support for adjusting current time.

Purpose

The main purpose of the library is to assist testing application in time-sensitive scenarios without a need to adjust its code (besides switching to use library itself for creating dates in application).

It is relatively simple to test time-sensitive scenarios for unit tests, but for functional tests it is much harder. Of course, there are plenty of solutions:

  • slope-it/clock-mock looks great, but depends on the PHP extension.
  • lcobucci/clock is very popular, but requires dependency on its own Clock object which would require updates of signatures of functions and methods and types of class properties.
  • Clock mocking in Symfony's PHPUnit bridge only mocks time-related functions, not \DateTimeInterface based classes.

This library aims to keep the number of required changes at a level comparable with other solutions. Required updates for the code are listed below and basically limited to change of \DateTime constructor methods into call to static method of the different class. It also simplifies testing cases when code execution took some time and this time change used somehow (think of performance tracking as an example).

General information

Whole API is exposed as a single \Flying\Date\Date class. API is provided as a set of static methods to make sure that they will be accessible from any part of code without a need to introduce any kind of additional dependencies.

Generated date objects are limited to \DateTimeImmutable. Upcoming ClockInterface from PSR-20 also provides only immutable dates.

Main API methods - now and from returning \DateTimeImmutable instances, whose values can be adjusted relative to the actual current time by providing a time shifting interval using adjust method.

Usage in application

In order to benefit from the ability to use time shifting, it is required to update parts of your code which creates new instances of the \DateTime or \DateTimeInterval objects.

To get \DateTime object it is required to convert obtained \DateTimeInterval object:

$mutableDateTime = \DateTime::createFromImmutable($immutableDateTime); 

Creating objects for current time and default timezone

  • Before: new \DateTimeImmutable()
  • After: \Flying\Date\Date::now()

Creating objects for arbitrary time and / or timezone

Creating from string

  • Before: new \DateTimeImmutable('2022-08-01', new \DateTimeZone('UTC'))
  • After: \Flying\Date\Date::from('2022-08-01', 'UTC')

Creating from format

  • Before: \DateTimeImmutable::createFromFormat(\DateTimeInterface::ATOM, 2022-08-01T12:23:34Z')
  • After: \Flying\Date\Date::fromFormat(\DateTimeInterface::ATOM, '2022-08-01T12:23:34Z')

Usage in tests

In order to test application behavior in different points of time, you need to do two things:

  1. Provide date adjustment value by calling \Flying\Date\Date::adjust() and pass either \DateTimeInterface that represents new target date or \DateInterval to define time shift relatively to the current time. Calling adjust() with no arguments removes date adjustment.
  2. Enable date adjustment by calling \Flying\Date\Date::allowAdjustment(true)

IMPORTANT! You should never use date adjustment in your application's code, ONLY IN TESTS! Use of it in application's code may result in unexpected behavior!

Even in tests, you should limit use of this feature to the tests which actually needs date adjustment functionality and disable it after doing the test.

Simplified configuration using attribute

In order to simplify use of the library and to ensure correct enabling / disabling of the date adjustment functionality in tests - it is possible to use AdjustableDate PHP attribute.

To enable use of the attribute you need to edit your PHPUnit configuration (phpunit.xml) and add test extension:

<extensions>
   <!-- ... other extensions ... -->
   <bootstrap class="Flying\Date\PHPUnit\Extension\DateExtension"/>
</extensions>

Then for test classes or (preferably) test methods that need to use adjustable date functionality you need to add #[AdjustableDate] attribute. It accepts optional configuration parameters:

  • bool $enabled - to control default state of the adjustable date functionality (true by default)
  • \DateTimeZone|string|null $timezone - to define timezone to use by default

Note on microseconds in date adjustment

For time shifting interval and adjusted dates, generated by the now and from methods microseconds part of the resulted date is forcibly set to zero. Date objects, which are generated without a date adjustment, are not affected.

It should be safe because date adjustment is meant to only be used for tests. Testing time shifts with microsecond precision on intervals less than a second is more reliable with use of the usleep(). For larger intervals include of microseconds may introduce difference of the whole second which may cause tests to break from time to time.

API methods

now

Signature:

\Flying\Date\Date::now(): \DateTimeImmutable

Provides the date object for the current date. Either timezone, defined through setTimezone() or PHP default timezone is used.

In case if date adjustment is enabled - returned date will be adjusted by the defined time shifting interval.

from

Signature:

\Flying\Date\Date::from(\DateTimeInterface|\DateInterval|string $date, \DateTimeZone|string|null $timezone = null): \DateTimeImmutable

Create the date object for a given arbitrary point of time from provided date and timezone information. Either given timezone, timezone defined through setTimezone() or PHP default timezone is used. It is allowed to pass valid timezone name as timezone value.

In case if date adjustment is enabled - returned date will be adjusted by the defined time shifting interval.

fromFormat

Signature:

\Flying\Date\Date::fromFormat(string $format, string $datetime, \DateTimeZone|string|null $timezone = null): \DateTimeImmutable|bool

Create the date object for given date string, formatted using given format using given timezone information. Either given timezone, timezone defined through setTimezone() or PHP default timezone is used. It is allowed to pass valid timezone name as timezone value.

In case if date adjustment is enabled - returned date will be adjusted by the defined time shifting interval.

getTimezone

Signature:

\Flying\Date\Date::getTimezone(): \DateTimeZone

Get timezone that is used for creating date objects.

setTimezone

Signature:

\Flying\Date\Date::setTimezone(\DateTimeZone|string|null $timezone = null): void

Defines (or resets) timezone that is used for creating date objects. It is allowed to pass valid timezone name as value.

adjust

Signature:

\Flying\Date\Date::adjust(\DateInterval|\DateTimeInterface|string|null $adjustment = null): void

Defines (or resets) the time shifting interval that is used for date adjusting while creating date objects. It is allowed to define either absolute point of time by passing \DateTimeInterface instance or a time shift relative to the current point of time by passing \DateInterval object.

It is also allowed to pass date formats or date interval definitions.

getAdjustment

Signature:

\Flying\Date\Date::getAdjustment(): ?\DateInterval

Returns currently defined the time shifting interval that is used for date adjusting while creating date objects.

allowAdjustment

Signature:

\Flying\Date\Date::allowAdjustment(bool $status): void

Allows control of the status of date adjustment functionality.

isAdjustmentAllowed

Signature:

\Flying\Date\Date::isAdjustmentAllowed(): bool

Returns current status of date adjustment functionality.

License

Library is licensed under MIT License.

flying/date 适用场景与选型建议

flying/date 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 17 次下载、GitHub Stars 达 0, 最近一次更新时间为 2022 年 08 月 26 日, 在 PHP 生态内属于活跃度较高的组件。

我们在过去多个企业项目中使用过 flying/date 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 flying/date 我们能提供哪些服务?
定制开发 / 二次开发

基于 flying/date 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 17
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 6
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 1
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2022-08-26