From 5ef9eedb5d32e0999b18ef0d0c18d463c419cf71 Mon Sep 17 00:00:00 2001 From: rlanvin Date: Fri, 22 Apr 2022 10:16:25 +0200 Subject: [PATCH] Fix #104 remove microseconds from date input --- CHANGELOG.md | 12 +++++++++++- src/RRule.php | 3 +-- src/RRuleTrait.php | 16 ++++++++++++++++ tests/RRuleTest.php | 18 ++++++++++++++++++ 4 files changed, 46 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 54b5aec..8cb3df1 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## [Unreleased] + +## [2.3.1] - 2022-04-22 + +### Fixed + +- Fix microseconds not always removed from dtstart, causing date comparison issues with specific date input [#104](https://github.com/rlanvin/php-rrule/issues/104) + ## [2.3.0] - 2021-10-25 ### Added @@ -215,7 +223,9 @@ - First release, everything before that was unversioned (`dev-master` was used). -[Unreleased]: https://github.com/rlanvin/php-rrule/compare/v2.2.2...HEAD +[Unreleased]: https://github.com/rlanvin/php-rrule/compare/v2.3.1...HEAD +[2.3.1]: https://github.com/rlanvin/php-rrule/compare/v2.3.0...v2.3.1 +[2.3.0]: https://github.com/rlanvin/php-rrule/compare/v2.2.2...v2.3.0 [2.2.2]: https://github.com/rlanvin/php-rrule/compare/v2.2.1...v2.2.2 [2.2.1]: https://github.com/rlanvin/php-rrule/compare/v2.2.0...v2.2.1 [2.2.0]: https://github.com/rlanvin/php-rrule/compare/v2.1.0...v2.2.0 diff --git a/src/RRule.php b/src/RRule.php index 0c3889c..c45b7ae 100755 --- a/src/RRule.php +++ b/src/RRule.php @@ -1391,7 +1391,7 @@ class RRule implements RRuleInterface $timeset = $this->timeset; } else { - // initialize empty if it's not going to occurs on the first iteration + // initialize empty if it's not going to occur on the first iteration if ( ($this->freq >= self::HOURLY && $this->byhour && ! in_array($hour, $this->byhour)) || ($this->freq >= self::MINUTELY && $this->byminute && ! in_array($minute, $this->byminute)) @@ -1563,7 +1563,6 @@ class RRule implements RRuleInterface return; } - // next($timeset); if ($occurrence >= $dtstart) { // ignore occurrences before DTSTART if ($this->count && $total >= $this->count) { $this->total = $total; diff --git a/src/RRuleTrait.php b/src/RRuleTrait.php index d68e3a7..490b824 100755 --- a/src/RRuleTrait.php +++ b/src/RRuleTrait.php @@ -204,6 +204,22 @@ trait RRuleTrait else { $date = clone $date; // avoid reference problems } + + // ensure there is no microseconds in the DateTime object even if + // the input contained microseconds, to avoid date comparison issues + // (see #104) + if (version_compare(PHP_VERSION, '7.1.0') < 0) { + $date = new \DateTime($date->format('Y-m-d H:i:s'), $date->getTimezone()); + } + else { + $date->setTime( + $date->format('H'), + $date->format('i'), + $date->format('s'), + 0 + ); + } + return $date; } } \ No newline at end of file diff --git a/tests/RRuleTest.php b/tests/RRuleTest.php index 362ff63..f54090f 100755 --- a/tests/RRuleTest.php +++ b/tests/RRuleTest.php @@ -2827,6 +2827,24 @@ class RRuleTest extends TestCase ], $occurrences, 'DateTimeImmutable produces valid results'); } + /** + * Test bug #104 + * @see https://github.com/rlanvin/php-rrule/issues/104 + */ + public function testMicrosecondsAreRemovedFromInput() + { + $dtstart = '2022-04-22 12:00:00.5'; + $rule = new RRule([ + 'dtstart' => $dtstart, + 'freq' => 'daily', + 'interval' => 1, + 'count' => 1 + ]); + $this->assertTrue($rule->occursAt('2022-04-22 12:00:00')); + $this->assertTrue($rule->occursAt('2022-04-22 12:00:00.5')); + $this->assertEquals(date_create('2022-04-22 12:00:00'), $rule[0]); + } + /////////////////////////////////////////////////////////////////////////////// // Array access and countable interfaces