Манипулирование датами в PHP - PullRequest
1 голос
/ 07 ноября 2011

Я пытаюсь повторить дату за месяц для фиксированного числа раз в цикле.Дата будет отображаться только в том случае, если дата является действительной, в противном случае она будет пропущена.Например, если «2012-02-30 10:10:00» входит в цикл, он будет проигнорирован и пропущен, и он перейдет к следующей итерации.

Приведенный ниже код отлично работает дляstart_date "2011-11-07 10:15:00", но когда я изменяю его на start_date, который комментируется, то есть "2011-11-30 10:15:00", он добавляет 24 часа после пропуска одной итерации.

Я не уверен, где я иду не так.

<?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 />";
}
?>

Ожидаемый результат для закомментированной начальной даты следующий:

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

Ответы [ 3 ]

0 голосов
/ 07 ноября 2011

Попробуйте следующее:

// 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 />';
}
0 голосов
/ 23 марта 2017

Вот короткая, заслуживающая доверия функция, которая отображает действительные метки даты и времени: онлайн-демонстрация

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);

Вывод (как требуется / ожидается):

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
0 голосов
/ 07 ноября 2011

при звонке

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

Добавляет 1 месяц к дате, но также компенсирует переменную repeat_timing. Вы добавляете 2678400 секунд к дате 30.01.2011, что соответствует примерно 1/1/2011.

Вам лучше хранить месяц, день и год отдельно от переменной даты и выполнять вычисления вручную. Это не позволит DATE изменить ваш таймфрейм.

...