rlanvin / php-rrule Goto Github PK
View Code? Open in Web Editor NEWLightweight and fast recurring dates library for PHP (RFC 5545)
License: Other
Lightweight and fast recurring dates library for PHP (RFC 5545)
License: Other
Is there any code available to rebuild the RFC5545 string from the arrays produced from the RSet() method?
My team noticed an issue when using this library to create RRules, in that when you create a rule from an array of values that contain parts with a value of 0
, and then use RRule->rfcString()
, the items with a value of 0
are dropped.
For example:
$rrule = new RRule(["FREQ" => "DAILY", "BYMINUTE" => 0, "BYHOUR" => 0]);
echo $rrule->rfcString();
Actual: FREQ=DAILY;
Expected value: FREQ=DAILY;BYMINUTE=0;BYHOUR=0;
This doesn't make any difference when figuring out recurrences, etc. as 0 would be a default value. However, the lack of a value is playing havoc within our application as we treat null
values differently from 0
values.
I think this line of code is the culprit:
https://github.com/rlanvin/php-rrule/blob/master/src/RRule.php#L640
Replacing if ( $value )
with if ( isset($value) )
would resolve the issue. Happy to submit a PR. :)
Hi,
thanks for the library. I'm using it in a recurring dates module for Drupal 8. I could make use of the getRule method that was recently added but do not want to require a development snapshot, so could you maybe create a 1.3.2 release that includes the recent commits?
I think I am running into an issue with a daylight savings and timezones.
When I create a php-rrule that the repeating time starts before a daylight savings and crosses over a daylight savings time change the UTC time that is being generated is not changing based on timezone that was entered.
For example
[value] => 2018-03-19T13:30:00
[end_value] => 2018-03-19T21:00:00
[rrule] => RRULE:FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR,SA,SU;UNTIL=20180331T000000Z
[infinite] => 0
[timezone] => America/Toronto
America/Toronto should be have a DST of +4 before 11-Mar-2018
My repeating events having times of the following which are correct.
2018-03-19T13:30:00 | 2018-03-19T21:00:00
2018-03-20T13:30:00 | 2018-03-20T21:00:00
2018-03-21T13:30:00 | 2018-03-21T21:00:00
2018-03-22T13:30:00 | 2018-03-22T21:00:00
2018-03-23T13:30:00 | 2018-03-23T21:00:00
2018-03-24T13:30:00 | 2018-03-24T21:00:00
2018-03-25T13:30:00 | 2018-03-25T21:00:00
2018-03-26T13:30:00 | 2018-03-26T21:00:00
2018-03-27T13:30:00 | 2018-03-27T21:00:00
2018-03-28T13:30:00 | 2018-03-28T21:00:00
2018-03-29T13:30:00 | 2018-03-29T21:00:00
2018-03-30T13:30:00 | 2018-03-30T21:00:00
Then If I set the Rrule to before the 11-Mar-2018 it set's all of the occurrences to the initial time set +5.
[value] => 2018-03-10T14:30:00
[end_value] => 2018-03-10T22:00:00
[rrule] => RRULE:FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR,SA,SU;UNTIL=20180331T000000Z
[infinite] => 0
[timezone] => America/Toronto
2018-03-10T14:30:00 | 2018-03-10T22:00:00
2018-03-11T14:30:00 | 2018-03-11T22:00:00
2018-03-12T14:30:00 | 2018-03-12T22:00:00
2018-03-13T14:30:00 | 2018-03-13T22:00:00
2018-03-14T14:30:00 | 2018-03-14T22:00:00
2018-03-15T14:30:00 | 2018-03-15T22:00:00
2018-03-16T14:30:00 | 2018-03-16T22:00:00
2018-03-17T14:30:00 | 2018-03-17T22:00:00
2018-03-18T14:30:00 | 2018-03-18T22:00:00
2018-03-19T14:30:00 | 2018-03-19T22:00:00
2018-03-20T14:30:00 | 2018-03-20T22:00:00
2018-03-21T14:30:00 | 2018-03-21T22:00:00
2018-03-22T14:30:00 | 2018-03-22T22:00:00
2018-03-23T14:30:00 | 2018-03-23T22:00:00
2018-03-24T14:30:00 | 2018-03-24T22:00:00
2018-03-25T14:30:00 | 2018-03-25T22:00:00
2018-03-26T14:30:00 | 2018-03-26T22:00:00
2018-03-27T14:30:00 | 2018-03-27T22:00:00
2018-03-28T14:30:00 | 2018-03-28T22:00:00
2018-03-29T14:30:00 | 2018-03-29T22:00:00
2018-03-30T14:30:00 | 2018-03-30T22:00:00
Shouldn't the occurrences switch to +4 hours after the 11-Mar-2018 ?
Hi, is exdate supported? I can see its present in the createFromRfcString function but when I try to use it I get the following error - Unsupported parameter(s): EXDATE
Hi,
Nice job on this RRule library. I did notice something weird with autocompletion. Some DateTime objects are referred to as "DaeTime". It appears that you made a typo on line 983.
Cheers,
Wouter
Hello, I'm trying to set up rules similar to the following:
Repeat [Monthly], [BY DAY], Where the Day = [TU] and is the [First] Day Of The Month
Words in brackets being variables that may change.
My problem at the moment is i'm unable to return the first Tuesday of every month. It seems Interval
works to return only 1 day out of the month but Interval
gets cancelled out if i use it in conjunction with byday
.
$rset = new RSet();
$rset->addRRule(array(
'freq' => RRule::MONTHLY,
'interval' => 1,
'count' => $count,
'byday' => 'TU',
'dtstart' => '2015-10-06 09:00:00'
));
$count being the total months between dtstart and the end date.
<?php
date_default_timezone_set("America/Chicago");
require "inc/php-rrule/RRuleInterface.php";
require "inc/php-rrule/RRule.php";
require "inc/php-rrule/RSet.php";
use RRule\RRule;
$rrule = new RRule(array(
"freq" => "WEEKLY",
"dtstart" => 1470323171,
"interval" => 1
));
$rfcString = $rrule->rfcString();
echo "<b>The RFC string is:</b> " . $rfcString . "<br><br>";
echo "<b>Parsing RFC string:</b> ";
$new_rrule = new RRule($rfcString);
generates the following output:
The RFC string is: DTSTART;TZID=+00:00:20160804T150611 RRULE:FREQ=WEEKLY
Parsing RFC string: Fatal error: Uncaught exception 'InvalidArgumentException' with message 'Invalid DTSTART property: date or date time format incorrect' in /path/to/php-rrule/RRule.php:649
This is because the RFC string generated has the timezone set as "+00:00" rather than "UTC".
Exception: DateTimeZone::__construct(): Unknown or bad timezone (W. Europe Standard Time) in /****/vendor/rlanvin/php-rrule/src/RfcParser.php:131
Upon further inspection it seems that this timezone is a creation by Microsoft. This format is used by Microsoft's mail services (Windows mail, Outlook). It would be nice if a simple translation from windows timezone to Php timezone was added.
Something as such would suffice:
https://github.com/sabre-io/vobject/blob/master/lib/timezonedata/windowszones.php
For future updates I'm considering dropping support for PHP version below 5.6, since they reached end of life a long time ago.
In particular, I think this would allow me to rewrite the main method as a proper generator instead of the current awkward implementation with static variables.
Since this would break backwards compatibility, it would be a version 2.x. Version 1.x would still be available, but not supported anymore.
Anybody here still requires PHP 5.3-5.5 for some reason?
Hey, there is a difference between the latest tag and the master branch, so I can't benefit from createFromRfcString
for instance and I don't want to move to master in my composer.json config.
v1.4.2...master
Hello!
I was trying to access the DTSTART datetime
object here, and so I went on and did the following:
$rule = new Rrule($show->rrule);
$dtstart = $rule['dtstart'];
// and sure enough, I get the datetime object.
Now I want to get, for the purpose of this issue, the count value.
// my first thought was to go and use this
$rule = new Rrule($show->rrule);
$values = $rule->getRule();
$count = $values['COUNT'];
// this works fine
//but if I do this...
$count = $rule['count']
// the return value is the datetime object for DTSTART
Is this... Normal behavior? I mean, if I can access the DTSTART property like so, I'd expect the others to be available too.
I have a rrule as below.
$rrule = new RRule([
'FREQ' => 'WEEKLY',
'INTERVAL' => 3,
'BYDAY' => 'WE,SA',
'DTSTART' => '2015-05-21',
'UNTIL' => '2018-12-31'
]);
it provide me first occurrence at "Sat 23 May 2015" and last as "Sat 15 Dec 2018"
what if i want only get only recurrence which are about to happen only in 2018, if I ignore other year recurrence in loop then it would not be best practice
I get this error on calling the humanReadable function.
The locale option does not look like a valid locale: en_sg
On passing the locale explicitly like below code it gives an other error.
$rrule->humanReadable(['locale'=>'en']);
( ! ) Fatal error: Call to a member function format() on null in /var/www/propsage/vendor/rlanvin/php-rrule/src/RRule.php on line 2362
I find my rrule strings losing formatting upon storing and retrieving them from my db.
In my code I was able to get around this by doing a string replace for space against "\n" right before sending them into the constructor for an RRule.
Just thought this repository could benefit from adding that little check for proper formatting.
I'm trying to create a bi-weekly rule that occurs every other Friday. I would expect the first occurrence to always be the first Friday after the DTSTART but that is only true when the WKST is one day after the BYDAY.
Example:
'FREQ' => 'WEEKLY',
'INTERVAL' => 2,
'BYDAY' => 'FR',
'WKST' => 'SU',
'DTSTART' => '2017-10-07',
'COUNT' => 10,
With a DTSTART of 2017-10-07 I would expect the first occurrence to be 2017-10-13 but instead it is 2017-10-20.
If the DTSTART is changed to 2017-10-08 then the first occurrence changes to 2017-10-13.
It works as I expect if the WKST is always one day after the BYDAY as in the following example:
'FREQ' => 'WEEKLY',
'INTERVAL' => 2,
'BYDAY' => 'FR',
'WKST' => 'SA',
'DTSTART' => '2017-10-07',
'COUNT' => 10,
Is this the intended behavior?
Would it be possible to exclude a range of days from a recurrence.
Example
DTSTART:20170501T090000Z
RRULE:FREQ=WEEKLY;UNTIL=20170531T090000Z;BYDAY=MO,TU
EXRULE:FREQ=WEEKLY;DTSTART=20170508T120000Z;UNTIL=20170509T140000Z;BYDAY=MO
I want to add a recurrence for the whole month of May but exclude a period on the 9th between 12PM and 2PM, or even a longer period from May 8th to May 9th.
As of today, I can't add a DTSTART in an EXRULE, so could I determine a start for the exception ?
Do I need to add as many EXDATE as there are in the range ?
Is there a way to get only one upcoming and past occurrence? instead of all occurrences?
I hope you don't mind me asking a support question, if so, please close this issue.
I am looking for the first 'occurrence' for an event in the future, with a 'DTSTART' in history.
A possible solution would be to create, say 10, occurrences from 'DTSTART', check if there is one in the future, if not create an other 10 etc...
Not very neatly I think. Is there a better solution for this kind of rule?
Hi,
According to the RFC 5545 DTSTART can also be defined in local (floating) time. This means that no timezone information will be appended to the DTSTART field.
When I assign a datetime to DTSTART (in format 2019-08-20 17:00:00) the UTC timezone will still be appended (by 'Z').
Does this package support floating times for DTSTART?
Regards,
Chris
First off - thanks for this. This is working very well for us!
It would be awesome to be able to tell the RRule class to use a different translation file for a specific locale. This way if we want things to be worded differently, we can simply copy the appropriate local file, make the changes, and tell the script on the fly where to find the new translation file.
This would be a huge help to me currently as I'm trying to get the results closer to what the app designer mocked up in my API.
Translation in /src/i18n/nl.php#L48 must be ', wordt gestart vanaf %{date}'
Get this error while creating rrule object from this string -
new RRule("DTSTART=20160107T160000Z;FREQ=DAILY;INTERVAL=1
")
This string is not compliant with the RFC (DTSTART cannot be part of RRULE). It is accepted as is for compability reasons only.
trace -
/vendor/rlanvin/php-rrule/src/RRule.php(199): parseRfcString()
rlanvin/php-rrule/src/RRule.php(768): trigger_error()
Hi,
i have a little problem with RRule->rfcString().
$myRule = new \RRule\RRule([
'FREQ' => 'WEEKLY',
'INTERVAL' => 1,
'BYDAY' => 'MO'
]);
$myRFCString = $myRule->rfcString();
This RFC String is generated.
FREQ=WEEKLY;BYDAY=MO
If i take this String and do somthing like this.
$rrule = new RRule($myRFCString, new DateTime());
$myReadableText = $rrule->humanReadable(
[
'locale' => 'de',
'date_formatter' => function ($date) {
return $date->format('d.m.Y');
}
]
);
An Exception will be throwed.
The INTERVAL rule part must be a positive integer (> 0)
In the rfcString Function the INTERVAL will be skiped if the Value is the default Value. (eg. 1).
Line 613 in c543bda
That cause a InvalidArgumentException in humanReadable.
Hi again,
While playing around with RRule I found that on lines 947 and 952 LogicException is referenced within the RRule namespace, rather than the global namespace.
And perhaps you could reference such dependencies as at the top of the file (e.g. "use LogicException;" ). That provides a bit more clarity concerning the external classes you use.
Thanks in advance! And now I'm off to find out what I did wrong to generate this Exception ;)
Cheers,
Wouter
Does the library support the DTEND parameter? or anything duration related?
I follow the example here https://github.com/rlanvin/php-rrule/wiki/RSet#iteration But I think it should be like this
use RRule\RSet;
$rset = new RSet;
$rset->addRRule([
'freq' => RRule::DAILY,
'interval' => 2,
'count' => 5,
'dtstart' => '1997-09-02 09:00:00'
]);
$rset->addExDate('1997-09-06 09:00:00');
foreach ( $rset as $occurrence ) {
echo $occurrence->format('r'),"\n";
}
// output:
// Tue, 02 Sep 1997 09:00:00 +0000
// Thu, 04 Sep 1997 09:00:00 +0000
// (Sat, 06 Sep 1997 09:00:00 +0000 will not be outputed because it is in EXDATE)
// Mon, 08 Sep 1997 09:00:00 +0000
// Wed, 10 Sep 1997 09:00:00 +0000
// Fri, 12 Sep 1997 09:00:00 +0000
Because we have count = 5, if 06 Sep 1997 is remove, 12 Sep 1997 should add in the end. In your example you only show 4 occurrences. I think it doesn't make sense :)
The file src/RRule.php, on line 660
static public function parseRfcString($string)
{
trigger_error('parseRfcString() is deprecated - use new RRule(), RRule::createFromRfcString() or \RRule\RfcParser::parseRRule() if necessary',E_USER_DEPRECATED);
return RfcParser::parseRRule($sring);
}
is returning a misspelled $sring variable instead of $string, that causes an error on parsing the provided text.
First I'd like to thank you for your work on this very useful library.
This is actually not an issue, but I'd like to access the "UNTIL" property in occurrences object (which now contains only date object). I'm using your library for event entry and (miss)use the "DTSTART" and "UNTIL" for start and end timestamp, because of that I need access to the UNTIL so that I can get the correct end time (UNTIL is provided as a timestamp).
I've been looking at the source and trying to find a way to add the "UNTIL" property (which is only available in the "rrule" object) to the "occurrence" object, but have failed to do so (simply don't know how to merge the property into "rlist_iterator").
Running RRuleTest on non-isolated environment may break other tests/behaviour, by not reverting to default after test ends.
We have a use-case where we want to remove ExDates and RDates from RSets. The most simple way to do this in my opinion would be to add setters for RSet attributes into the RSet class. If I made a PR with that functionality & tests for it, would that be something that would be accepted?
Further, we have some code that pieces together an RFC string from an RSet, however, like was mentioned here it needs to be opinionated about how to reconstruct it (remove DTStarts from RRules, and keep the top level DTStart). If I made a PR adding that functionality into the RSet class, noting specifically that some functionality is not supported (multiple DTStarts) would that be accepted?
Hi, I was wondering if EXDATE is something you would consider implementing?
Thanks.
The library is fantastic, by the way.
I made a function for generating string from Rset i'd be glad to see equivalent in official distribution
` public function toString()
{
$rrules = $this->getRRules();
$string = '';
foreach ($rrules as $rrule)
$string .= $rrule->rfcString() . PHP_EOL;
$exdates = $this->getExDates();
if (count($exdates)) {
$string .= 'EXDATE:';
foreach ($exdates as $date)
$string .= $date->format(ISO_FORMAT) . ',';
$string = rtrim($string, ',');
$string .= PHP_EOL;
}
return $string;`
that's my code
How does this library handle monthly recurrences on the 29th-31st days, over months which don't have those days? Does it skip them, or default to the last day in that month? Is this configurable?
ie
2013-01-31, 2013-02-28, 2013-03-31, 2013-04-30, 2013-05-31
or
2013-01-31, ___skipped, 2013-03-31, ___skipped, 2013-05-31
This discusses the issue, and a solution I think:
rfc7529 #section-4.1
So I suppose my question is ultimately, has SKIP been implemented?
Hi!
Thanks for the great library. When I pass in a simple RRULE (the three steps are a quirk of the larger project...):
$datestring = 'RRULE:FREQ=WEEKLY;BYDAY=WE';
$datearray = \RRule\RfcParser::parseRRule($datestring);
$rrule = new RRule($datearray);
and then try to find the next occurrence (based on code you've provided elsewhere here)
$today = date('Y-m-d\TH:i:m');
$next = $rrule->getOccurrencesBetween($today, null, 1);
I get the following error:
Error: Call to a member function format() on boolean in RRule\RRule->iterate() (line 1659 of /var/www/vendor/rlanvin/php-rrule/src/RRule.php).
RRule\RRule->iterate() (Line: 1035)
RRule\RRule->next() (Line: 194)
However, when I add an end date, the error no longer appears (
RRULE:FREQ=WEEKLY;BYDAY=WE;UNTIL=22000101T070000Z
).
We've worked around this locally by appending a far future UNTIL for user-created repeating events.
php-rrule release: v1.4.0
I'm creating an RRule instance: $rrule = new RRule('DTSTART=20170202T000000Z;FREQ=DAILY;UNTIL=20170205T000000Z')
I get an exception thrown as follows:
Invalid UNTIL property: The value of the UNTIL rule part MUST be a date if DTSTART is a date.
Stack:
in vendor/rlanvin/php-rrule/src/RRule.php at line 723 -
switch ( $dtstart_type ) {
case 'date':
if ( strpos($value, 'T') !== false) {
throw new \InvalidArgumentException(
'Invalid UNTIL property: The value of the UNTIL rule part MUST be a date if DTSTART is a date.'
);
}
at RRule ::parseRfcString ('DTSTART=20170202T000000Z;FREQ=MONTHLY;UNTIL=20170706T000000Z')
in vendor/rlanvin/php-rrule/src/RRule.php at line 187 +
at RRule ->__construct ('DTSTART=20170202T000000Z;FREQ=MONTHLY;UNTIL=20170706T000000Z')
I had a look into the cause and it seems to be because UNTIL
is being parsed before DTSTART
.
The variable $dtstart_type
is initialised to date
on line 648, so if it parses UNTIL
first then it will always throw this error if UNTIL
is a string.
Actually i'm not entirely sure what the desired behaviour is as there is no handling of DTSTART
specifically within the RRULE
case there. I think my string will always end up in the RRULE
case?
If I can understand the thinking then I can maybe help with fixing for my particular use case. Or if my case is invalid then please let me know! I'm no master of the rrule rfc!
I am using codeigniter
I installed this library through composer.
I created a object to use this, but I am getting this error
It would be really useful if RSet's could support having a mix of RRule's and ExRule's, where subsequent rules would override previous ones.
For example:
use RRule\RSet;
$set = new RSet();
$set->addRRule([
'FREQ' => 'HOURLY',
'DTSTART' => '20180404T080000Z',
'UNTIL' => '20180405T160000Z',
]);
$set->addExRule([
'FREQ' => 'HOURLY',
'DTSTART' => '20180404T160000Z',
'UNTIL' => '20180405T080000Z',
]);
$set->addRRule([
'FREQ' => 'HOURLY',
'DTSTART' => '20180404T180000Z',
'UNTIL' => '20180405T020000Z',
]);
foreach ($set as $date)
echo $date->format('r'), "\n";
Would ideally output:
Wed, 04 Apr 2018 08:00:00 +0000
Wed, 04 Apr 2018 09:00:00 +0000
Wed, 04 Apr 2018 10:00:00 +0000
Wed, 04 Apr 2018 11:00:00 +0000
Wed, 04 Apr 2018 12:00:00 +0000
Wed, 04 Apr 2018 13:00:00 +0000
Wed, 04 Apr 2018 14:00:00 +0000
Wed, 04 Apr 2018 15:00:00 +0000
Wed, 04 Apr 2018 18:00:00 +0000
Wed, 04 Apr 2018 19:00:00 +0000
Wed, 04 Apr 2018 20:00:00 +0000
Wed, 04 Apr 2018 21:00:00 +0000
Wed, 04 Apr 2018 22:00:00 +0000
Wed, 04 Apr 2018 23:00:00 +0000
Thu, 05 Apr 2018 00:00:00 +0000
Thu, 05 Apr 2018 01:00:00 +0000
Thu, 05 Apr 2018 02:00:00 +0000
Thu, 05 Apr 2018 09:00:00 +0000
Thu, 05 Apr 2018 10:00:00 +0000
Thu, 05 Apr 2018 11:00:00 +0000
Thu, 05 Apr 2018 12:00:00 +0000
Thu, 05 Apr 2018 13:00:00 +0000
Thu, 05 Apr 2018 14:00:00 +0000
Thu, 05 Apr 2018 15:00:00 +0000
Thu, 05 Apr 2018 16:00:00 +0000
Where currently it outputs:
Wed, 04 Apr 2018 08:00:00 +0000
Wed, 04 Apr 2018 09:00:00 +0000
Wed, 04 Apr 2018 10:00:00 +0000
Wed, 04 Apr 2018 11:00:00 +0000
Wed, 04 Apr 2018 12:00:00 +0000
Wed, 04 Apr 2018 13:00:00 +0000
Wed, 04 Apr 2018 14:00:00 +0000
Wed, 04 Apr 2018 15:00:00 +0000
Thu, 05 Apr 2018 09:00:00 +0000
Thu, 05 Apr 2018 10:00:00 +0000
Thu, 05 Apr 2018 11:00:00 +0000
Thu, 05 Apr 2018 12:00:00 +0000
Thu, 05 Apr 2018 13:00:00 +0000
Thu, 05 Apr 2018 14:00:00 +0000
Thu, 05 Apr 2018 15:00:00 +0000
Thu, 05 Apr 2018 16:00:00 +0000
The difference:
Wed, 04 Apr 2018 08:00:00 +0000
Wed, 04 Apr 2018 09:00:00 +0000
Wed, 04 Apr 2018 10:00:00 +0000
Wed, 04 Apr 2018 11:00:00 +0000
Wed, 04 Apr 2018 12:00:00 +0000
Wed, 04 Apr 2018 13:00:00 +0000
Wed, 04 Apr 2018 14:00:00 +0000
Wed, 04 Apr 2018 15:00:00 +0000
- Wed, 04 Apr 2018 18:00:00 +0000
- Wed, 04 Apr 2018 19:00:00 +0000
- Wed, 04 Apr 2018 20:00:00 +0000
- Wed, 04 Apr 2018 21:00:00 +0000
- Wed, 04 Apr 2018 22:00:00 +0000
- Wed, 04 Apr 2018 23:00:00 +0000
- Thu, 05 Apr 2018 00:00:00 +0000
- Thu, 05 Apr 2018 01:00:00 +0000
- Thu, 05 Apr 2018 02:00:00 +0000
Thu, 05 Apr 2018 09:00:00 +0000
Thu, 05 Apr 2018 10:00:00 +0000
Thu, 05 Apr 2018 11:00:00 +0000
Thu, 05 Apr 2018 12:00:00 +0000
Thu, 05 Apr 2018 13:00:00 +0000
Thu, 05 Apr 2018 14:00:00 +0000
Thu, 05 Apr 2018 15:00:00 +0000
Thu, 05 Apr 2018 16:00:00 +0000
I'm not sure how inline this is with the spec, but it would definitely be a useful feature for advanced event generation.
Hey there! I just came across this library (https://github.com/rlanvin/php-rrule), and I was hoping to ask you a couple questions about it, if you don't mind. โค๏ธ
To date I've used the https://github.com/simshaun/recurr library on my projects. Did you create your library because you were not happy with this specific implementation? I'm curious if you're able to share how your library is different?
The one issue I ran into when generating RRULEs is performance. Everything works okay if you're only generating a set of dates for a short period of time, but if you generate them for a long period of time it can be a very slow process.
For example, someone may choose to create a recurring date that started 5 years ago and repeats every single week. I may have a calendar that I want to show all the events on for the current month. With the simshaun/recurr library I can scope the results between two dates (the current month), which is great, but really all it does it run the RRULE for the entire time period and then chop off dates outside of the range given. This had led to poor performance, since it takes a bit to generate them all.
Does this library do things any different? How's the performance for large date ranges like this?
Thanks!
Hi,
First : thank you for this wonderful library !
When I create a new recurrence from a string pattern like the following one, the last occurence is missing.
Example :
FREQ=DAILY;INTERVAL=1;UNTIL=20160629
$recurrence = new Recurrence($startdate, $pattern);
//$startdate 24/06/2016 10:00 UTC for the example below
$rset = $recurrence->getRSet();
foreach($rset as $occurence) {
print_r($occurrence);
}
That will give you :
[Thu Jun 23 11:17:43.218553 2016] [:error] [pid 6821] [client 127.0.0.1:50212] DateTime Object\n(\n [date] => 2016-06-24 10:00:00.000000\n [timezone_type] => 3\n [timezone] => Etc/GMT\n)\n, referer: http://127.0.0.1/epeires2b/
[Thu Jun 23 11:17:43.219020 2016] [:error] [pid 6821] [client 127.0.0.1:50212] DateTime Object\n(\n [date] => 2016-06-25 10:00:00.000000\n [timezone_type] => 3\n [timezone] => Etc/GMT\n)\n, referer: http://127.0.0.1/epeires2b/
[Thu Jun 23 11:17:43.219498 2016] [:error] [pid 6821] [client 127.0.0.1:50212] DateTime Object\n(\n [date] => 2016-06-26 10:00:00.000000\n [timezone_type] => 3\n [timezone] => Etc/GMT\n)\n, referer: http://127.0.0.1/epeires2b/
[Thu Jun 23 11:17:43.220017 2016] [:error] [pid 6821] [client 127.0.0.1:50212] DateTime Object\n(\n [date] => 2016-06-27 10:00:00.000000\n [timezone_type] => 3\n [timezone] => Etc/GMT\n)\n, referer: http://127.0.0.1/epeires2b/
[Thu Jun 23 11:17:43.220390 2016] [:error] [pid 6821] [client 127.0.0.1:50212] DateTime Object\n(\n [date] => 2016-06-28 10:00:00.000000\n [timezone_type] => 3\n [timezone] => Etc/GMT\n)\n, referer: http://127.0.0.1/epeires2b/
In the documentation -- https://github.com/rlanvin/php-rrule/wiki/RRuleInterface -- informs getOccurencesBetween(), but corret is getOccurrencesBetween()
Hi there,
Is it possible to include a method in the library that returns the first recurrence after the given datetime instance? Something like what has been done in python-dateutil (https://labix.org/python-dateutil). The method that I am referring to here is rruleset.after(dt, inc=False)
Thank you!
Hi @rlanvin,
Seems like it's impossible to use the RRule::humanReadable()
method if the \Locale
doesn't exist, or if the locale is wrong. There are some cases where the default Locale
is en_US_POSIX
which in turn triggers an exception in RRule::i18nLoad()
line 2022
. Would it be possible to fallback to en
if the locale isn't set or isn't supported?
I could make a PR for it if you'd like, just wondering if that's something you see as fitting in this case?
This error is only triggered when intl
fails to load:
InvalidArgumentException: The locale option does not look like a valid locale: LC_CTYPE=en_US.UTF-8;LC_NUMERIC=C;LC_TIME=C;LC_COLLATE=C;LC_MONETARY=C;LC_MESSAGES=C;LC_PAPER=C;LC_NAME=C;LC_ADDRESS=C;LC_TELEPHONE=C;LC_MEASUREMENT=C;LC_IDENTIFICATION=C. For more option install the intl extension.
The regex here expects locale in format such as en_US.UTF-8
instead of what's given:
https://github.com/rlanvin/php-rrule/blob/master/src/RRule.php#L2084
According to setlocale
specs, all these extra parameters will normally be returned for setLocale(LC_ALL, 0)
, which is called here:
https://github.com/rlanvin/php-rrule/blob/master/src/RRule.php#L2193
To only get en_US.UTF-8
we'll want to use LC_CTYPE
instead:
https://www.php.net/manual/en/function.setlocale.php#106811
Applying this change on my test site solved the problem for me.
With the Python version (python dateutils), it is possible to parse a RFC string with multiple RRULE
lines (or RDATE
, EXDATE
, EXRULE
) directly into a RSet. That could be interesting to have as well.
This will require some refactoring of RRule::parseRfcString()
to make it a factory method, or coding an actual factory method on top of it.
The constructor would still only return a RRule
since it is probably not possible and not advisable to have the constructor returns a different object.
A RSet should also be able to be formatted into a RFC String with multiple lines.
If this is a feature that would be useful, leave a ๐
Packagist doesn't contain the latest fixes because it is stuck at version 1.6.1.
Can you please create a new ta 1.6.2. for current master?
An issue with v2.1.0 that did not exist in v1.6.2
A weekly recurrance rule is limited to 1460 elements whereas the earlier version seems unlimited. Code example below:
$rruleConfig = [
'FREQ' => "WEEKLY",
'INTERVAL' => 1,
'DTSTART' => 1572503950,
'COUNT' => 2000
];
$rrule = new RRule\RRule($rruleConfig);
$instCount=0;
foreach ($rrule as $instCount => $row){
$instDT = date_timestamp_get($row);
echo $instCount." ".$instDT."
";
$instCount ++;
}
Hai @rlanvin ,
I would like to parse this string
[CASE]
RRULE:FREQ=MONTHLY;DTSTART=20170201T010000Z;UNTIL=20170228T030000Z;BYDAY=TU,RDATE:20170222T010000Z,EXDATE:20170221T010000Z
.
The library does parses it but it igores the EXDATE and the RDATE.
[Example output]
Array ( [FREQ] => MONTHLY [DTSTART] => 20170201T010000Z [UNTIL] => DateTime Object ( [date] => 2017-02-28 03:00:00 [timezone_type] => 2 [timezone] => Z ) [BYDAY] => TU,RDATE )
I checked the source code but it seems it didn't have the code to parse it.
[Question]
Could we have the ability to parse this kind of rules?
Thank you so much.
Is the library capable of parsing and generating occurrences from WordPress recurrence rules? I'm designing a cron to determine active events at the moment to deliver it on the mobile app. My idea is to
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.