Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Resolve second reported problem within issue #238.
This problem was caused by an imperfect approach to translating between different week starts.
Current Approach
php
'sDateTime::setISODate()
follows ISO-8601 and expects weeks to start on a Monday, with days being identified numerically like so:rfc5545
defaults to Monday week starts, but allows alternate week starts to be used withinRRULE
s.The way I had initially implemented the translation between two different week starts was to offset the days on or after the alternate week start by -7. Thus, given
WKST=TH
, the week day numerical identifiers would be as follows:If we test this against an iCal snippet:
We would expect August 6th, 7th, 16th, 17th, 20th, 21st, 30th, and 31st, and September 3rd, 4th, 13th, and 14th.
In the first loop, the RRULE parsing code would first generate August 2nd, 3rd, 6th and 7th. The first two are before the start date, and the third date is the start date, so these three are discarded leaving August 7th.
Bump up the base date up by two weeks to 20th August (as we have an
INTERVAL
of two) and the second iteration generates August 16th, 17th, 20th, and 21st .Bump the base date up another two weeks to 3rd September, and the third iteration generates 30th and 31st of August, and the 3rd and 4th of September.
Bump up another two weeks to 17th September, and this is after the end date stated in the
UNTIL
, so we stop. But we're still missing the final two dates.Alternate Approach
An alternate way might be to offset all days before the week start by +7, so with the same
WKST
as before, the day numerical identifiers passed tosetISODate
look like the following:However this approach is also flawed. Retaining the same ICal snippet as before, the first iteration - starting at 6th August - would generate the following dates: August 9th, 10th, 13th and 14th... none of which are dates we want.
Changing the offset to +(7 x
INTERVAL
) generates the following dates on the first iteration: August 16th, 17th, 20th, 21st. Better as these are dates we'd want, but note that August 7th has not been generated (and never will be).The New Approach
The approach actually implemented in this PR is slightly more complex. Instead of one set of offsets, we have two. First, offset the day numerical ids that fall before the day of the initial date (not the
WKST
) +7. E.g. when using the same ICal snippet as before:Then, offset the days that fall on or after the
WKST
by +(7 * (INTERVAL
- 1)):Now, when we run the above snippet, the first iteration generates August 6th, 7th, 16th, and 17th.
The second iteration, starting from the base date of August 20th, generates 20th, 21st, 30th and 31st.
The third iteration, starting from the base date of September 3rd, generates September 3rd, 4th, 13th and 14th.
And the next iteration would start from the base date of September 17th, but this is after the
UNTIL
so we stop.And we now have all the dates we'd expect from this
RRULE
.Testing
This clears
composer test
; and if we test against the provided ICal snippet provided by @britweb-tim in issue #238:The day numerical ids passed to
setISODate
are:And the dates ultimately generated by the parser are: Aug 18th and 25th, and Sept 1st