Skip to content

Commit 48d4716

Browse files
authored
Merge pull request #582 from phil-davis/by-year-day-436
Fix bug in by year day
2 parents 86d8c52 + 408b591 commit 48d4716

File tree

2 files changed

+89
-24
lines changed

2 files changed

+89
-24
lines changed

lib/Recur/RRuleIterator.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -602,11 +602,12 @@ protected function nextYearly()
602602
// loop through all YearDay and Days to check all the combinations
603603
foreach ($this->byYearDay as $byYearDay) {
604604
$date = clone $this->currentDate;
605-
$date = $date->setDate($currentYear, 1, 1);
606605
if ($byYearDay > 0) {
607-
$date = $date->add(new \DateInterval('P'.$byYearDay.'D'));
606+
$date = $date->setDate($currentYear, 1, 1);
607+
$date = $date->add(new \DateInterval('P'.($byYearDay - 1).'D'));
608608
} else {
609-
$date = $date->sub(new \DateInterval('P'.abs($byYearDay).'D'));
609+
$date = $date->setDate($currentYear, 12, 31);
610+
$date = $date->sub(new \DateInterval('P'.abs($byYearDay + 1).'D'));
610611
}
611612

612613
if ($date > $this->currentDate && in_array($date->format('N'), $dayOffsets)) {

tests/VObject/Recur/RRuleIteratorTest.php

Lines changed: 85 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -526,19 +526,36 @@ public function testYearlyByMonthByDay()
526526
);
527527
}
528528

529+
public function testYearlyNewYearsDay()
530+
{
531+
$this->parse(
532+
'FREQ=YEARLY;COUNT=7;INTERVAL=2;BYYEARDAY=1',
533+
'2011-01-01 03:07:00',
534+
[
535+
'2011-01-01 03:07:00',
536+
'2013-01-01 03:07:00',
537+
'2015-01-01 03:07:00',
538+
'2017-01-01 03:07:00',
539+
'2019-01-01 03:07:00',
540+
'2021-01-01 03:07:00',
541+
'2023-01-01 03:07:00',
542+
]
543+
);
544+
}
545+
529546
public function testYearlyByYearDay()
530547
{
531548
$this->parse(
532549
'FREQ=YEARLY;COUNT=7;INTERVAL=2;BYYEARDAY=190',
533-
'2011-07-10 03:07:00',
550+
'2011-07-09 03:07:00',
534551
[
535-
'2011-07-10 03:07:00',
536-
'2013-07-10 03:07:00',
537-
'2015-07-10 03:07:00',
538-
'2017-07-10 03:07:00',
539-
'2019-07-10 03:07:00',
540-
'2021-07-10 03:07:00',
541-
'2023-07-10 03:07:00',
552+
'2011-07-09 03:07:00',
553+
'2013-07-09 03:07:00',
554+
'2015-07-09 03:07:00',
555+
'2017-07-09 03:07:00',
556+
'2019-07-09 03:07:00',
557+
'2021-07-09 03:07:00',
558+
'2023-07-09 03:07:00',
542559
]
543560
);
544561
}
@@ -559,7 +576,7 @@ public function testYearlyByYearDayImmutable()
559576
$parser->next();
560577

561578
$item = $parser->current();
562-
$this->assertEquals($item->format('Y-m-d H:i:s'), '2013-07-10 03:07:00');
579+
$this->assertEquals($item->format('Y-m-d H:i:s'), '2013-07-09 03:07:00');
563580
}
564581

565582
public function testYearlyByYearDayMultiple()
@@ -569,13 +586,13 @@ public function testYearlyByYearDayMultiple()
569586
'2011-07-10 14:53:11',
570587
[
571588
'2011-07-10 14:53:11',
572-
'2011-10-29 14:53:11',
573-
'2014-07-10 14:53:11',
574-
'2014-10-29 14:53:11',
575-
'2017-07-10 14:53:11',
576-
'2017-10-29 14:53:11',
577-
'2020-07-09 14:53:11',
578-
'2020-10-28 14:53:11',
589+
'2011-10-28 14:53:11',
590+
'2014-07-09 14:53:11',
591+
'2014-10-28 14:53:11',
592+
'2017-07-09 14:53:11',
593+
'2017-10-28 14:53:11',
594+
'2020-07-08 14:53:11',
595+
'2020-10-27 14:53:11',
579596
]
580597
);
581598
}
@@ -587,11 +604,11 @@ public function testYearlyByYearDayByDay()
587604
'2001-04-07 14:53:11',
588605
[
589606
'2001-04-07 14:53:11',
590-
'2006-04-08 14:53:11',
591-
'2012-04-07 14:53:11',
592-
'2017-04-08 14:53:11',
593-
'2023-04-08 14:53:11',
594-
'2034-04-08 14:53:11',
607+
'2007-04-07 14:53:11',
608+
'2018-04-07 14:53:11',
609+
'2024-04-06 14:53:11',
610+
'2029-04-07 14:53:11',
611+
'2035-04-07 14:53:11',
595612
]
596613
);
597614
}
@@ -614,6 +631,53 @@ public function testYearlyByYearDayNegative()
614631
);
615632
}
616633

634+
/*
635+
* Verifies that -365 back in the year is usually 1 Jan, but
636+
* in leap years it is 2 Jan.
637+
*/
638+
public function testYearlyByYearDayLargeNegative()
639+
{
640+
$this->parse(
641+
'FREQ=YEARLY;COUNT=8;BYYEARDAY=-365',
642+
'2001-01-01 14:53:11',
643+
[
644+
'2001-01-01 14:53:11',
645+
'2002-01-01 14:53:11',
646+
'2003-01-01 14:53:11',
647+
'2004-01-02 14:53:11',
648+
'2005-01-01 14:53:11',
649+
'2006-01-01 14:53:11',
650+
'2007-01-01 14:53:11',
651+
'2008-01-02 14:53:11',
652+
]
653+
);
654+
}
655+
656+
/*
657+
* Verifies that -366 back in the year is 1 Jan in a leap year
658+
* Interestingly, it goes back to 31 Dec of the previous year
659+
* when not a leap year. The spec says that -366 is valid, and
660+
* makes no mention of it being valid only in a leap year, so
661+
* the behavior seems reasonable.
662+
*/
663+
public function testYearlyByYearDayMaxNegative()
664+
{
665+
$this->parse(
666+
'FREQ=YEARLY;COUNT=8;BYYEARDAY=-366',
667+
'2001-01-01 14:53:11',
668+
[
669+
'2001-01-01 14:53:11',
670+
'2001-12-31 14:53:11',
671+
'2002-12-31 14:53:11',
672+
'2004-01-01 14:53:11',
673+
'2004-12-31 14:53:11',
674+
'2005-12-31 14:53:11',
675+
'2006-12-31 14:53:11',
676+
'2008-01-01 14:53:11',
677+
]
678+
);
679+
}
680+
617681
public function testYearlyByYearDayInvalid390()
618682
{
619683
$this->expectException(InvalidDataException::class);

0 commit comments

Comments
 (0)