意外的DateTime DateInterval DatePeriod结果

时间:2014-10-30 11:42:14

标签: php date datetime

虽然使用DateTime DateInterval和DatePeriod来计算两个日期之间的间隔,但在使用P1W(周)和P1M(月)时我遇到了一些意想不到的结果。

如果我们在9月30日到10月29日之间获得月份,则仅输出“9月”。将结束日期更改为10月30日输出'Sep'和'Oct'。我的第一个想法可能是它需要成为本月的最后一天,但当然,10月有31天......

$dateStart  = '2014-09-30 00:00:00';
$dateEnd    = '2014-10-29 23:59:59'; // Sep
// $dateEnd = '2014-10-30 23:59:59'; // Sep, Oct
// $dateEnd = '2014-10-31 23:59:59'; // Sep, Oct
$dateInt    = 'M';

$start      = new DateTime($dateStart);
$end        = new DateTime($dateEnd);
$interval   = new DateInterval('P1'.$dateInt);
$period     = new DatePeriod($start, $interval, $end);

foreach ($period as $day) {
    var_dump($day->format($dateInt));
}

尝试获取两个日期之间的周数时会发生同样的事情。将结束日期设置为10月27日星期一,不包括结果中的那一周(44)。然而,将结束时间改为10月28日星期二,确实包括第44周。

$dateStart  = '2014-09-30 00:00:00';
$dateEnd    = '2014-10-27 23:59:59'; // Monday - 40, 41, 42, 43
// $dateEnd = '2014-10-28 23:59:59'; // Tuesday - 40, 41, 42, 43, 44
// $dateEnd = '2014-10-29 23:59:59'; // Wednesday - 40, 41, 42, 43, 44
$dateInt    = 'W';

$start      = new DateTime($dateStart);
$end        = new DateTime($dateEnd);
$interval   = new DateInterval('P1'.$dateInt);
$period     = new DatePeriod($start, $interval, $end);

foreach ($period as $day) {
    var_dump($day->format($dateInt));
}

有谁知道这是否是一个已知错误?如果是这样/如果没有,有没有人知道最好的解决方法/修复?

2 个答案:

答案 0 :(得分:3)

文档在comments中说明:

  

不包括endDate日期时间

所以2014-09-30 00:00:00 - 2014-10-30 00:00:00包含1个月

但2014-09-30 00:00:00 - 2014-10-30 00:00:01包含2个月

此外,文档声明您甚至可以通过在构造函数方法调用中使用标志来排除startDate。

答案 1 :(得分:2)

好的,正如评论中指出的那样,问题是我的开始/结束日期不会超过我正在检查的间隔(即一周或一个月)。愚蠢的球可以制作!

因此,解决方法是将结束日期设置为一周的最后一天(一周)或一个月的最后一天(一个月)。为了确保开始日期不会发生同样的问题,我们还可以确保开始日期是本周的星期一或本月的第一天。

月份示例和带有修复的结果;

$dateStart  = '2014-09-30 00:00:00';
$dateEnd    = '2014-10-29 23:59:59'; // Sep, Oct
// $dateEnd = '2014-10-30 23:59:59'; // Sep, Oct
// $dateEnd = '2014-10-31 23:59:59'; // Sep, Oct
$dateInt    = 'M';

$start      = new DateTime($dateStart);
$end        = new DateTime($dateEnd);

if($dateInt == 'W') {
    $start  = $start->modify('Monday this week');
    $end    = $end->modify('this Sunday');
} else if($dateInt == 'M') {
    $start  = $start->modify('first day of this month');
    $end    = $end->modify('last day of this month');
}

$interval   = new DateInterval('P1'.$dateInt);
$period     = new DatePeriod($start, $interval, $end);

foreach ($period as $day) {
    var_dump($day->format($dateInt));
}

周示例和带有修复的结果;

$dateStart  = '2014-09-30 00:00:00';
$dateEnd    = '2014-10-27 23:59:59'; // Monday - 40, 41, 42, 43, 44
// $dateEnd = '2014-10-28 23:59:59'; // Tuesday - 40, 41, 42, 43, 44
// $dateEnd = '2014-10-29 23:59:59'; // Wednesday - 40, 41, 42, 43, 44
$dateInt    = 'W';

$start      = new DateTime($dateStart);
$end        = new DateTime($dateEnd);

if($dateInt == 'W') {
    $start  = $start->modify('Monday this week');
    $end    = $end->modify('this Sunday');
} else if($dateInt == 'M') {
    $start  = $start->modify('first day of this month');
    $end    = $end->modify('last day of this month');
}

$interval   = new DateInterval('P1'.$dateInt);
$period     = new DatePeriod($start, $interval, $end);

foreach ($period as $day) {
    var_dump($day->format($dateInt));
}

这个似乎是问题的解决方法。

它也可能与此错误有关 - https://bugs.php.net/bug.php?id=52480