Report generated 11-04-2023 12:42

Feature: Recurring Dates Computing

Provides a complete implementation of dates computing based on recurrence rules as specified in the iCalendar RFC 5545.

The idea is to compute a set of dates from a start date by applying one or more recurrence rules. The start date should be specified in ISO 8601 format; Here is a wiki link as well for more details.

The recurrence rule (rrule) should be specified in the following format and all the keywords are supported:

rrule       = rrule-part *( ";" rrule-part )  
                ;  
                ; The rule parts are not ordered in any  
                ; particular sequence.  
                ;  
                ; The FREQ rule part is REQUIRED,  
                ; but MUST NOT occur more than once.  
                ;  
                ; The UNTIL or COUNT rule part is REQUIRED,  
                ; but they MUST NOT occur in the same 'rrule'.  
                ;  
                ; The other rule parts are OPTIONAL,  
                ; but MUST NOT occur more than once.  

rrule-part  = ( "FREQ" "=" freq )  
                / ( "UNTIL" "=" enddate )  
                / ( "COUNT" "=" 1*DIGIT )  
                / ( "INTERVAL" "=" 1*DIGIT )  
                / ( "BYSECOND" "=" byseclist )  
                / ( "BYMINUTE" "=" byminlist )  
                / ( "BYHOUR" "=" byhrlist )  
                / ( "BYWEEKDAY" "=" bywdaylist )  
                / ( "BYMONTHDAY" "=" bymodaylist )  
                / ( "BYYEARDAY" "=" byyrdaylist )  
                / ( "BYWEEKNO" "=" bywknolist )  
                / ( "BYMONTH" "=" bymolist )  
                / ( "BYSETPOS" "=" bysplist )  
                / ( "WKST" "=" weekday )  

freq        = "SECONDLY" / "MINUTELY" / "HOURLY" / "DAILY" / "WEEKLY" / "MONTHLY" / "YEARLY"  
enddate     = date in either iso format YYYY-MM-DD[THHmmss] or in YYYYMMDD[THHmmss] format; By default the time is 00:00:00.  
byseclist   = seconds *("," seconds)  
    seconds     = 1*2DIGIT       ;0 to 60  
byminlist   = minutes *("," minutes)  
    minutes     = 1*2DIGIT       ;0 to 59  
byhrlist    = hour *("," hour)  
    hour        = 1*2DIGIT       ;0 to 23  
bywdaylist  = weekdaynum *("," weekdaynum)  
    weekdaynum  = [[plus / minus] ordwk] weekday  
    plus        = "+"  
    minus       = "-"  
    ordwk       = 1*2DIGIT       ;1 to 53  
    weekday     = "SU" / "MO" / "TU" / "WE" / "TH" / "FR" / "SA"  
    ;Corresponding to SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY,  
    ;FRIDAY, and SATURDAY days of the week.  
bymodaylist = monthdaynum *("," monthdaynum)  
    monthdaynum = [plus / minus] ordmoday  
    ordmoday    = 1*2DIGIT       ;1 to 31  
byyrdaylist = yeardaynum *("," yeardaynum)  
    yeardaynum  = [plus / minus] ordyrday  
    ordyrday    = 1*3DIGIT      ;1 to 366  
bywknolist  = weeknum *("," weeknum)  
    weeknum     = [plus / minus] ordwk  
bymolist    = monthnum *("," monthnum)  
    monthnum    = 1*2DIGIT       ;1 to 12  
bysplist    = setposday *("," setposday)  
    setposday   = yeardaynum  

Here are some examples of recurrence rules (The last one is make up from two rules that will be applied one after another):

  • RRULE:FREQ=DAILY;COUNT=30
  • RRULE:FREQ=MONTHLY;COUNT=36
  • RRULE:FREQ=MONTHLY;COUNT=36;BYMONTHDAY=-1
  • RRULE:FREQ=YEARLY;INTERVAL=2;BYMONTH=1;BYWEEKDAY=SU
  • RRULE:FREQ=MONTHLY;COUNT=36 RRULE:FREQ=YEARLY;COUNT=10

Finally, the computed recurring dates will be returned as list of dates in either ISO 8601 format or RFC 1123 format (EEE, dd MMM yyyy HH:mm:ss Z; Example: Mon, 20 Sep 2021 02:00:00 GMT).

Feature Coverage By Scenario

Overview

Rule: Daily for 5 occurrences
Scenario: Daily computing from a start date involving last day of a 31-day month
Rule: Every 10 days for 5 occurrences
Scenario: Every 10 days computing from a start date involving last day of a 31-day month
Scenario: Every 10 days computing from a start date not involving last day of a 31-day month
Rule: Monthly for 12 occurrences
Scenario: Monthly computing from a start date involving last day of a 31-day month
Scenario: Monthly computing from a start date involving last day of a 30-day month
Rule: Monthly last day for 12 occurrences
Scenario: Monthly last day computing from a start date involving last day of a 31-day month
Scenario: Monthly last day computing from a start date not involving last day of the month
Scenario: Monthly last day computing from a start date involving last day of a 30-day month
Scenario: Monthly last day computing from a start date of a leap year involving last day of a 31-day month
Scenario: Monthly last day computing from a start date involving last day of february
Rule: Monthly third penultimate day for 12 occurrences
Scenario: Monthly third penultimate day computing from a start date involving last day of a 31-day month
Scenario: Monthly third penultimate day computing from a start date not involving last day of the month
Scenario: Monthly third penultimate day computing from a start date involving last day of a 30-day month
Scenario: Monthly third penultimate day computing from a start date involving last day of february
Rule: Monthly third penultimate day for 36 occurrences
Scenario: Monthly third penultimate day computing from a start date of a leap year involving last day of a 31-day month
Rule: Monthly last day for 12 occurrences and after yearly for 3 occurrences
Scenario: Monthly and yearly computing from a start date with involving day of a 31-day month
Rule: Monthly last day for 12 occurrences and after every quarter until the end of the year
Scenario: Monthly and quartly computing from a start date involving last day of a 31-day month
Rule: Daily for 11 occurrences and after monthly last day for 12 occurrences and finally yearly for 5 occurences
Scenario: Daily, monthly and yearly computing from a start date not involving last day of the month
Rule: Monthly on the 1st Friday for 10 occurrences
Scenario: Monthly on the 1st Friday from a start date involving last day of a 31-day month
Rule: Monthly on the 2nd and 15th of the month for 12 occurrences
Scenario: Monthly on the 2nd and 15th from a start date involving last day of a 31-day month
Rule: Monthly on the first and last day of the month for 12 occurrences
Scenario: Monthly on the first and last day from a start date involving last day of a 31-day month
Rule: Every Monday of every month for 10 occurrences
Scenario: Every Monday of every month computing from a start date involving last day of a 31-day month
Rule: Every four years, the first Tuesday after a Monday in November for 10 occurrences
Scenario: The U.S. Presidential Election day computing from 2020
Rule: Recurring computation on the time part
Scenario: Every 3 hours from 9h00 AM to 5h00 PM on a specific day
Scenario: Every 3 hours from 00h00 to 5h00 PM on a specific day
Scenario: Every a quarter of an hour for 6 occurrences
Scenario: Weekly for 6 occurrences

Scenarios

Rule: Daily for 5 occurrences

Given the start date 2021-03-31

When the rrule FREQ=DAILY;COUNT=5 is applied

Then the recurring dates should be

date
2021-03-31
2021-04-01
2021-04-02
2021-04-03
2021-04-04

Rule: Every 10 days for 5 occurrences

Given the start date 2021-03-31

When the rrule FREQ=DAILY;INTERVAL=10;COUNT=5 is applied

Then the recurring dates should be

date
2021-03-31
2021-04-10
2021-04-20
2021-04-30
2021-05-10

Given the start date 2021-03-28

When the rrule FREQ=DAILY;INTERVAL=10;COUNT=5 is applied

Then the recurring dates should be

date
2021-03-28
2021-04-07
2021-04-17
2021-04-27
2021-05-07

Rule: Monthly for 12 occurrences

Recurrence rules may generate recurrence instances with an invalid date (e.g., February 30 or April 31).
Such recurrence instances are ignored and not counted, which can lead to possibly surprising behavior.
The recurrence rule generates invalid dates (e.g., April 31, June 31, February 31, ...), and they are simply ignored.

Given the start date 2021-03-31

When the rrule FREQ=MONTHLY;COUNT=12 is applied

Then the recurring dates should be

date
2021-03-31
2021-05-31
2021-07-31
2021-08-31
2021-10-31
2021-12-31
2022-01-31
2022-03-31
2022-05-31
2022-07-31
2022-08-31
2022-10-31

The recurrence rule generates one invalid date (30 February 2022), and it's simply ignored.

Given the start date 2021-04-30

When the rrule FREQ=MONTHLY;COUNT=12 is applied

Then the recurring dates should be

date
2021-04-30
2021-05-30
2021-06-30
2021-07-30
2021-08-30
2021-09-30
2021-10-30
2021-11-30
2021-12-30
2022-01-30
2022-03-30
2022-04-30

Rule: Monthly last day for 12 occurrences

Given the start date 2021-03-31

When the rrule FREQ=MONTHLY;COUNT=12;BYMONTHDAY=-1 is applied

Then the recurring dates should be

date
2021-03-31
2021-04-30
2021-05-31
2021-06-30
2021-07-31
2021-08-31
2021-09-30
2021-10-31
2021-11-30
2021-12-31
2022-01-31
2022-02-28

Given the start date 2021-03-15

When the rrule FREQ=MONTHLY;COUNT=12;BYMONTHDAY=-1 is applied

Then the recurring dates should be

date
2021-03-31
2021-04-30
2021-05-31
2021-06-30
2021-07-31
2021-08-31
2021-09-30
2021-10-31
2021-11-30
2021-12-31
2022-01-31
2022-02-28

Given the start date 2021-04-30

When the rrule FREQ=MONTHLY;COUNT=12;BYMONTHDAY=-1 is applied

Then the recurring dates should be

date
2021-04-30
2021-05-31
2021-06-30
2021-07-31
2021-08-31
2021-09-30
2021-10-31
2021-11-30
2021-12-31
2022-01-31
2022-02-28
2022-03-31

Given the start date 2020-01-31

When the rrule FREQ=MONTHLY;COUNT=12;BYMONTHDAY=-1 is applied

Then the recurring dates should be

date
2020-01-31
2020-02-29
2020-03-31
2020-04-30
2020-05-31
2020-06-30
2020-07-31
2020-08-31
2020-09-30
2020-10-31
2020-11-30
2020-12-31

Given the start date 2021-02-28

When the rrule FREQ=MONTHLY;COUNT=12;BYMONTHDAY=-1 is applied

Then the recurring dates should be

date
2021-02-28
2021-03-31
2021-04-30
2021-05-31
2021-06-30
2021-07-31
2021-08-31
2021-09-30
2021-10-31
2021-11-30
2021-12-31
2022-01-31

Rule: Monthly third penultimate day for 12 occurrences

Given the start date 2021-03-31

When the rrule FREQ=MONTHLY;COUNT=12;BYMONTHDAY=-3 is applied

Then the recurring dates should be

date
2021-04-28
2021-05-29
2021-06-28
2021-07-29
2021-08-29
2021-09-28
2021-10-29
2021-11-28
2021-12-29
2022-01-29
2022-02-26
2022-03-29

Given the start date 2021-03-26

When the rrule FREQ=MONTHLY;COUNT=12;BYMONTHDAY=-3 is applied

Then the recurring dates should be

date
2021-03-29
2021-04-28
2021-05-29
2021-06-28
2021-07-29
2021-08-29
2021-09-28
2021-10-29
2021-11-28
2021-12-29
2022-01-29
2022-02-26

Given the start date 2021-04-30

When the rrule FREQ=MONTHLY;COUNT=12;BYMONTHDAY=-3 is applied

Then the recurring dates should be

date
2021-05-29
2021-06-28
2021-07-29
2021-08-29
2021-09-28
2021-10-29
2021-11-28
2021-12-29
2022-01-29
2022-02-26
2022-03-29
2022-04-28

Given the start date 2021-02-28

When the rrule FREQ=MONTHLY;COUNT=12;BYMONTHDAY=-3 is applied

Then the recurring dates should be

date
2021-03-29
2021-04-28
2021-05-29
2021-06-28
2021-07-29
2021-08-29
2021-09-28
2021-10-29
2021-11-28
2021-12-29
2022-01-29
2022-02-26

Rule: Monthly third penultimate day for 36 occurrences

The period contains one leap year for which the third penultimate day of february is 27.

Given the start date 2020-01-31

When the rrule FREQ=MONTHLY;COUNT=36;BYMONTHDAY=-3 is applied

Then the recurring dates should be

date
2020-02-27
2020-03-29
2020-04-28
2020-05-29
2020-06-28
2020-07-29
2020-08-29
2020-09-28
2020-10-29
2020-11-28
2020-12-29
2021-01-29
2021-02-26
2021-03-29
2021-04-28
2021-05-29
2021-06-28
2021-07-29
2021-08-29
2021-09-28
2021-10-29
2021-11-28
2021-12-29
2022-01-29
2022-02-26
2022-03-29
2022-04-28
2022-05-29
2022-06-28
2022-07-29
2022-08-29
2022-09-28
2022-10-29
2022-11-28
2022-12-29
2023-01-29

Rule: Monthly last day for 12 occurrences and after yearly for 3 occurrences

Given the start date 2021-03-31

When the rrules in the following list are applied in order

FREQ=MONTHLY;COUNT=12;BYMONTHDAY=-1
FREQ=YEARLY;COUNT=3

Then the recurring dates should be

date
2021-03-31
2021-04-30
2021-05-31
2021-06-30
2021-07-31
2021-08-31
2021-09-30
2021-10-31
2021-11-30
2021-12-31
2022-01-31
2022-02-28
2023-02-28
2024-02-28

Rule: Monthly last day for 12 occurrences and after every quarter until the end of the year

Given the start date 2021-03-31

When the rrules in the following list are applied in order

FREQ=MONTHLY;COUNT=12;BYMONTHDAY=-1
FREQ=MONTHLY;INTERVAL=3;UNTIL=2022-12-31

Then the recurring dates should be

date
2021-03-31
2021-04-30
2021-05-31
2021-06-30
2021-07-31
2021-08-31
2021-09-30
2021-10-31
2021-11-30
2021-12-31
2022-01-31
2022-02-28
2022-05-28
2022-08-28
2022-11-28

Rule: Daily for 11 occurrences and after monthly last day for 12 occurrences and finally yearly for 5 occurences

Given the start date 2021-03-21

When the rrules in the following list are applied in order

FREQ=DAILY;COUNT=11
FREQ=MONTHLY;COUNT=12;BYMONTHDAY=-1
FREQ=YEARLY;COUNT=5

Then the recurring dates should be

date
2021-03-21
2021-03-22
2021-03-23
2021-03-24
2021-03-25
2021-03-26
2021-03-27
2021-03-28
2021-03-29
2021-03-30
2021-03-31
2021-04-30
2021-05-31
2021-06-30
2021-07-31
2021-08-31
2021-09-30
2021-10-31
2021-11-30
2021-12-31
2022-01-31
2022-02-28
2023-02-28
2024-02-28
2025-02-28
2026-02-28

Rule: Monthly on the 1st Friday for 10 occurrences

Given the start date 2021-03-31

When the rrule FREQ=MONTHLY;COUNT=10;BYWEEKDAY=FR(1) is applied

Then the recurring dates should be

date
2021-04-02
2021-05-07
2021-06-04
2021-07-02
2021-08-06
2021-09-03
2021-10-01
2021-11-05
2021-12-03
2022-01-07

Rule: Monthly on the 2nd and 15th of the month for 12 occurrences

Given the start date 2021-03-31

When the rrule FREQ=MONTHLY;COUNT=12;BYMONTHDAY=2,15 is applied

Then the recurring dates should be

date
2021-04-02
2021-04-15
2021-05-02
2021-05-15
2021-06-02
2021-06-15
2021-07-02
2021-07-15
2021-08-02
2021-08-15
2021-09-02
2021-09-15

Rule: Monthly on the first and last day of the month for 12 occurrences

Given the start date 2021-03-31

When the rrule FREQ=MONTHLY;COUNT=12;BYMONTHDAY=1,-1 is applied

Then the recurring dates should be

date
2021-03-31
2021-04-01
2021-04-30
2021-05-01
2021-05-31
2021-06-01
2021-06-30
2021-07-01
2021-07-31
2021-08-01
2021-08-31
2021-09-01

Rule: Every Monday of every month for 10 occurrences

Given the start date 2021-03-31

When the rrule FREQ=MONTHLY;COUNT=10;BYWEEKDAY=MO is applied

Then the recurring dates should be

date
2021-04-05
2021-04-12
2021-04-19
2021-04-26
2021-05-03
2021-05-10
2021-05-17
2021-05-24
2021-05-31
2021-06-07

Rule: Every four years, the first Tuesday after a Monday in November for 10 occurrences

The next 10 U.S. Presidential Election day.

Given the start date 2020-02-14

When the rrule FREQ=YEARLY;INTERVAL=4;COUNT=10;BYMONTH=11;BYWEEKDAY=TU;BYMONTHDAY=2,3,4,5,6,7,8 is applied

Then the recurring dates should be

date
2020-11-03
2024-11-05
2028-11-07
2032-11-02
2036-11-04
2040-11-06
2044-11-08
2048-11-03
2052-11-05
2056-11-07

Rule: Recurring computation on the time part

Given the start date 2021-09-20T09:00:00

When the rrule FREQ=HOURLY;INTERVAL=3;UNTIL=2021-09-20T170000 is applied

Then the recurring dates should be

date
2021-09-20T09:00:00
2021-09-20T12:00:00
2021-09-20T15:00:00

Given the start date 2021-09-20

When the rrule FREQ=HOURLY;INTERVAL=3;UNTIL=2021-09-20T170000 is applied

Then the recurring dates should be

date
2021-09-20T00:00:00
2021-09-20T03:00:00
2021-09-20T06:00:00
2021-09-20T09:00:00
2021-09-20T12:00:00
2021-09-20T15:00:00

Given the start date 2021-09-20T09:00:00

When the rrule FREQ=MINUTELY;INTERVAL=15;COUNT=6 is applied

Then the recurring dates should be

date
2021-09-20T09:00:00
2021-09-20T09:15:00
2021-09-20T09:30:00
2021-09-20T09:45:00
2021-09-20T10:00:00
2021-09-20T10:15:00

Given the start date 2021-09-20T09:00:00

When the rrule FREQ=WEEKLY;COUNT=6 is applied

Then the recurring dates should be

date
2021-09-20T09:00:00
2021-09-27T09:00:00
2021-10-04T09:00:00
2021-10-11T09:00:00
2021-10-18T09:00:00
2021-10-25T09:00:00

Feature Coverage By Scenario

Test Outcomes

Test Performance

Key Statistics

Number of Scenarios 27 Total Duration 2s
Total Number of Test Cases 27 Fastest Test 29ms
Number of Manual Test Cases 0 Slowest Test 978ms
Tests Started Apr 11, 2023 12:42:03 Average Execution Time 73ms
Tests Finished Apr 11, 2023 10:42:05 Total Execution Time 1s

Automated Tests

feature Scenario Context Steps Started Total Duration Result
Recurring Dates Computing Daily computing from a start date involving last day of a 31-day month windows 3 12:42:03 978ms SUCCESS
Recurring Dates Computing Every 10 days computing from a start date involving last day of a 31-day month windows 3 10:42:04 036ms SUCCESS
Recurring Dates Computing Every 10 days computing from a start date not involving last day of a 31-day month windows 3 10:42:04 036ms SUCCESS
Recurring Dates Computing Monthly computing from a start date involving last day of a 31-day month windows 3 10:42:04 043ms SUCCESS
Recurring Dates Computing Monthly computing from a start date involving last day of a 30-day month windows 3 10:42:04 035ms SUCCESS
Recurring Dates Computing Monthly last day computing from a start date involving last day of a 31-day month windows 3 10:42:04 040ms SUCCESS
Recurring Dates Computing Monthly last day computing from a start date not involving last day of the month windows 3 10:42:04 036ms SUCCESS
Recurring Dates Computing Monthly last day computing from a start date involving last day of a 30-day month windows 3 10:42:05 034ms SUCCESS
Recurring Dates Computing Monthly last day computing from a start date of a leap year involving last day of a 31-day month windows 3 10:42:05 037ms SUCCESS
Recurring Dates Computing Monthly last day computing from a start date involving last day of february windows 3 10:42:05 037ms SUCCESS
Recurring Dates Computing Monthly third penultimate day computing from a start date involving last day of a 31-day month windows 3 10:42:05 033ms SUCCESS
Recurring Dates Computing Monthly third penultimate day computing from a start date not involving last day of the month windows 3 10:42:05 037ms SUCCESS
Recurring Dates Computing Monthly third penultimate day computing from a start date involving last day of a 30-day month windows 3 10:42:05 031ms SUCCESS
Recurring Dates Computing Monthly third penultimate day computing from a start date involving last day of february windows 3 10:42:05 053ms SUCCESS
Recurring Dates Computing Monthly third penultimate day computing from a start date of a leap year involving last day of a 31-day month windows 3 10:42:05 048ms SUCCESS
Recurring Dates Computing Monthly and yearly computing from a start date with involving day of a 31-day month windows 3 10:42:05 053ms SUCCESS
Recurring Dates Computing Monthly and quartly computing from a start date involving last day of a 31-day month windows 3 10:42:05 044ms SUCCESS
Recurring Dates Computing Daily, monthly and yearly computing from a start date not involving last day of the month windows 3 10:42:05 034ms SUCCESS
Recurring Dates Computing Monthly on the 1st Friday from a start date involving last day of a 31-day month windows 3 10:42:05 056ms SUCCESS
Recurring Dates Computing Monthly on the 2nd and 15th from a start date involving last day of a 31-day month windows 3 10:42:05 052ms SUCCESS
Recurring Dates Computing Monthly on the first and last day from a start date involving last day of a 31-day month windows 3 10:42:05 044ms SUCCESS
Recurring Dates Computing Every Monday of every month computing from a start date involving last day of a 31-day month windows 3 10:42:05 035ms SUCCESS
Recurring Dates Computing The U.S. Presidential Election day computing from 2020 windows 3 10:42:05 034ms SUCCESS
Recurring Dates Computing Every 3 hours from 9h00 AM to 5h00 PM on a specific day windows 3 10:42:05 036ms SUCCESS
Recurring Dates Computing Every 3 hours from 00h00 to 5h00 PM on a specific day windows 3 10:42:05 030ms SUCCESS
Recurring Dates Computing Every a quarter of an hour for 6 occurrences windows 3 10:42:05 031ms SUCCESS
Recurring Dates Computing Weekly for 6 occurrences windows 3 10:42:05 029ms SUCCESS

Manual Tests

No manual tests were recorded
Serenity BDD version 3.6.22