Skip to content

Commit

Permalink
Merge pull request #356 from cakephp/trait-cleanup
Browse files Browse the repository at this point in the history
3.x Clean up traits and remove methods from Date
  • Loading branch information
othercorey authored Dec 8, 2022
2 parents a19d000 + 021042b commit b100f7c
Show file tree
Hide file tree
Showing 13 changed files with 162 additions and 302 deletions.
67 changes: 65 additions & 2 deletions src/Chronos.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,7 @@
*/
class Chronos
{
use Traits\FormattingTrait;
use Traits\RelativeKeywordTrait;
use FormattingTrait;

/**
* @var int
Expand Down Expand Up @@ -208,6 +207,14 @@ class Chronos
*/
protected static ?DifferenceFormatterInterface $diffFormatter = null;

/**
* Regex for relative period.
*
* @var string
*/
// phpcs:disable Generic.Files.LineLength.TooLong
protected static string $relativePattern = '/this|next|last|tomorrow|yesterday|midnight|today|[+-]|first|last|ago/i';

/**
* @var \DateTimeImmutable
*/
Expand Down Expand Up @@ -323,6 +330,62 @@ public static function hasTestNow(): bool
return static::$testNow !== null;
}

/**
* Determine if there is just a time in the time string
*
* @param string|null $time The time string to check.
* @return bool true if there is a keyword, otherwise false
*/
private static function isTimeExpression(?string $time): bool
{
// Just a time
if (is_string($time) && preg_match('/^[0-2]?[0-9]:[0-5][0-9](?::[0-5][0-9](?:\.[0-9]{1,6})?)?$/', $time)) {
return true;
}

return false;
}

/**
* Determine if there is a relative keyword in the time string, this is to
* create dates relative to now for test instances. e.g.: next tuesday
*
* @param string|null $time The time string to check.
* @return bool true if there is a keyword, otherwise false
*/
public static function hasRelativeKeywords(?string $time): bool
{
if (self::isTimeExpression($time)) {
return true;
}
// skip common format with a '-' in it
if ($time && preg_match('/[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}/', $time) !== 1) {
return preg_match(static::$relativePattern, $time) > 0;
}

return false;
}

/**
* Determines if there is no fixed date in the time string.
*
* @param \Cake\Chronos\Chronos|\Cake\Chronos\ChronosDate|\DateTimeInterface|string|null $time The time string to check
* @return bool true if doesn't contain a fixed date
*/
private static function isRelativeOnly(Chronos|ChronosDate|DateTimeInterface|string|null $time): bool
{
if ($time === null) {
return true;
}

if (!is_string($time)) {
return false;
}

// must not contain fixed date before relative keywords or time expression
return preg_match('/[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}/', $time) !== 1;
}

/**
* Get weekend days
*
Expand Down
71 changes: 67 additions & 4 deletions src/ChronosDate.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,7 @@
*/
class ChronosDate
{
use Traits\FormattingTrait;
use Traits\FrozenTimeTrait;
use Traits\TestingAidTrait;
use FormattingTrait;

/**
* Format to use for __toString method when type juggling occurs.
Expand Down Expand Up @@ -272,6 +270,71 @@ public static function diffFormatter(?DifferenceFormatterInterface $formatter =
return static::$diffFormatter = $formatter;
}

/**
* Add an Interval to a Date
*
* Any changes to the time will be ignored and reset to 00:00:00
*
* @param \DateInterval $interval The interval to modify this date by.
* @return static A modified Date instance
*/
public function add(DateInterval $interval): static
{
if ($interval->f > 0 || $interval->s > 0 || $interval->i > 0 || $interval->h > 0) {
throw new InvalidArgumentException('Cannot add intervals with time components');
}
$new = clone $this;
$new->native = $new->native->add($interval)->setTime(0, 0, 0);

return $new;
}

/**
* Subtract an Interval from a Date.
*
* Any changes to the time will be ignored and reset to 00:00:00
*
* @param \DateInterval $interval The interval to modify this date by.
* @return static A modified Date instance
*/
public function sub(DateInterval $interval): static
{
if ($interval->f > 0 || $interval->s > 0 || $interval->i > 0 || $interval->h > 0) {
throw new InvalidArgumentException('Cannot subtract intervals with time components');
}
$new = clone $this;
$new->native = $new->native->sub($interval)->setTime(0, 0, 0);

return $new;
}

/**
* Creates a new instance with date modified according to DateTimeImmutable::modifier().
*
* Attempting to change a time component will raise an exception
*
* @param string $modifier Date modifier
* @return static
*/
public function modify(string $modifier): static
{
if (preg_match('/hour|minute|second/', $modifier)) {
throw new InvalidArgumentException('Cannot modify date objects by time values');
}

$new = clone $this;
$new->native = $new->native->modify($modifier);
if ($new->native === false) {
throw new InvalidArgumentException('Unable to modify date using: ' . $modifier);
}

if ($new->format('H:i:s') !== '00:00:00') {
$new->native = $new->native->setTime(0, 0, 0);
}

return $new;
}

/**
* Sets the date.
*
Expand Down Expand Up @@ -1487,7 +1550,7 @@ public function __isset(string $name): bool
public function __debugInfo(): array
{
$properties = [
'hasFixedNow' => static::hasTestNow(),
'hasFixedNow' => Chronos::hasTestNow(),
'date' => $this->format('Y-m-d'),
];

Expand Down
2 changes: 2 additions & 0 deletions src/DifferenceFormatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
*
* Provides a swappable component for other libraries to leverage.
* when localizing or customizing the difference output.
*
* @internal
*/
class DifferenceFormatter implements DifferenceFormatterInterface
{
Expand Down
5 changes: 3 additions & 2 deletions src/Traits/FormattingTrait.php → src/FormattingTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,16 @@
* @link http://cakephp.org CakePHP(tm) Project
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
namespace Cake\Chronos\Traits;
namespace Cake\Chronos;

use Cake\Chronos\Chronos;
use DateTime;

/**
* Provides string formatting methods for datetime instances.
*
* Expects implementing classes to define static::$toStringFormat
*
* @internal
*/
trait FormattingTrait
{
Expand Down
134 changes: 0 additions & 134 deletions src/Traits/FrozenTimeTrait.php

This file was deleted.

Loading

0 comments on commit b100f7c

Please sign in to comment.