Recurr is a PHP library for working with recurrence rules (RRULE) and converting them in to DateTime objects.
Recurr was developed as a precursor for a calendar with recurring events, and is heavily inspired by rrule.js.
Recurr is hosted on packagist, meaning you can install it with Composer.
-
Create a composer.json file
{ "require": { "simshaun/recurr": "dev-master" } }We recommend using a stable version instead of dev-master.
-
Install Composer and run the install command
wget http://getcomposer.org/composer.phar php composer.phar install
-
Include Composer's autoloader
require 'vendor/autoload.php';
$timezone = 'America/New_York';
$startDate = new \DateTime('2013-06-12 20:00:00', new \DateTimeZone($timezone));
$endDate = new \DateTime('2013-06-14 20:00:00', new \DateTimeZone($timezone)); // Optional
$rule = new \Recurr\Rule('FREQ=MONTHLY;COUNT=5', $startDate, $endDate, $timezone);
$transformer = new \Recurr\Transformer\ArrayTransformer();
print_r($transformer->transform($rule));$transformer->transform(...)returns aRecurrenceCollectionofRecurrenceobjects.- Each
RecurrencehasgetStart()andgetEnd()methods that return a\DateTimeobject. - If the transformed
Rulelacks an end date,getEnd()will return a\DateTimeobject equal to that ofgetStart().
Note: The transformer has a "virtual" limit (default 732) on the number of objects it generates. This prevents the script from crashing on an infinitely recurring rule. You can change the virtual limit in the call to
transformor theArrayTransformerconstructor.
Constraints (\Recurr\Transformer\ConstraintInterface) are used by the ArrayTransformer to allow or prevent certain dates from being added to a RecurrenceCollection. Recurr provides the following constraints:
AfterConstraint(\DateTime $after, $inc = false)BeforeConstraint(\DateTime $before, $inc = false)BetweenConstraint(\DateTime $after, \DateTime $before, $inc = false)
$inc defines what happens if $after or $before are themselves recurrences. If $inc = true, they will be included in the collection. For example,
$startDate = new \DateTime('2014-06-17 04:00:00');
$rule = new \Recurr\Rule('FREQ=MONTHLY;COUNT=5', $startDate);
$transformer = new \Recurr\Transformer\ArrayTransformer();
$constraint = new \Recurr\Transformer\Constraint\BeforeConstraint(new \DateTime('2014-08-01 00:00:00'));
print_r($transformer->transform($rule, null, $constraint));Note: If building your own constraint, it is important to know that dates which do not meet the constraint's requirements do not count toward the transformer's virtual limit. If you manually set your constraint's
$stopsTransformerproperty tofalse, the transformer might crash via an infinite loop. See theBetweenConstraintfor an example on how to prevent that.
RecurrenceCollection provides the following chainable helper methods to filter out recurrences:
startsBetween(\DateTime $after, \DateTime $before, $inc = false)startsBefore(\DateTime $before, $inc = false)startsAfter(\DateTime $after, $inc = false)endsBetween(\DateTime $after, \DateTime $before, $inc = false)endsBefore(\DateTime $before, $inc = false)endsAfter(\DateTime $after, $inc = false)
$inc defines what happens if $after or $before are themselves recurrences. If $inc = true, they will be included in the filtered collection. For example,
pseudo...
2014-06-01 startsBetween(2014-06-01, 2014-06-20) // false
2014-06-01 startsBetween(2014-06-01, 2014-06-20, true) // true
Note:
RecurrenceCollectionextends the Doctrine project's ArrayCollection class.
Recurr supports transforming some recurrence rules in to human readable text. This feature is still in beta and only supports yearly, monthly, weekly, and daily frequencies. It is not yet localized and only supports English.
$rule = new Rule('FREQ=YEARLY;INTERVAL=2;COUNT=3;', new \DateTime());
$textTransformer = new TextTransformer();
echo $textTransformer->transform($rule);- Monthly recurring rules: If your start date is on the 29th, 30th, or 31st, Recurr will skip the months that have less than that number of days. This behavior is configurable:
$timezone = 'America/New_York';
$startDate = new \DateTime('2013-01-31 20:00:00', new \DateTimeZone($timezone));
$rule = new \Recurr\Rule('FREQ=MONTHLY;COUNT=5', $startDate, null, $timezone);
$transformer = new \Recurr\Transformer\ArrayTransformer();
$transformerConfig = new \Recurr\Transformer\ArrayTransformerConfig();
$transformerConfig->enableLastDayOfMonthFix();
$transformer->setConfig($transformerConfig);
print_r($transformer->transform($rule));
/* Recurrences:
* 2013-01-31
* 2013-02-28
* 2013-03-31
* 2013-04-30
* 2013-05-31
*/Recurr is still in beta, and is most likely not 100% free of bugs. Feel free to comment or make pull requests. Please include tests with PRs.
Recurr is licensed under the MIT License. See the LICENSE file for details.