-
Notifications
You must be signed in to change notification settings - Fork 135
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add a getNextRecurrence method #91
Comments
Can you clarify this request? |
I guess we're always most interested in the next occurrences, and I also find it hard to get. Thanks |
As part of the refactoring I'll be doing for #94, I'll keep this issue in mind. I'm thinking that part of the public API will be |
I'm not sure if that's what @rukavina wanted to say, but trying to find the next occurence, from the present moment is what I think would be really great. Like he said, if the rule had a DTSTART far away in the past, and you just want to know when the next recurrence will happen, it's kind of counter productive to generate all of the recurrences... |
I'm not sure this is possible to do. You typically need some sort of seed date to start from. What we've don't is use redis to cache seed dates from previous expansions so we can pick a valid one to start from. The only tricky part of that is if there is a |
@AdamEsterle using @simshaun's built in array transformer with a virtual limit worked for me: use Carbon\Carbon;
use Recurr\Rule;
use Recurr\Transformer\ArrayTransformer;
use Recurr\Transformer\ArrayTransformerConfig;
use Recurr\Transformer\Constraint\AfterConstraint;
$rule = 'FREQ=MONTHLY;COUNT=12';
$rrule = new Rule(
$rule,
Carbon::now(),
null
);
$next_run_at = self::nextOccurrence($rule, $rrule, Carbon::now(), $this->count);
...
public static function nextOccurrence($ruleText, Rule $rrule, Carbon $lastRun = null, $count = 0)
{
$maxCount = $rrule->getCount();
if ($maxCount !== null && $count >= $maxCount)
{
return null;
}
$constraint = null;
$arrayTransformer = new ArrayTransformer();
$transformerConfig = new ArrayTransformerConfig();
$transformerConfig->enableLastDayOfMonthFix();
$transformerConfig->setVirtualLimit(2);
$arrayTransformer->setConfig($transformerConfig);
// if there is a last run supplied, meaning we are looking
// for the next date, not the first date,
// we will be adding an after contstraint
if ($lastRun !== null)
{
// if there was a last run, and the
// original ruleText just happens
// to contain a DTSTART, we *MUST* set the rrule object
// to use now's DTSTART instead... otherwise, the
// virtual limit will be surpassed and our result will be null
if (str_contains($ruleText, 'DTSTART=')) {
$rrule->setStartDate($lastRun);
}
$constraint = new AfterConstraint($lastRun, false);
}
$occurrences = $arrayTransformer->transform($rrule, $constraint)->map(function($occurrence) {
return Carbon::instance($occurrence->getStart());
});
if (!$occurrences->isEmpty())
{
return $occurrences->first();
}
else
{
return null;
}
} one weird thing is you have to set a virtual limit of 2, not one. you can ignore my $count logic unless you need it. Also, the virtual limit will cause your results of nextOccurrence() to be What happens for me is I have a rule like: His library uses a big array for all the generated recurrences - so I'm essentially tricking it into only making two - using only one also breaks something which I forget now. EDITED added case for resetting dtstart |
I see this request is five years old. Is there really no way to calculate the next occurrence of a date/time interval? It seems that would be the most critical thing to be able to do with a date/time interval. |
The lib was a port of rrule.js and it wasn't designed with that in mind at the time. I started a rewrite based on an iterator design, but haven't finished it; It's not a priority for me at this time. |
Okay, thank you. I'll just leave a note here for anyone that is curious. For anyone that is looking to calculate occurrences, we found this package: https://github.com/rlanvin/php-rrule We are still using this recurr package to write the rules then the rrule package has classes that provide methods for calculating occurrences based on the rule string. |
I calculated the RecurrenceCollection and used it to find the number of Recurrences
$recurrences->count()
and the first and last start dates
$recurrences->first()->getStart()
$recurrences->last()->getStart()
but I went to calculate what the next recurrence would be and there was no easy solution. I had to do a recalculation with another transform with a different end date.
It would be nice to just be able to call a method and have it return the next recurrence (perhaps by ignoring the current end date?)
The text was updated successfully, but these errors were encountered: