カレンダーの日付範囲に基づいて毎月の定期的なイベントを計算しようとしています。February (28 days)
しかし、その月の29日にイベントが発生したときに、計算の問題に遭遇しました。私が助けを借りずに周りを検索しようとしたときに、専門家が私にいくつかの指針を与えることを願っています。
スクリプトとして直接実行しやすいように、次のコードを含めました。範囲は正常に機能しており、January
範囲に該当する2つの日付が表示されます。
// JANUARY 2013 Range (Working)
2012-12-29
2013-01-29
ただし、2月の範囲のコメントを解除すると、次の出力が開始されます。
2013-01-29 // This is correct
2013-02-28 // This is the date which I want to ignore because its not on the 29th.
また、April
範囲のコメントを解除すると、何も出力されなくなります。である1つの日付を出力する必要があり2013-04-29
ます。したがって、問題は2月の計算にあると思います。
<?php
// Start Calendar Range
// JANUARY 2013 Range (Working)
$rangeStart = new DateTime( '2012-12-30' );
$rangeEnd = new DateTime( '2013-02-03' );
// FEBRUARY 2013 Range (Not Working)
//$rangeStart = new DateTime( '2013-01-27' );
//$rangeEnd = new DateTime( '2013-03-03' );
// APRIL 2013 Range (Not Working)
//$rangeStart = new DateTime( '2013-03-31' );
//$rangeEnd = new DateTime( '2013-04-05' );
// MAY 2013 Range (Working)
//$rangeStart = new DateTime( '2013-04-28' );
//$rangeEnd = new DateTime( '2013-06-02' );
// Event date start
$eventStart = new DateTime( '2012-10-29' );
$recurTimes = 1;
// Loop thru the days of month
while( $rangeStart->format('U') <= $rangeEnd->format('U') ) {
$currView = mktime( 0, 0, 0, $rangeStart->format('m'), $eventStart->format('d'), $rangeStart->format('Y') );
$interval = round(($currView-$eventStart->format('U')) / 60 / 60 / 24 / 30);
$monthsAway = $eventStart->format('m')+$interval;
$recurMonth = $eventStart->format('m')%$recurTimes;
if( $monthsAway%$recurTimes == $recurMonth ) {
$nextRecur = getNextRecur( $eventStart->format('U'), $interval );
echo date( 'Y-m-d', $nextRecur ) . '<br />';
}
$rangeStart->modify('+1 month');
}
// function to add 1 month with leap year in consideration
function getNextRecur( $baseTime=null, $months=1 ) {
if( is_null( $baseTime ) ) $baseTime = time( );
$xMonths = strtotime( '+' . $months . ' months', $baseTime );
$before = (int)date( 'm', $baseTime )+12*(int)date( 'Y', $baseTime );
$after = (int)date( 'm', $xMonths )+12*(int)date( 'Y', $xMonths );
if( $after > $months+$before ) {
$xMonths = strtotime( date('Ym01His', $xMonths) . ' -1 day' );
}
return $xMonths;
}
?>