Fixed bug #80047 (DatePeriod doesn't warn with custom DateTimeImmutable)#9174
Fixed bug #80047 (DatePeriod doesn't warn with custom DateTimeImmutable)#9174derickr merged 2 commits intophp:PHP-8.0from
Conversation
|
Fine for me 👍 So the warning will appear only after PHP 8.2.0, right? |
|
@kylekatarnls I don't see the point of a warning in 8.2 any more either. What I will likely do is make an RFC to tidy up inheritance with deprecations for PHP 8.3, with potential breaking changes in 9.0. |
|
Ah cool, fine for me. What would be the deprecation in 8.3? I think having new CustomDateTime($date->format('Y-m-d H:i:s.u'), $date->getTimezone()); |
cmb69
left a comment
There was a problem hiding this comment.
Makes sense to me. Thank you!
This would need to be cherry picked into the 8.0.22 and 8.1.9 branches by the release managers (/cc @carusogabriel, @ramsey, @patrickallaert).
Why? Is this fix so urgent, that we can't wait four more weeks, so we have it in an RC?
|
@cmb69 It's because the wrong fix (ie, BC breaking) is in the current RC. |
Ah, in this case the fix should indeed be cherry-picked into the release branches. |
|
This introduced a bug in our production apps since the linux repository downloaded the version 8.1.9 automatically and this has a breaking change if you typehint the result of the interval $period = new DatePeriod(new Carbon('2022-09-09'), new DateInterval('P1D'), new Carbon('2022-09-15'));
collect($period)->each(fn(Carbon $date) => $date->dayOfWeek)
// 👆
// This works in PHP 8.1.8 but not in 8.1.9Should we disable auto-update for small versions (hotfixes)? I thought the smallest number would never introduce breaking changes |
That version is not yet released, though. ;) Anyhow, we do our best not to introduce incompatibilities in revisions, but fixing this bug didn't leave us much choice. Note though, that there never was a guarantee that DatePeriod methods or properties would be of a more specific type than |
|
@Lloople using: $period = new CarbonPeriod(new Carbon('2022-09-09'), new DateInterval('P1D'), new Carbon('2022-09-15'));
$period->excludeEndDate();
collect($period)->each(fn(Carbon $date) => $date->dayOfWeek)instead should help. |
|
With this PHP 8.1 seems to switch behavior in the middle in a way that seems to cause regressions. Existing code: $applicationDate = new \Cake\I18n\FrozenTime('2022-07-29');
$terminationDate = new \Cake\I18n\FrozenTime('2022-08-29');
$interval = \DateInterval::createFromDateString('1 week');
$daterange = new \DatePeriod($applicationDate, $interval, $terminationDate);
$periods = [];
foreach ($daterange as $date) {
if ($date == $daterange->start) {
$startDate = $date;
} else {
$startDate = $date->startOfYear();
}
if ($date == $daterange->end) {
$endDate = $date;
} else {
$endDate = $date->endOfYear(); // <----- Error happens over here
}
}After 8.1.9 it now fails since $date is now DateTimeImmutable "only" instead of the custom FrozenTime object that contains those methods.
Sounds like quite the BC breaking behavior for a 8.1 patch series. |
|
@dereuromark, see https://bugs.php.net/80047 for an explantions why we needed to fix the current behavior, and why we could not do it in a "correct" (and BC preserving) way. I'm aware that this change is bad, but actually nobody should extend |
|
Work-around: foreach ($daterange as $rawDate) {
$date = new \Cake\I18n\FrozenTime($rawDate->format('Y-m-d H:i:s.u', $rawDate->getTimezone()); |
|
Couldnt this be internal behavior of the above object? |
|
@derickr I would love that too. 😇 It sounds feasible as public function current(): DateTImeInterface
{
$date = ...;
$expectedClass = get_class($this->start);
if (get_class($date) === $expectedClass) {
return $date;
}
return new $expectedClass($date->format('Y-m-d H:i:s.u', $date->getTimezone());
}but in C. |
The problem is that the signature of the subclass' constructor is not know (well, there is reflection, but still, which argument values should be passed?) To make that work,
|
|
We were bitten by this change as well unfortunately on multiple applications. With Wouldn't it have been better to include this bug fix from 8.2.0 and up? |
@kylekatarnls — Would this be a better solution, return the original base class for the iterator created DateTime/DateTimeImmutable objects? It doesn't suffer from the broken-constructor issue, and neither does it invalidate LSP (as it says nothing about iterator-returned objects).
This would need to be cherry picked into the 8.0.22 and 8.1.9 branches by the release managers (/cc @carusogabriel, @ramsey, @patrickallaert).