2016-12-06 83 views
1

我想用PHP计算Recurly计划的下一个开票日期。 有两种类型的结算周期:每年|每月。 我试图使用DateTime和DateInterval类,但没有得到预期的结果。PHP - 如何计算一个月或一年后

<?php 
$referenceTime = new \DateTime('2016-01-31'); 
$oneMonthLater = $referenceTime->modify('+1 month'); 
var_dump($oneMonthLater); 
// public 'date' => string '2016-03-02 00:00:00.000000' 

1个月添加到Januray月31日给我三月份的第二个而不是29日(或28日),因为我期望的那样。

同为8月31日:

<?php 
$referenceTime = new \DateTime('2016-08-31'); 
$oneMonthLater = $referenceTime->modify('+1 month'); 
var_dump($oneMonthLater); 
// public 'date' => string '2016-10-01 00:00:00.000000' 

如果每年,我预计2016年2月29日+1年=> 2017年2月28日

感谢。

+0

向我们展示您迄今为止所做的工作......我们会更轻松地回答。 –

+0

$ next_bill_date = new DateTime(); if($ plan_interval_unit =='year'){ $ interval_spec ='P'。$ plan ['plan_interval_length']。'Y'; ($ plan_interval_unit =='month'){ $ interval_spec ='P'。$ plan ['plan_interval_length']。'M'; } $ next_bill_date-> add(new DateInterval($ interval_spec)); –

+0

请将它添加到您的问题中。难以阅读/理解在这里... :( –

回答

0
function get_next_billing_date($now, $type, $format = 'Y-m-d') 
{ 
    $date = new DateTime($now); 

    $y = $date->format("Y"); 
    $m = $date->format("m"); 
    $d = $date->format("d"); 

    if ($type == 'year') { 
     $y++; 
     if ($m == 2 && $d == 29) { 
      $d = 28; 
     } 
    } else if ($type == 'month') { 
     if ($m == 12) { 
      $y++; 
      $m = 1; 
     } else { 
      $m++; 
     } 

     $first_date = sprintf("%04d-%02d-01", $y, $m); 
     $last_day_of_next_month = date('t', strtotime($first_date)); 

     if ($d > $last_day_of_next_month) { 
      $d = $last_day_of_next_month; 
     } 
    } else { 
     // not supported 
     return false; 
    } 

    $date->setDate($y, $m, $d); 

    return $date->format($format); 
} 
0

可能是类似的东西:

if (date('d') !== date('d', strtotime('+1 month')) 
    date ('Y-m-d H:i:s', strtotime('last day of next month')); 

if (date('d') !== date('d', strtotime('+1 year')) 
    date ('Y-m-d H:i:s', strtotime('last day of this month next year')); 
1

您可以致电modify PHP的DateTime对象来计算下一个相对于当前的日期。以下代码显示了您将如何处理您的具体情况。

$next_bill_date = new DateTime(); 
switch($plan_interval_unit) { 
    case "year": 
     $next_bill_date->modify("last day of next month"); 
     break; 

    case "month": 
     $next_bill_date->modify("last day of this month next year"); 
     break; 
} 
2

试试这个,如果date > 28uselast day of next month使用别的+1 month

$get_date = strtotime("31-01-2016"); 
$dt = explode("-",$get_date); 
$dt = $dt[0]; 
var_dump(($dt > 28) ? date("d-m-Y", strtotime("31-01-2016 last day of next month")) : date("d-m-Y", strtotime("31-01-2016 +1 month"))); 

DEMO

0

您可以使用PHP内置strtotime()功能

// One month from today 
$date = date('Y-m-d', strtotime('+1 month')); 

// One month from a specific date 
$date = date('Y-m-d', strtotime('+1 month', strtotime('2016-12-06'))); 
+0

这不能解决指定的问题,除非我失去了一些东西?如果我使用日期'2016-01-31'结果实际上'周三,2016年3月2日...'但是OP正在寻找它返回_“二月二十九日(或二十八日)”。 – Henders

+0

你需要过去一个月还是将来的一个月? –

+0

我回答了我自己,谢谢你的帮助! –