DateTimeComparator.php 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. <?php declare(strict_types=1);
  2. /*
  3. * This file is part of sebastian/comparator.
  4. *
  5. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace SebastianBergmann\Comparator;
  11. use function abs;
  12. use function assert;
  13. use function floor;
  14. use function sprintf;
  15. use DateInterval;
  16. use DateTime;
  17. use DateTimeImmutable;
  18. use DateTimeZone;
  19. final class DateTimeComparator extends ObjectComparator
  20. {
  21. public function accepts(mixed $expected, mixed $actual): bool
  22. {
  23. return ($expected instanceof DateTime || $expected instanceof DateTimeImmutable) &&
  24. ($actual instanceof DateTime || $actual instanceof DateTimeImmutable);
  25. }
  26. /**
  27. * @param array<mixed> $processed
  28. *
  29. * @throws ComparisonFailure
  30. */
  31. public function assertEquals(mixed $expected, mixed $actual, float $delta = 0.0, bool $canonicalize = false, bool $ignoreCase = false, array &$processed = []): void
  32. {
  33. assert($expected instanceof DateTime || $expected instanceof DateTimeImmutable);
  34. assert($actual instanceof DateTime || $actual instanceof DateTimeImmutable);
  35. $absDelta = abs($delta);
  36. $delta = new DateInterval(sprintf('PT%dS', $absDelta));
  37. $delta->f = $absDelta - floor($absDelta);
  38. $actualClone = (clone $actual)
  39. ->setTimezone(new DateTimeZone('UTC'));
  40. $expectedLower = (clone $expected)
  41. ->setTimezone(new DateTimeZone('UTC'))
  42. ->sub($delta);
  43. $expectedUpper = (clone $expected)
  44. ->setTimezone(new DateTimeZone('UTC'))
  45. ->add($delta);
  46. if ($actualClone < $expectedLower || $actualClone > $expectedUpper) {
  47. throw new ComparisonFailure(
  48. $expected,
  49. $actual,
  50. $expected->format('Y-m-d\TH:i:s.uO'),
  51. $actual->format('Y-m-d\TH:i:s.uO'),
  52. 'Failed asserting that two DateTime objects are equal.',
  53. );
  54. }
  55. }
  56. }