DateInterval issues with negative directions
Nobody has claimed this yet.
- Dominant language
- C
- Stars
- 40.4k
- Forks
- 8.1k
- Avg merge
- 2d 13h
- Merged PRs (30d)
- 96
Description
Description
I am going to put a few connected issues I have noticed around DateInterval and DatePeriod into a single report:
1: DateInterval->invert is "readonly"
DateInterval:::__construct() only allows positive $duration e.g. P1D not P-1D (I appreciate this is the correct behaviour as it is based around the ISO8601 which has no concept of negative periods). However... the DateInterval->invert which allows the period to be reversed can only be changed by manually setting that property and the docs explicitly say:
The available properties listed below depend on PHP version, and should be considered as readonly.
It would be good to be able to change this property safely.
2: DateInterval::createFromDateString allows negative periods
DateInterval::createFromDateString('-1 day') is accepted but this sets DateInterval->d = -1 rather than using the ::invert property. This is inconsistent with the always-positive periods which __construct allows.
I would expect it to:
- Reject mixed positive and negative period values, what would
+1 year -6 montheven mean? - Accept if only negative periods passed but then set
::invert = 1and the properties of::y..fas+ve
3: DateInterval::createFromDateString('-1 day') leads to infinite loop in DatePeriod
$datePeriod = new \DatePeriod(
new \DateTimeImmutable('2000-01-01'),
\DateInterval::createFromDateString('-1 day'),
new \DateTimeImmutable('2000-01-05'),
);
echo iterator_count($datePeriod); // stuck in infinite loop
4: DateInterval::createFromDateString('-1 day') still doesn't work if start and end reversed in DatePeriod
$datePeriod = new \DatePeriod(
new \DateTimeImmutable('2000-01-05'),
\DateInterval::createFromDateString('-1 day'),
new \DateTimeImmutable('2000-01-01'),
);
echo iterator_count($datePeriod); // 0 (but would expect 4)
5: DatePeriod doesn't respect DateInterval->invert
$dateInterval = new \DateInterval('P1D');
$dateInterval->invert = 1;
# will not go backwards from high to low dates
$datePeriod = new \DatePeriod(
new \DateTimeImmutable('2000-01-05'),
$dateInterval,
new \DateTimeImmutable('2000-01-01'),
);
echo iterator_count($datePeriod); // 0 (but would expect 4)
# incorrectly goes forward from low to high dates
$datePeriod = new \DatePeriod(
new \DateTimeImmutable('2000-01-01'),
$dateInterval,
new \DateTimeImmutable('2000-01-05'),
);
echo iterator_count($datePeriod); // 4 (but would expect 0)
PHP Version
8.3.114
Operating System
Rocky 8
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the examples using the DateInterval and DatePeriod entry points, including negative intervals, reversed dates, and the invert property. Review the existing date-period behavior and decide consistent semantics for negative directions, mixed signs, and inverted intervals. Done means the reported cases have defined, non-looping behavior with regression coverage.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- php
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100