I have an event system set up and it works in cycles. For example, users can create events in 2, 4, 6 and 8 weekly cycles. Eventually this will be user definable.
I need to be able to calculate the current cycle for any future events that are not actually generated.
So e.g. if a user has selected a 6-week event cycle, and 9th August is cycle week 5, 16th August will be week 6, the 23rd will then be week 1, and so forth, continuously looping back through the cycle for each week. If we get all the way down to 15th November for example, that will be cycle week 1 again.
"2021-08-09"
5
"2021-08-16"
6
"2021-08-23"
1
"2021-08-30"
2
"2021-09-06"
3
What would be the best way for me to calculate the current week cycle if I know the start of the cycle and the current date? Hopefully that makes sense?
I have the following at the moment, but a loop is going to be quite expensive I'd have thought if I'm calculating this in 5-10 years time.
$start = Carbon\Carbon::parse('2021-08-09');
$end = Carbon\Carbon::parse('2021-11-15');
$cycle_weeks = 6;
$current_cycle = 5;
dump("Week - {$start->toDateString()} - Cycle {$current_cycle}");
// Get current cycle week
while ($start->lt($end)) {
$start = $start->addWeeks(1);
$current_cycle = $current_cycle + 1;
if ($current_cycle > $cycle_weeks) {
$current_cycle = 1;
}
dump("Week - {$start->toDateString()} - Cycle {$current_cycle}");
}
This gives me the date but at the expense of cycling through every week until the end date. I can't think of a mathematical way - if any - to perhaps work out the cycle based on the difference in weeks?
"Week - 2021-08-09 - Cycle 5"
"Week - 2021-08-16 - Cycle 6"
"Week - 2021-08-23 - Cycle 1"
"Week - 2021-08-30 - Cycle 2"
"Week - 2021-09-06 - Cycle 3"
"Week - 2021-09-13 - Cycle 4"
"Week - 2021-09-20 - Cycle 5"
"Week - 2021-09-27 - Cycle 6"
"Week - 2021-10-04 - Cycle 1"
"Week - 2021-10-11 - Cycle 2"
"Week - 2021-10-18 - Cycle 3"
"Week - 2021-10-25 - Cycle 4"
"Week - 2021-11-01 - Cycle 5"
"Week - 2021-11-08 - Cycle 6"
"Week - 2021-11-15 - Cycle 1"
I think this could work:
function currentCycle(Carbon $startDate, Carbon $currentDate, int $cycles, int $startCycle) {
if ($startCycle > $cycles) $startCycle = 1;
return (($currentDate->diffInWeeks($startDate)+$startCycle-1)%$cycles)+1;
}
The idea is:
$cycles
would give you a 0-based cycle number if the cycles started at $startDate
. The division remainder (mod) in PHP is given by the %
operator$startCycle-1
and add this number to the diff
result. We then covert this 0-based result back to 1-based by adding +1
at the endThis should allow you to get the cycle based on any start date, any current date, any start cycle on that start date and any number of cycles.