Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sequence has multiple same period ,call the intersections func ,result is error #134

Closed
maogou opened this issue Dec 6, 2023 · 5 comments
Assignees

Comments

@maogou
Copy link
Contributor

maogou commented Dec 6, 2023

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

nyamsprod added a commit that referenced this issue Dec 6, 2023
@nyamsprod nyamsprod self-assigned this Dec 6, 2023
@nyamsprod
Copy link
Member

fixed base on PR thanks

@nyamsprod
Copy link
Member

the version 5.3.1 is released with your fix. Thanks again
https://github.com/thephpleague/period/releases/tag/5.3.1

@maogou
Copy link
Contributor Author

maogou commented Dec 7, 2023

@nyamsprod

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

@nyamsprod
Copy link
Member

@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).

@maogou
Copy link
Contributor Author

maogou commented Dec 7, 2023

@nyamsprod

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!

https://github.com/maogou/period

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants