Php DateTime :: setDate()不在第一个DatePeriod迭代上工作

时间:2016-05-25 23:23:01

标签: php datetime

在某些报告中,我会在接下来的6个月内循环并找出开始/结束范围以进行计算。对于每个月的循环,setDate()在第一个月正常工作。

# Loop over the next 6 months (from start of this month)
$now = new DateTime("first day of this month", new DateTimeZone("Pacific/Auckland"));

$end = clone $now;
$end->modify("+6 month");

$int = new DateInterval("P1M");
$period = new DatePeriod($now, $int, $end);

# For each month, work out the start/end dates and times for the reports
foreach ($period as $month) {
    $start = clone $month;
    $start->setDate($start->format("Y"), $start->format("m"), 1);
    $start->setTime(0, 0, 0);

    $end = clone $month;
    $end->setDate($end->format("Y"), $end->format("m"), $end->format("t"));
    $end->setTime(23, 23, 59);

    # Dumping out data here shows weirdness below
}

无论如何,第一个月结束时都是第一个月。即使我手动将其设置为任何其他有效日整数。我把它剥离到了一个简单的例子,它还在做它。

string(19) "2016-05-01 00:00:00"
string(19) "2016-05-01 23:23:59" <- Huh? This should be 31
===========
string(19) "2016-06-01 00:00:00"
string(19) "2016-06-30 23:23:59"
===========
string(19) "2016-07-01 00:00:00"
string(19) "2016-07-31 23:23:59"
...etc...

我在php 5.5.26

1 个答案:

答案 0 :(得分:1)

  

使用某些relative formats创建DateTime对象时PHP中的错误。

     

PHP Bug #63863 DateTime:setDate() date not used after modify("last day of...")

     

这似乎只有在使用某些相对格式来创建DateTime对象时才会发生,例如'last day of next month''first day of this month',但是'last sat of July 2008' 不会导致错误。

感谢评论中的Mike

简单的解决方法,使用不同的方法创建初始$now DateTime对象。

https://eval.in/577984

# Loop over the next 6 months (from start of this month)
$now = new DateTime("now", new DateTimeZone("Pacific/Auckland"));
$now->setDate($now->format("Y"), $now->format("m"), 1);

$end = clone $now;
$end->modify("+6 month");

$int = new DateInterval("P1M");
$period = new DatePeriod($now, $int, $end);

# For each month, work out the start/end dates and times for the reports
foreach ($period as $month) {
    $start = clone $month;
    $start->setDate($start->format("Y"), $start->format("m"), 1);
    $start->setTime(0, 0, 0);

    $end = clone $month;
    $end->setDate($end->format("Y"), $end->format("m"), $end->format("t"));
    $end->setTime(23, 23, 59);

    echo $start->format('Y-m-d H:i:s') . "\n";
    echo $end->format('Y-m-d H:i:s') . "\n";
}