Skip to content

Commit eb23303

Browse files
committed
Refactor summer time start logic into advanceTheDate function
1 parent a70fae5 commit eb23303

File tree

1 file changed

+31
-68
lines changed

1 file changed

+31
-68
lines changed

lib/Recur/RRuleIterator.php

+31-68
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,33 @@ public function fastForward(\DateTimeInterface $dt): void
284284

285285
/* Functions that advance the iterator {{{ */
286286

287+
/**
288+
* Advances currentDate by the interval.
289+
* Takes into account the case where summer time starts and
290+
* the event time on that day may have had to be advanced,
291+
* usually by 1 hour.
292+
*/
293+
protected function advanceTheDate(string $interval): void
294+
{
295+
$hourOfCurrentDate = (int) $this->currentDate->format('G');
296+
$this->currentDate = $this->currentDate->modify($interval);
297+
$hourOfNextDate = (int) $this->currentDate->format('G');
298+
if (0 === $this->hourJump) {
299+
// Remember if the clock time jumped forward on the next date.
300+
// That happens if the next date is a day when summer time starts
301+
// and the event time is in the non-existent hour of the day.
302+
// For example, an event that normally starts at 02:30 will
303+
// have to start at 03:30 on that day.
304+
$this->hourJump = $hourOfNextDate - $hourOfCurrentDate;
305+
} else {
306+
// The hour "jumped" for the previous date, to avoid the non-existent time.
307+
// currentDate got set ahead by (usually) 1 hour on that day.
308+
// Adjust it back for this next occurrence.
309+
$this->currentDate = $this->currentDate->sub(new \DateInterval('PT'.$this->hourJump.'H'));
310+
$this->hourJump = 0;
311+
}
312+
}
313+
287314
/**
288315
* Does the processing for advancing the iterator for hourly frequency.
289316
*/
@@ -298,23 +325,7 @@ protected function nextHourly(): void
298325
protected function nextDaily(): void
299326
{
300327
if (!$this->byHour && !$this->byDay) {
301-
$hourOfCurrentDate = (int) $this->currentDate->format('G');
302-
$this->currentDate = $this->currentDate->modify('+'.$this->interval.' days');
303-
$hourOfNextDate = (int) $this->currentDate->format('G');
304-
if (0 === $this->hourJump) {
305-
// Remember if the clock time jumped forward on the nextDate.
306-
// That happens if nextDate is a day when summer time starts
307-
// and the event time is in the non-existent hour of the day.
308-
// For example, an event that normally starts at 02:30 will
309-
// have to start at 03:30 on that day.
310-
$this->hourJump = $hourOfNextDate - $hourOfCurrentDate;
311-
} else {
312-
// The hour "jumped" for the previous date, to avoid the non-existent time.
313-
// currentDate got set ahead by (usually) one hour on that day.
314-
// Adjust it back for this next occurrence.
315-
$this->currentDate = $this->currentDate->sub(new \DateInterval('PT'.$this->hourJump.'H'));
316-
$this->hourJump = 0;
317-
}
328+
$this->advanceTheDate('+'.$this->interval.' days');
318329

319330
return;
320331
}
@@ -373,23 +384,7 @@ protected function nextDaily(): void
373384
protected function nextWeekly(): void
374385
{
375386
if (!$this->byHour && !$this->byDay) {
376-
$hourOfCurrentDate = (int) $this->currentDate->format('G');
377-
$this->currentDate = $this->currentDate->modify('+'.$this->interval.' weeks');
378-
$hourOfNextDate = (int) $this->currentDate->format('G');
379-
if (0 === $this->hourJump) {
380-
// Remember if the clock time jumped forward on the nextDate.
381-
// That happens if nextDate is a day when summer time starts
382-
// and the event time is in the non-existent hour of the day.
383-
// For example, an event that normally starts at 02:30 will
384-
// have to start at 03:30 on that day.
385-
$this->hourJump = $hourOfNextDate - $hourOfCurrentDate;
386-
} else {
387-
// The hour "jumped" for the previous date, to avoid the non-existent time.
388-
// currentDate got set ahead by (usually) one hour on that day.
389-
// Adjust it back for this next occurrence.
390-
$this->currentDate = $this->currentDate->sub(new \DateInterval('PT'.$this->hourJump.'H'));
391-
$this->hourJump = 0;
392-
}
387+
$this->advanceTheDate('+'.$this->interval.' weeks');
393388

394389
return;
395390
}
@@ -448,23 +443,7 @@ protected function nextMonthly(): void
448443
// occur to the next month. We Must skip these invalid
449444
// entries.
450445
if ($currentDayOfMonth < 29) {
451-
$hourOfCurrentDate = (int) $this->currentDate->format('G');
452-
$this->currentDate = $this->currentDate->modify('+'.$this->interval.' months');
453-
$hourOfNextDate = (int) $this->currentDate->format('G');
454-
if (0 === $this->hourJump) {
455-
// Remember if the clock time jumped forward on the nextDate.
456-
// That happens if nextDate is a day when summer time starts
457-
// and the event time is in the non-existent hour of the day.
458-
// For example, an event that normally starts at 02:30 will
459-
// have to start at 03:30 on that day.
460-
$this->hourJump = $hourOfNextDate - $hourOfCurrentDate;
461-
} else {
462-
// The hour "jumped" for the previous date, to avoid the non-existent time.
463-
// currentDate got set ahead by (usually) one hour on that day.
464-
// Adjust it back for this next occurrence.
465-
$this->currentDate = $this->currentDate->sub(new \DateInterval('PT'.$this->hourJump.'H'));
466-
$this->hourJump = 0;
467-
}
446+
$this->advanceTheDate('+'.$this->interval.' months');
468447
} else {
469448
$increase = 0;
470449
do {
@@ -642,23 +621,7 @@ protected function nextYearly(): void
642621
}
643622

644623
// The easiest form
645-
$hourOfCurrentDate = (int) $this->currentDate->format('G');
646-
$this->currentDate = $this->currentDate->modify('+'.$this->interval.' years');
647-
$hourOfNextDate = (int) $this->currentDate->format('G');
648-
if (0 === $this->hourJump) {
649-
// Remember if the clock time jumped forward on the nextDate.
650-
// That happens if nextDate is a day when summer time starts
651-
// and the event time is in the non-existent hour of the day.
652-
// For example, an event that normally starts at 02:30 will
653-
// have to start at 03:30 on that day.
654-
$this->hourJump = $hourOfNextDate - $hourOfCurrentDate;
655-
} else {
656-
// The hour "jumped" for the previous date, to avoid the non-existent time.
657-
// currentDate got set ahead by (usually) one hour on that day.
658-
// Adjust it back for this next occurrence.
659-
$this->currentDate = $this->currentDate->sub(new \DateInterval('PT'.$this->hourJump.'H'));
660-
$this->hourJump = 0;
661-
}
624+
$this->advanceTheDate('+'.$this->interval.' years');
662625

663626
return;
664627
}

0 commit comments

Comments
 (0)