Sequence has multiple same period ,call the intersections func ,result is error
maogou opened this issue · comments
Bug Report
(Fill in the relevant information below to help triage your issue.)
Information | Description |
---|---|
Version | 5.3 |
PHP version | 8.1.22 |
OS Platform | Windows |
Summary
(Please explain in plain english your bug)
Sequence has multiple same period ,call the intersections is error
Standalone code, or other way to reproduce the problem
<?php
$p1 = Period::fromDate('2023-01-01 00:00:00','2023-01-03 00:00:00');
$p2 = Period::fromDate('2023-01-01 00:00:00','2023-01-03 00:00:00');
$p3 = Period::fromDate('2023-01-01 00:00:00','2023-01-03 00:00:00');
$p4 = Period::fromDate('2023-01-02 00:00:00','2023-01-04 00:00:00');
$p5 = Period::fromDate('2023-01-02 00:00:00','2023-01-04 00:00:00');
$seq = new Sequence($p1,$p2,$p3,$p4,$p5);
$xx = $seq->intersections()->jsonSerialize();
print_r($xx);
current output
Array
(
[0] => League\Period\Period Object
(
[startDate] => DateTimeImmutable Object
(
[date] => 2023-01-01 00:00:00.000000
[timezone_type] => 3
[timezone] => Asia/Shanghai
)
[endDate] => DateTimeImmutable Object
(
[date] => 2023-01-03 00:00:00.000000
[timezone_type] => 3
[timezone] => Asia/Shanghai
)
[bounds] => League\Period\Bounds Enum
(
[name] => IncludeStartExcludeEnd
)
)
[1] => League\Period\Period Object
(
[startDate] => DateTimeImmutable Object
(
[date] => 2023-01-01 00:00:00.000000
[timezone_type] => 3
[timezone] => Asia/Shanghai
)
[endDate] => DateTimeImmutable Object
(
[date] => 2023-01-03 00:00:00.000000
[timezone_type] => 3
[timezone] => Asia/Shanghai
)
[bounds] => League\Period\Bounds Enum
(
[name] => IncludeStartExcludeEnd
)
)
[2] => League\Period\Period Object
(
[startDate] => DateTimeImmutable Object
(
[date] => 2023-01-02 00:00:00.000000
[timezone_type] => 3
[timezone] => Asia/Shanghai
)
[endDate] => DateTimeImmutable Object
(
[date] => 2023-01-03 00:00:00.000000
[timezone_type] => 3
[timezone] => Asia/Shanghai
)
[bounds] => League\Period\Bounds Enum
(
[name] => IncludeStartExcludeEnd
)
)
[3] => League\Period\Period Object
(
[startDate] => DateTimeImmutable Object
(
[date] => 2023-01-02 00:00:00.000000
[timezone_type] => 3
[timezone] => Asia/Shanghai
)
[endDate] => DateTimeImmutable Object
(
[date] => 2023-01-04 00:00:00.000000
[timezone_type] => 3
[timezone] => Asia/Shanghai
)
[bounds] => League\Period\Bounds Enum
(
[name] => IncludeStartExcludeEnd
)
)
)
after fix output is right ????:
Array
(
[0] => League\Period\Period Object
(
[startDate] => DateTimeImmutable Object
(
[date] => 2023-01-01 00:00:00.000000
[timezone_type] => 3
[timezone] => Asia/Shanghai
)
[endDate] => DateTimeImmutable Object
(
[date] => 2023-01-03 00:00:00.000000
[timezone_type] => 3
[timezone] => Asia/Shanghai
)
[bounds] => League\Period\Bounds Enum
(
[name] => IncludeStartExcludeEnd
)
)
[1] => League\Period\Period Object
(
[startDate] => DateTimeImmutable Object
(
[date] => 2023-01-02 00:00:00.000000
[timezone_type] => 3
[timezone] => Asia/Shanghai
)
[endDate] => DateTimeImmutable Object
(
[date] => 2023-01-04 00:00:00.000000
[timezone_type] => 3
[timezone] => Asia/Shanghai
)
[bounds] => League\Period\Bounds Enum
(
[name] => IncludeStartExcludeEnd
)
)
)
or this is right ??
Array
(
[0] => League\Period\Period Object
(
[startDate] => DateTimeImmutable Object
(
[date] => 2023-01-02 00:00:00.000000
[timezone_type] => 3
[timezone] => Asia/Shanghai
)
[endDate] => DateTimeImmutable Object
(
[date] => 2023-01-03 00:00:00.000000
[timezone_type] => 3
[timezone] => Asia/Shanghai
)
[bounds] => League\Period\Bounds Enum
(
[name] => IncludeStartExcludeEnd
)
)
)
(Please complete the text below to help us fix the issue)
can add contains func check the same in sequence ???
public function intersections(): self
{
$current = null;
$isPreviouslyContained = false;
$reducer = function (Sequence $sequence, Period $period) use (&$current, &$isPreviouslyContained): Sequence {
if (null === $current) {
$current = $period;
return $sequence;
}
/** @var Period $current */
$isContained = $current->contains($period);
if ($isContained && $isPreviouslyContained && !$sequence->contains($current)) {
$sequence->push($current->intersect($period));
return $sequence;
}
if ($current->overlaps($period) && !$sequence->contains($current)) {
$sequence->push($current->intersect($period));
}
$isPreviouslyContained = $isContained;
if (!$isContained) {
$current = $period;
}
return $sequence;
};
return $this
->sorted($this->sortByStartDate(...))
->reduce($reducer, new self());
}
Expected result
Array
(
[0] => League\Period\Period Object
(
[startDate] => DateTimeImmutable Object
(
[date] => 2023-01-01 00:00:00.000000
[timezone_type] => 3
[timezone] => Asia/Shanghai
)
[endDate] => DateTimeImmutable Object
(
[date] => 2023-01-03 00:00:00.000000
[timezone_type] => 3
[timezone] => Asia/Shanghai
)
[bounds] => League\Period\Bounds Enum
(
[name] => IncludeStartExcludeEnd
)
)
[1] => League\Period\Period Object
(
[startDate] => DateTimeImmutable Object
(
[date] => 2023-01-02 00:00:00.000000
[timezone_type] => 3
[timezone] => Asia/Shanghai
)
[endDate] => DateTimeImmutable Object
(
[date] => 2023-01-04 00:00:00.000000
[timezone_type] => 3
[timezone] => Asia/Shanghai
)
[bounds] => League\Period\Bounds Enum
(
[name] => IncludeStartExcludeEnd
)
)
)
or
Array
(
[0] => League\Period\Period Object
(
[startDate] => DateTimeImmutable Object
(
[date] => 2023-01-02 00:00:00.000000
[timezone_type] => 3
[timezone] => Asia/Shanghai
)
[endDate] => DateTimeImmutable Object
(
[date] => 2023-01-03 00:00:00.000000
[timezone_type] => 3
[timezone] => Asia/Shanghai
)
[bounds] => League\Period\Bounds Enum
(
[name] => IncludeStartExcludeEnd
)
)
)
(What was the expected (correct) behavior?)
Remove duplicate period and give me right intersect periods
Actual result
(What is the current (buggy) behavior?)
i pull a pr , but i do not confirm the pr is right , can you help explain the case real right result ?? thinks
fixed base on PR thanks
the version 5.3.1
is released with your fix. Thanks again
https://github.com/thephpleague/period/releases/tag/5.3.1
Thank you for opening up this project. I really like it If I have time, I will implement a Golang version of the period. If you don't recommend it, I would like to make it open source after implementation because my work mainly uses PHP and Golang languages, but I don't have the corresponding Package for the Golang language
@maogou I believe there is already a go port done here https://github.com/studiofrenetic/period maybe it needs some update (full disclosure I do not know go so I can not evaluate the library codebase).
I spent a day implementing the corresponding functions in Golang . This project is really great . Thank you again for opening up this project and for your prompt and enthusiastic response to my message!