PHPackages                             lewisjenkins/craft-rrule - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. lewisjenkins/craft-rrule

ActiveYii2-extension[Utility &amp; Helpers](/categories/utility)

lewisjenkins/craft-rrule
========================

RRULE helpers for Craft CMS (wraps rlanvin/php-rrule).

1.0.0(10mo ago)053↓94.1%MITPHPPHP ^8.2

Since Aug 14Pushed 10mo agoCompare

[ Source](https://github.com/lewisjenkins/craft-rrule)[ Packagist](https://packagist.org/packages/lewisjenkins/craft-rrule)[ Docs](https://github.com/lewisjenkins/craft-rrule)[ RSS](/packages/lewisjenkins-craft-rrule/feed)WikiDiscussions main Synced today

READMEChangelog (1)Dependencies (2)Versions (2)Used By (0)

Craft RRULE Wrapper
===================

[](#craft-rrule-wrapper)

A minimal **Craft CMS 5 module** that exposes the [php-rrule](https://github.com/rlanvin/php-rrule) library to **Twig**. This wrapper stays faithful to the original library and does not change its behaviour — it simply makes `RRule` and `RSet` available in templates.

Requirements
------------

[](#requirements)

- PHP 8.2+
- Craft CMS 5+

Installation
------------

[](#installation)

```
composer require lewisjenkins/craft-rrule
```

Usage (Twig)
------------

[](#usage-twig)

The module exposes two helpers on `craft.rrule`:

- `craft.rrule.rrule(spec)` — create an `RRule` from an **array** or **RFC-style string**
- `craft.rrule.rset(spec?)` — create an `RSet`; optional **multi-line RFC block** string

### RRULE — simple string example

[](#rrule--simple-string-example)

```
{% set rr = craft.rrule.rrule('
DTSTART;TZID=America/New_York:20250809T090000
RRULE:FREQ=DAILY;COUNT=3
') %}
{% for d in rr.getOccurrences() %}
  {{ d|date('Y-m-d H:i e', d.timezone) }}
{% endfor %}
```

### Expected output

[](#expected-output)

```
2025-08-09 09:00 America/New_York
2025-08-10 09:00 America/New_York
2025-08-11 09:00 America/New_York

```

### RRULE — array example

[](#rrule--array-example)

```
{% set rr = craft.rrule.rrule({
  'FREQ': 'DAILY',
  'COUNT': 3,
  'DTSTART': date('2025-08-09 09:00', 'America/New_York')
}) %}
{% for d in rr.getOccurrences() %}
  {{ d|date('Y-m-d H:i e', d.timezone) }}
{% endfor %}
```

### Expected output

[](#expected-output-1)

```
2025-08-09 09:00 America/New_York
2025-08-10 09:00 America/New_York
2025-08-11 09:00 America/New_York

```

### RSET — multi-line block example

[](#rset--multi-line-block-example)

```
{% set rset = craft.rrule.rset('
DTSTART;TZID=America/New_York:19970901T090000
RRULE:FREQ=DAILY;COUNT=3
EXDATE;TZID=America/New_York:19970902T090000
') %}
{% for d in rset.getOccurrences() %}
  {{ d|date('Y-m-d H:i e', d.timezone) }}
{% endfor %}
```

### Expected output

[](#expected-output-2)

```
1997-09-01 09:00 America/New_York
1997-09-03 09:00 America/New_York

```

### RSET — array example

[](#rset--array-example)

```
{% set rset = craft.rrule.rset() %}
{% do rset.addRRule({
  'FREQ': 'DAILY',
  'COUNT': 3,
  'DTSTART': date('1997-09-01 09:00', 'America/New_York')
}) %}
{% do rset.addExDate(date('1997-09-02 09:00', 'America/New_York')) %}
{% for d in rset.getOccurrences() %}
  {{ d|date('Y-m-d H:i e', d.timezone) }}
{% endfor %}
```

### Expected output

[](#expected-output-3)

```
1997-09-01 09:00 America/New_York
1997-09-03 09:00 America/New_York

```

### Timezone formatting

[](#timezone-formatting)

Each occurrence (`DateTime`) retains its own timezone. Always format using the occurrence’s timezone:

```
{{ d|date('Y-m-d H:i e', d.timezone) }}
```

Full API &amp; Examples
-----------------------

[](#full-api--examples)

Refer to the original library for the complete API and many examples:

- **RRule**:
- **RSet**:

###  Health Score

32

—

LowBetter than 69% of packages

Maintenance53

Moderate activity, may be stable

Popularity9

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity49

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

325d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/3381958?v=4)[Lewis Jenkins](/maintainers/lewisjenkins)[@lewisjenkins](https://github.com/lewisjenkins)

---

Top Contributors

[![lewisjenkins](https://avatars.githubusercontent.com/u/3381958?v=4)](https://github.com/lewisjenkins "lewisjenkins (18 commits)")

---

Tags

rrulerecurrenceyii2modulecalendarschedulingCraftcraftcms

### Embed Badge

![Health badge](/badges/lewisjenkins-craft-rrule/health.svg)

```
[![Health](https://phpackages.com/badges/lewisjenkins-craft-rrule/health.svg)](https://phpackages.com/packages/lewisjenkins-craft-rrule)
```

###  Alternatives

[craftcms/feed-me

Import content from XML, RSS, CSV or JSON feeds into entries, categories, Craft Commerce products, and more.

293952.6k33](/packages/craftcms-feed-me)[verbb/formie

The most user-friendly forms plugin for Craft.

102393.6k70](/packages/verbb-formie)[verbb/comments

Add comments to your site.

13753.9k](/packages/verbb-comments)[verbb/vizy

A flexible visual editor field for Craft.

4250.4k](/packages/verbb-vizy)[verbb/hyper

A user-friendly links field for Craft.

24147.8k12](/packages/verbb-hyper)[verbb/social-poster

Automatically post entries to social media.

918.5k](/packages/verbb-social-poster)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
