Ricki Moore
Ricki Moore

Reputation: 1223

Php Laravel date array loop logic

Im working on a project that requires to schedule events with the ability to repeat them for a specific length of time. My goal is to pass the initial date from the form and increment it by 7 so that the date will land on the same weekday for the number of iterations selected. I have accounted for dates that stretch into new months and new years. However towards the end of the loop the dates get off. An example of the error :

Error:

    array:16 [
  0 => "2016-07-05"
  1 => "2016-07-12"
  2 => "2016-07-19"
  3 => "2016-07-26"
  4 => "2016-08-02"
  5 => "2016-08-09"
  6 => "2016-08-16"
  7 => "2016-08-23"
  8 => "2016-08-30"
  9 => "2016-09-06"
  10 => "2016-09-13"
  11 => "2016-09-20"
  12 => "2016-09-27"
  13 => "2016-10-03" --> should be 10-04
  14 => "2016-10-10" --> should be 10-11
  15 => "2016-10-17" --> should be 10-18
]

another example:

array:16 [
  0 => "2016-12-01"
  1 => "2016-12-08"
  2 => "2016-12-15"
  3 => "2016-12-22"
  4 => "2016-12-29"
  5 => "2017-01-05"
  6 => "2017-01-12"
  7 => "2017-01-19"
  8 => "2017-01-26"
  9 => "2017-02-02"
  10 => "2017-02-09"
  11 => "2017-02-16"
  12 => "2017-02-23"
  13 => "2017-03-02"
  14 => "2017-03-06" --> should be 03-09
  15 => "2017-03-13" --> should be 03-16
]

Here is the function I made:

First I pass the request from the controller to the model. Then i take the initial date and break it into initial year, month and day. Now im working on the weekly repeat for the limit of classes available. I increment the initial day by 7 taking to account if it goes past the number of days in that month and incrementing that month and year when needed. Every date I make is pushed into the array above. Can you help find the missing step which is making the dates get off at towards the end of the loop?

    public static function repeat_array($request){
    $repeat = $request->get('repeat_event');
    $iteration = $request->get('repeat_iteration');
    $initial = $request->get('date');


    $mySets = Packages::my_sets();
    $myReps = Packages::my_reps();
    $initial_Y = date('Y',strtotime($initial));
    $initial_M = date('m',strtotime($initial));
    $initial_D = date('d',strtotime($initial));

    $days_in_month = date('t',strtotime($initial_Y.'-'.$initial_M.'-01'));
    $current_count = CalenderEvents::class_count();

    $class_limit = $mySets*$myReps;


    if($current_count >= $class_limit){
        dd('too many');
    } else{
        if($repeat == 'weekly'){
            if($iteration == 'Null'){
                $weekly_array = [];
                $loop_date = $initial_D;
                $loop_month = $initial_M;
                $loop_year = $initial_Y;
                for($i = 0; $i < $class_limit; $i++){   -> //loop through the dates until limit is reached.
                    if($i == 0){   --> push the initial date as the first value in array. 
                        array_push($weekly_array, $initial);
                    } else{     --> increment the day by 7. 

                        $loop_date = $loop_date + 7;

                    if ($loop_date > $days_in_month){   --> //when the dates surpasses the amount of days in the month increment the month and subtract 30 from the total to get correct date. 

                            $loop_date = $loop_date - 30;
                            $loop_month++;

                        if($loop_month > 12){

                            $loop_month = 1;
                            $loop_year++;
                            $loop_date = $loop_date - 1;

                                $date = date('Y-m-d',strtotime($loop_year.'-'.$loop_month.'-'.$loop_date));

                                array_push($weekly_array, $date);

                            } else{

                                $loop_date = $loop_date - 1;

                                $date = date('Y-m-d',strtotime($loop_year.'-'.$loop_month.'-'.$loop_date));

                                array_push($weekly_array, $date);
                            }

                        } else{

                            $date = date('Y-m-d',strtotime($loop_year.'-'.$loop_month.'-'.$loop_date));

                            array_push($weekly_array, $date);

                        }
                    }
                }
                dd($weekly_array);
            }
        }
        $remainder = $class_limit - $current_count;
    }

    return true;
}

Upvotes: 2

Views: 2168

Answers (1)

Lex Lustor
Lex Lustor

Reputation: 1615

You can use relative formats with dates in php to make interpolate dates.

Init your date with a DateTime class

$date = new DateTime($initial)

keep the date formatted in you array

$weekly_array[] = $date->format('Y-m-d')

and for each iteration

$date = $date->modify('+1 week');
$weekly_array[] = $date->format('Y-m-d')

This handles well the passage to the next year as shown in that ideone example.

Upvotes: 3

Related Questions