我正在尝试根据日历日期范围计算每月重复活动。但是当事件发生在当月29日时,我偶然发现了February (28 days)
计算的问题。希望有些专家可以给我一些指导,因为我试着在没有帮助的情况下四处寻找。
我已经包含以下代码,以便于直接作为脚本运行。 January
范围工作正常,这使我有2个日期属于范围:
// JANUARY 2013 Range (Working)
2012-12-29
2013-01-29
但如果您取消注释二月范围,则会开始输出:
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
范围,它就会开始输出任何内容。它应该输出一个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;
}
?>
答案 0 :(得分:0)
也许你的approch有一个原因,但在我看来,它有点围绕着房子。 我们都知道,所有的月份都是不变的,而二月是奇怪的。 所以我会嘲笑你从那个角度看它。
我没有看过如何“完全”我会这样做,但我会简化它只是在二月份工作。 也许你可以做一年检查,看看它是否是闰年。然后让您的代码执行您在插入Febuarys日期时所需的代码。
答案 1 :(得分:0)
你可以尝试
示例1
$rangeStart = new DateTime('2012-12-30');
$rangeEnd = new DateTime('2013-02-03');
$eventStart = new DateTime('2012-10-29');
var_dump(getRange($rangeStart, $rangeEnd, $eventStart));
输出
array
0 => string '2013-01-29' (length=10)
示例2
$rangeStart = new DateTime('2012-01-27');
$rangeEnd = new DateTime('2013-03-03');
$eventStart = new DateTime('2012-10-29');
var_dump(getRange($rangeStart, $rangeEnd, $eventStart));
输出
array
0 => string '2012-10-29' (length=10)
1 => string '2012-11-29' (length=10)
2 => string '2012-12-29' (length=10)
3 => string '2013-01-29' (length=10)
使用的功能
function getRange($rangeStart, $rangeEnd, $eventStart, $fixedDay = 29) {
$lastStart = clone $rangeStart;
$rangeStart->setDate($eventStart->format('Y'), $eventStart->format('m'), $eventStart->format('d'));
$list = array();
while ( $rangeStart <= $rangeEnd ) {
if ($rangeStart > $rangeEnd)
break;
if ($rangeStart->format('m') == 2 || $rangeStart < $lastStart) {
$rangeStart->modify('+1 month');
$rangeStart->setDate($rangeStart->format('Y'), $rangeStart->format('m'), $fixedDay);
continue;
}
$list[] = $rangeStart->format("Y-m-d");
$rangeStart->modify('+1 month');
$rangeStart->setDate($rangeStart->format('Y'), $rangeStart->format('m'), $fixedDay);
}
return $list;
}