1

I am trying to repeat the date by a month for a fixed number of times in a loop. It will only echo the date if the date is a valid date otherwise it will skip the date. For example if the "2012-02-30 10:10:00" is coming in the loop it will be ignored and skipped and it will move on to the next iteration.

The below code works fine for the start_date "2011-11-07 10:15:00" but when i change it to the start_date which is commented i.e. "2011-11-30 10:15:00" it adds 24 hours after the skipping one iteration.

I am not sure where I am going wrong.

<?php
//$start_date = "2011-11-30 10:15:00";
$start_date = "2011-11-07 10:15:00";
$no_of_repeat = 15;
$repeat_timing = 0;
for($x=0; $x<$no_of_repeat; $x++) {
    $start_date = date('Y-m-d G:i:s',(strtotime($start_date) + ($repeat_timing)));
    if(date("m",strtotime($start_date)) != 12) {
        $next_month = date('m',strtotime($start_date)) + 1;
        $year = date('Y',strtotime($start_date));
    } else {
        $next_month = 1 ;
        $year = date('Y',strtotime($start_date)) + 1;
    }
    $day = date("d",strtotime($start_date));
    $next_date =
    $year."-".
    $next_month."-".
    $day." ".
    date("G",strtotime($start_date)).":".
    date("i",strtotime($start_date)).":".
    date("s",strtotime($start_date));
    if(checkdate($next_month,$day,$year))
        $repeat_timing = strtotime($next_date) - strtotime($start_date);
    else
        continue;   
    echo $next_date."<br />";
}
?>

The expected outcome for the commented start_date is as follows:

2011-12-30 10:15:00
2012-1-30 10:15:00
2012-3-30 10:15:00
2012-4-30 10:15:00
2012-5-30 10:15:00
2012-6-30 10:15:00
2012-7-30 10:15:00
2012-8-30 10:15:00
2012-9-30 10:15:00
2012-10-30 10:15:00
2012-11-30 10:15:00
2012-12-30 10:15:00
2013-1-30 10:15:00
Deduplicator
  • 44,692
  • 7
  • 66
  • 118
Nihilarian
  • 1,190
  • 1
  • 10
  • 17

3 Answers3

0

Here is a short, trustworthy function that echoes valid datetime stamps: online demo

function getValidDateTimes($date,$iterations){
    if(preg_match("/(\d{4})-(\d{1,2})-(\d{2}) (.*)/",$date,$n)){ // capture datetime bits
        list(,$Y,$n,$d,$time)=$n;       // declare bits as variables for readability
        for(++$n,$x=0; $x<$iterations; ++$x,++$n){  // start with month after $start_date
            $n=($n>12?"1":$n);              // reset to 1 when month exceeds 12
            $date="$Y-$n-$d";               // build literal new date
            if($date==date("Y-n-d",strtotime($date))){  // built date versus assumed date
                echo "$date $time<br>";   // store valid date with concatenated time
            }
        }
    }
}

$start_date="2011-11-30 10:15:00";
$iterations=15;

getValidDateTimes($start_date,$iterations);

Output (as desired/expected):

2011-12-30 10:15:00
2011-1-30 10:15:00
2011-3-30 10:15:00
2011-4-30 10:15:00
2011-5-30 10:15:00
2011-6-30 10:15:00
2011-7-30 10:15:00
2011-8-30 10:15:00
2011-9-30 10:15:00
2011-10-30 10:15:00
2011-11-30 10:15:00
2011-12-30 10:15:00
2011-1-30 10:15:00
mickmackusa
  • 43,625
  • 12
  • 83
  • 136
  • @NikhilRao If you think this is the best answer in the list, please award it the green tick so that your question is removed from the unanswered questions list. If there is something not quite right, please let me know and I'll adjust it. – mickmackusa Mar 23 '17 at 12:19
0

When you call

 $start_date = date('Y-m-d G:i:s',(strtotime($start_date) + ($repeat_timing)));

It is adding 1 month to the date, but it is also compensating for the repeat_timing variable. You are adding 2678400 seconds to the date of 1/30/2011 wich equates to roughly 3/1/2011.

You are better off keeping the month, day, and year separate from the date variable and do the calculation manually. This will keep DATE from changing the timeframe on you.

James Williams
  • 4,221
  • 1
  • 19
  • 35
0

Try out the following:

// starting variables
$startDate = "2011-11-30";
$time = '10:15:00';
$numberOfTimesToRepeat = 10;

// Set our counts to 0
$count = 0;
$datesFound = 0;

// parse date
list($startYear,$startMonth,$startDay) = explode('-',$startDate);

// Create an array
while ($datesFound < $numberOfTimesToRepeat) {

    // Calculate number of months to add
    $monthsToAdd = fmod($count,12);

    // Calculate new month number
    $newMonth = (($startMonth + $monthsToAdd) > 12) ? ($startMonth + $monthsToAdd - 12) : ($startMonth + $monthsToAdd);

    // Add the leading 0 if necessary   
    if ($newMonth < 10 && strlen($newMonth) < 2) $newMonth = '0'.$newMonth;

    // Calculate number of months to add
    $yearsToAdd = floor(($count/12));

    $newYear = $startYear + $yearsToAdd;

    if (checkdate($newMonth,$startDay,$newYear)) {
        $dates[] = $newYear.'-'.$newMonth.'-'.$startDay.' '.$time;
        $datesFound++;
    }

    // increase our count either way
    $count++;

}



// Show the dates
foreach ($dates as $date) {
    echo $date.'<br />';
}
Andy Fleming
  • 7,655
  • 6
  • 33
  • 53