/recurrence

Generation of date recurrences in PHP

Primary LanguagePHPMIT LicenseMIT

Recurrence

License: MIT Build Status Scrutinizer Code Quality Code Coverage

Presentation

This library allow to manage datetime recurrences. It implement basic RRULE standards and add constraints support.

RFC : https://tools.ietf.org/html/rfc5545#page-37

Usage

Create recurrences using object method

$recurrence = (new Recurrence())
    ->setFrequency(new Frequency('MONTHLY'))
    ->setPeriodStartAt(new \Datetime('2017-01-01'))
    ->setPeriodEndAt(new \Datetime('2017-12-31'))
    ->setInterval(1);
$periods = (new DatetimeProvider())->provide($recurrence);

Available methods :

  • setFrequency (Frequency) : set FREQ option
  • setPeriodStartAt (\Datetime()) : set DTSTART option
  • setPeriodEndAt (\Datetime()) : set UNTIL option
  • setInterval (integer) : set INTERVAL option
  • setCount (integer) : set COUNT option

Create recurrences from RRULE standard expression

This example as the same result as example above using object method :

$recurrence = (new RecurrenceProvider())->create('FREQ=MONTHLY;DTSTART=20170101;UNTIL=20171231;INTERVAL=1');
$periods    = (new DatetimeProvider())->provide($recurrence);

Supported rules :

  • FREQ : YEARLY, MONTHLY, WEEKLY, DAILY, HOURLY, MINUTELY, SECONDLY
  • DTSTART :
    • Simple date : string using format YYYYMMDD (example : 20170520)
    • Datetime : string using format YYYYMMDDTHHMMSS (example : 20170520T154720)
    • Datetime UTC : string using format YYYYMMDDTHHMMSSZ (example : 20170520T154720Z)
  • DTSTART with TZID : string using format {timezone}:YYYYMMDDTHHMMSS (example : Europe/Paris:20170520T154720)
  • UNTIL :
    • Simple date : string using format YYYYMMDD (example : 20170520)
    • Datetime : string using format YYYYMMDDTHHMMSS (example : 20170520T154720)
    • Datetime UTC : string using format YYYYMMDDTHHMMSSZ (example : 20170520T154720Z)
  • UNTIL with TZID : string using format {timezone}:YYYYMMDDTHHMMSS (example : Europe/Paris:20170520T154720)
  • INTERVAL : simple integer
  • COUNT : simple integer

Adding constraints

You can add some constraint to Recurrence in order to manage more precisely generated datetimes.
For example, if you do not want to generate datetime on wednesday (day 3 according to date format in PHP), add this constraint :

$recurrence->addConstraint(new ExcludeDaysOfWeekConstraint([3]));
  • EndOfMonthConstraint : if recurrence has MONTHLY frequency and start date is last day of current month, force last day of month for all datetimes
  • ExcludeDaysOfWeekConstraint : if datetime is concerned, DatetimeProvider will return next valid date
  • ExcludeWeekendConstraint : if datetime is concerned, DatetimeProvider will return next monday

Constraints are not a part of RRULE standard, this is an addition to optimize datetimes manipulation.
Be careful, constraints will be applied in the order you add it to recurrence.

Unit tests

./vendor/bin/atoum -d tests/units/Recurrence

Html code coverage is generated here : ./var/code-coverage

Remember that you need xdebug to generate code coverage report.

Benchmark

To assume that you don't degrade performance when you update the library, run a benchmark using context name initial first :

./vendor/bin/phpbench run --store --tag="initial" --report=default

Before committing your changes, run a new benchmark using update as context :

./vendor/bin/phpbench run --store --tag="update" --report=default

You can then list log to see evolution using :

./vendor/bin/phpbench log

Or even better, compare the 2 benchmarks and see if you don't degrade performance with your changes :

./vendor/bin/phpbench run --report=aggregate --ref=initial