fix: return 0 from length() when excluded boundaries leave a period empty
Excluding the boundaries of a one or two unit long period pushes the included start past the included end. diff()->days is unsigned and the HOUR/MINUTE/SECOND branch applied abs() outright, so that backwards range was measured as a positive distance and the unconditional +1 inflated it further: a one day period reported 1, 2, 2 and 3 for EXCLUDE_NONE, START, END and ALL, while iterating the same objects yielded nothing. Return 0 up front when the included start is past the included end. This matches what the MONTH and YEAR precisions already returned through iterator_count(), and lets the now unreachable abs() go.
This commit is contained in:
1 parent
79eb344eb0
commit
5763d58d02
4 files changed
+208
-1
No files matched your search
@@ -66,6 +66,13 @@ trait PeriodGetters
|
||||
|
||||
public function length(): int
|
||||
{
|
||||
// Excluding the boundaries of a period that is only a few units long can push the
|
||||
// included start past the included end. Such a period contains nothing, which is what
|
||||
// iterating over it yields, so its length is 0 rather than a distance measured backwards.
|
||||
if ($this->includedStart() > $this->includedEnd()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Length of month and year are not fixed, so we can't predict the length without iterate
|
||||
// TODO: maybe we can use cal_days_in_month ?
|
||||
if ($this->precision->equals(Precision::MONTH(), Precision::YEAR())) {
|
||||
@@ -73,7 +80,7 @@ trait PeriodGetters
|
||||
}
|
||||
|
||||
if ($this->precision->equals(Precision::HOUR(), Precision::MINUTE(), Precision::SECOND())) {
|
||||
$length = abs($this->includedEnd()->getTimestamp() - $this->includedStart()->getTimestamp());
|
||||
$length = $this->includedEnd()->getTimestamp() - $this->includedStart()->getTimestamp();
|
||||
|
||||
if ($this->precision->equals(Precision::SECOND())) {
|
||||
return $length + 1;
|
||||
|
||||
Reference in new issue
Block a user