Last active
September 8, 2022 15:46
-
-
Save drock/6389437 to your computer and use it in GitHub Desktop.
A comparator object for PHPUnit to support asserting that two DateTime objects are logically equaly.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Class DateTimeComparator | |
* | |
* Custom Comparator for PHPUnit to compare two DateTime objects | |
* The default object comparator will report some DateTime object pairs | |
* as not equal even if they are canonically equal because the object | |
* comparator looks a exact object field values. A DateTime object | |
* can have multiple timezone values that represent the same timezone | |
* however. This comparator compares the object's UTC timestamps | |
* | |
*/ | |
class DateTimeComparator extends \PHPUnit_Framework_Comparator | |
{ | |
/** | |
* Returns whether the comparator can compare two values. | |
* | |
* @param mixed $expected The first value to compare | |
* @param mixed $actual The second value to compare | |
* @return boolean | |
*/ | |
public function accepts($expected, $actual) | |
{ | |
return $expected instanceof \DateTime && $actual instanceof \DateTime; | |
} | |
/** | |
* Asserts that two values are equal. | |
* | |
* @param DateTime $expected The first value to compare | |
* @param DateTime $actual The second value to compare | |
* @param float|int $delta The allowed numerical distance between two values to | |
* consider them equal | |
* @param bool $canonicalize If set to TRUE, arrays are sorted before | |
* comparison | |
* @param bool $ignoreCase If set to TRUE, upper- and lowercasing is | |
* ignored when comparing string values | |
* @throws \PHPUnit_Framework_ComparisonFailure Thrown when the comparison | |
* fails. Contains information about the | |
* specific errors that lead to the failure. | |
*/ | |
public function assertEquals($expected, $actual, $delta = 0, $canonicalize = FALSE, $ignoreCase = FALSE) | |
{ | |
/* @var $expected \DateTime */ | |
/* @var $actual \DateTime */ | |
if (abs($expected->getTimestamp() - $actual->getTimestamp()) > $delta) | |
{ | |
throw new PHPUnit_Framework_ComparisonFailure( | |
$expected, | |
$actual, | |
$expected->format(\DateTime::ISO8601), | |
$actual->format(\DateTime::ISO8601) | |
); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//register the comparator with PHPUnit. | |
//This is typically done in your bootstrap file | |
PHPUnit_Framework_ComparatorFactory::getDefaultInstance()->register(new DateTimeComparator()); | |
//in a test... | |
$date1 = new DateTime('2013-01-01 00:00:00', new DateTimeZone('UTC)); | |
$date2 = new DateTime('2012-12-31 19:00:00', new DateTimeZone('America/New_York')); //assuming current DST offest is UTC - 5hrs | |
$this->assertEquals($date1, $date2); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Version for phpunit 7+ (requires php7):
Comments omitted on purpose.