Skip to content

Commit 53e6692

Browse files
authored
Merge pull request #229 from Kharhamel/DatePeriodBug
added a test to document the bug and methods to work around it
2 parents 0094669 + 3ce6d9f commit 53e6692

File tree

2 files changed

+40
-3
lines changed

2 files changed

+40
-3
lines changed

generator/tests/DateTimeImmutableTest.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,4 +165,35 @@ public function testEquals(): void
165165
$this->assertEquals($phpDateTime, $safeDateTime2);
166166
$this->assertEquals($safeDateTime1, $safeDateTime2);
167167
}
168+
169+
//DatePeriod corrupts our DateTimeImmutable by setting their inner to null.
170+
//This bug cannot be solved without editing DatePeriod itself.
171+
public function testDatePeriodBug(): void
172+
{
173+
$start = new \Safe\DateTimeImmutable('2020-01-01');
174+
$end = (new \Safe\DateTimeImmutable('2020-01-03'))->modify('+1 day');
175+
$datePeriod = new \DatePeriod($start, new \DateInterval('P1D'), $end);
176+
177+
/** @var DateTimeImmutable $date */
178+
foreach ($datePeriod as $date) {
179+
$this->expectException(\TypeError::class);
180+
$this->assertNull($date->getInnerDateTime());
181+
}
182+
183+
}
184+
185+
public function testSwitchBetweenRegularAndSafe(): void
186+
{
187+
$d = new \DateTimeImmutable('2019-01-01');
188+
$d2 = \Safe\DateTimeImmutable::createFromRegular($d);
189+
$d3 = $d2->getInnerDateTime();
190+
$this->assertSame($d->format('Y-m-d H:i:s.u'), $d3->format('Y-m-d H:i:s.u'));
191+
}
192+
193+
public function testSwitchBetweenRegularAndSafe2(): void
194+
{
195+
$d = new \Safe\DateTimeImmutable('2019-01-01');
196+
$d2 = \Safe\DateTimeImmutable::createFromRegular($d->getInnerDateTime());
197+
$this->assertSame($d->format('Y-m-d H:i:s.u'), $d2->format('Y-m-d H:i:s.u'));
198+
}
168199
}

lib/DateTimeImmutable.php

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,20 @@ public function __construct($time = 'now', $timezone = null)
3232
$this->innerDateTime = new parent($time, $timezone);
3333
}
3434

35-
//switch from regular datetime to safe version
36-
private static function createFromRegular(\DateTimeImmutable $datetime): self
35+
//switch between regular datetime and safe version
36+
public static function createFromRegular(\DateTimeImmutable $datetime): self
3737
{
3838
$safeDatetime = new self($datetime->format('Y-m-d H:i:s.u'), $datetime->getTimezone()); //we need to also update the wrapper to not break the operators '<' and '>'
39-
$safeDatetime->innerDateTime = $datetime;
39+
$safeDatetime->innerDateTime = $datetime; //to make sure we don't lose information because of the format().
4040
return $safeDatetime;
4141
}
4242

43+
//usefull if you need to switch back to regular DateTimeImmutable (for example when using DatePeriod)
44+
public function getInnerDateTime(): \DateTimeImmutable
45+
{
46+
return $this->innerDateTime;
47+
}
48+
4349
/////////////////////////////////////////////////////////////////////////////
4450
// overload functions with false errors
4551

0 commit comments

Comments
 (0)