为什么约会给我一个错误的约会?

时间:2015-01-19 12:29:09

标签: php date

我想根据时间戳和其他一些信息来计算日期。

我的功能如下:

function getLastDeliveryDate($timestamp,$endOfMonth=true,$extraMonth=0){

    $days               = 0;
    $extraDays          = 0;
    $endOfCurrentMonth  = 0;
    $tsDay              = 86400;

    if($endOfMonth){
        $endOfCurrentMonth = date("t", $timestamp) - date("d",$timestamp);
        //rest of days in current month. In this sample 16 days
    }

    for($i=0;$i<$extraMonth;$i++){
        $x = $i + 1; 
        $date = new DateTime(date("Y-m-d", $timestamp)); //create dateobject to add a month
        $date->modify("+{$x} month"); // add the month (next month)
        $extraDays += date("t", strtotime($date->format("Y-m-d")));
        // get the days of the selected month and add them to count
        // in this case its 31 + 30 + 31 = 92
    }

    $days = $endOfCurrentMonth + $extraDays;
    // count everything together 16 + 92 = 108 days

    return date("d.m.y", $timestamp + ($tsDay*$days));
    //returning date with 108 days added.
}

作为一个示例,我将函数称为:

// the timestamp is 2015-07-15
echo getLastDeliveryDate(1436911200, true, 3); 
// should return 2015-10-31

但这回归2015-10-30,我不知道为什么。但108天应该是2015-10-31。这里出了什么问题?

如果我打电话

echo getLastDeliveryDate(1436911200, true, 2);

正确并给我2015-09-30

实际上我总是想要这个月的最后一天。

修改

有线,如果我在这里测试一下:IDEONE一切正常。我的项目不是:(

2 个答案:

答案 0 :(得分:1)

您需要在循环之前创建日期时间对象:

$date = new DateTime(date("Y-m-d", $timestamp)); //create dateobject to add month
// simpler alternative: $date = new DateTime("@$timestamp");
for($i=0;$i<$extraMonth;$i++){
    $date->modify("+1 month"); // add the month (next month)
    // $extraDays += date("t", strtotime($date->format("Y-m-d")));
    // you can reduce this line to:
    $extraDays += $date->format("t");
}

// Result: 15-10-31

否则总会添加31,因为您使用时间戳的日期+ 1个月。

注意:

您可以将整个功能简化为:

function getLastDeliveryDate($timestamp,$endOfMonth=true,$extraMonth=0){
    $date = new DateTime("@$timestamp");
    $date->modify("+$extraMonth month");
    if ($endOfMonth)
        $date->modify("last day of this month");
    return $date->format("d.m.y");
}

答案 1 :(得分:1)

问题是夏令时。你在2015年10月25日失去了一个小时。因为你的时间戳正好是0:00:00你输了一个小时导致“30.10.2015 23:00:00”实际应该是0:00:00

function getLastDeliveryDate($timestamp,$endOfMonth=true,$extraMonth=0){

    $days = 0;
    $extraDays = 0;
    $endOfCurrentMonth = 0;
    $tag = 86400;
    if(date( 'H',$timestamp)==0){$timestamp+=3601;}
    if($endOfMonth){
    $endOfCurrentMonth = date("t", $timestamp) - date("d",$timestamp);
    }

    $date = new DateTime(date("Y-m-d", $timestamp));
    for($i=0;$i<$extraMonth;$i++){
        $date->modify("+1 month");
        $extraDays += $date->format("t");
    }

    $days = $endOfCurrentMonth + $extraDays;
    return date("d.m.y", $timestamp + ($tag*$days));

}

echo getLastDeliveryDate(1436911200, true, 3);

如果您的日期时间固定为0:00:00,则此代码通过添加一小时一秒来解决此问题。如果您不关心工作时间本身,那么此解决方案将解决您的问题并且在任何情况下都是可行的。如果你关心时间,你必须检查你是否在夏令时,并采取相应的行动。