Skip to content

Commit

Permalink
Fixes #37: support non canonical timezones in mocks
Browse files Browse the repository at this point in the history
  • Loading branch information
asprega committed May 19, 2023
1 parent dda085e commit d5b17c5
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 7 deletions.
15 changes: 9 additions & 6 deletions src/DateTimeMock/DateTimeMock.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,15 @@ public function __construct(?string $datetime = 'now', ?DateTimeZone $timezone =
if ($timezone !== null && !$isDateTimeStringRelative) {
// When there's a timezone and the provided date is absolute, the timestamp must be calculated with that
// specific timezone in order to mimic behavior of the original \DateTime (which does not modify time).
$this->setTimestamp(
strtotime(
"$datetime {$timezone->getName()}",
ClockMock::getFrozenDateTime()->getTimestamp()
)
);
$timestamp = strtotime("$datetime {$timezone->getName()}", ClockMock::getFrozenDateTime()->getTimestamp());
if ($timestamp === false) {
// Some non-canonical timezone names (e.g. US/Eastern) are not supported by `strtotime`. In these cases,
// apply the same workaround by using the offset in seconds.
$offset = -$timezone->getOffset(new \DateTime('now'));
$timestamp = strtotime("$datetime $offset seconds", ClockMock::getFrozenDateTime()->getTimestamp());
}

$this->setTimestamp($timestamp);
} else {
$this->setTimestamp(strtotime($datetime, ClockMock::getFrozenDateTime()->getTimestamp()));
}
Expand Down
21 changes: 20 additions & 1 deletion tests/ClockMockTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ public function test_DateTime_constructor_with_absolute_mocked_date()
/**
* @see https://github.com/slope-it/clock-mock/issues/26
*/
public function test_DateTime_constructor_with_absolute_date_and_timezone()
public function test_DateTime_constructor_with_absolute_date_and_canonical_timezone()
{
// The mocked date, either aboslute or relative, is irrelevant for this test. Having a mocked date is enough.
ClockMock::freeze(new \DateTime('now'));
Expand All @@ -119,6 +119,25 @@ public function test_DateTime_constructor_with_absolute_date_and_timezone()
$this->assertSame('1986-06-05 12:13:14', $absoluteDateTimeWithTimezone->format('Y-m-d H:i:s'));
}

/**
* @see https://github.com/slope-it/clock-mock/issues/37
* @see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
*/
public function test_DateTime_constructor_with_absolute_date_and_non_canonical_timezone()
{
// The mocked date, either aboslute or relative, is irrelevant for this test. Having a mocked date is enough.
ClockMock::freeze(new \DateTime('now'));

$absoluteDateTimeWithTimezone = new \DateTime(
'1986-06-05 12:13:14',
$usEasternTimezone = new \DateTimeZone('US/Eastern')
);

// Verification: when date is absolute and timezone is specified, the mocked clock should have no effect.
$this->assertEquals($usEasternTimezone, $absoluteDateTimeWithTimezone->getTimezone());
$this->assertSame('1986-06-05 12:13:14', $absoluteDateTimeWithTimezone->format('Y-m-d H:i:s'));
}

/**
* @see https://github.com/slope-it/clock-mock/issues/31
*/
Expand Down

0 comments on commit d5b17c5

Please sign in to comment.