simshaun / recurr

PHP library for working with recurrence rules (RRULE); meant to help with recurring calendar events.
Other
1.21k stars 135 forks source link

Order occurences defined by unordered BY* rule parts #211

Closed alexandre-le-borgne closed 7 months ago

alexandre-le-borgne commented 8 months ago

Usage case:

RRULE :

DTSTART=20240111T005500Z;FREQ=DAILY;INTERVAL=1;BYSETPOS=1,8,15,22,29,36;BYHOUR=16,22,08,10,10,11;BYMINUTE=55,16,50,40,50,00;BYSECOND=0

Custom constraint:

class OccurrenceIndexConstraint extends Constraint
{
    private int $index = 0;

    public function __construct(
        private readonly int $indexStop,
        private readonly ?\DateTimeInterface $afterDate = null,
    ) {
    }

    public function test(\DateTimeInterface $date): bool
    {
        if ($this->index > $this->indexStop) {
            $this->stopsTransformer = true;

            return false;
        }

        if ($this->afterDate !== null && $date < $this->afterDate) {
            return false;
        }

        ++$this->index;

        return true;
    }
}

Usage code :

    public function getNthOccurrenceAfterDate(Rule $rule, $nth, ?\DateTimeInterface $afterDate, bool $defaultToLast = false): ?Recurrence
    {
        /** @var RecurrenceCollection<Recurrence> $occurrence */
        $occurrences = self::createArrayTransformer()->transform(
            $rule,
            new OccurrenceIndexConstraint($nth, $afterDate)
        );

        if ($occurrences->count()) {
            return $defaultToLast ? $occurrences->last() : $occurrences->get($nth);
        }

        return null;
    }

     $nextOccurrence = getNthOccurrenceAfterDate(
            $rrule,
            0,
            new \DateTimeImmutable('2024-01-11 00:55:00'),
        );
        dd($nextOccurrence);

Expected: 2024-01-11 08:50:00.0 Got: 2024-01-11 16:55:00.0

According to :

3.1.1. List and Field Separators

Some properties and parameters allow a list of values. Values in a list of values MUST be separated by a COMMA character. There is no significance to the order of values in a list. For those parameter values (such as those that specify URI values) that are specified in quoted-strings, the individual quoted-strings are separated by a COMMA character.