2016-12-06 2 views
1

Я хотел бы рассчитать следующую дату выставления счета плана Recurly на PHP. Существует два типа биллингового цикла: ежегодно | ежемесячно. Я пытался использовать классы 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' 

Добавление одного месяца до 31 Januray дает мне второй марта, а не 29-й (или 28-го) февраля, как я бы ожидать.

То же самое для 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' 

Если раз в год, я ожидаю, Feb 29, 2016 + 1 год => 28 февраля 2017

Спасибо.

+0

Покажите нам, что вы сделали до сих пор ... Нам будет легче ответить. –

+0

$ next_bill_date = new DateTime(); if ($ plan_interval_unit == 'year') { $ interval_spec = 'P'. $ Plan ['plan_interval_length']. 'Y'; } else if ($ plan_interval_unit == 'month') { $ interval_spec = 'P'. $ Plan ['plan_interval_length']. 'M'; } $ next_bill_date-> добавить (новый 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 с DateTime объекта в PHP для расчета следующей даты по отношению к текущей дате. Следующий код показывает, как вы это сделаете в своей конкретной ситуации.

$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', результат на самом деле' Wed, 02 Mar 2016 ... ', но ОП искал, чтобы он возвращался _« 29 (или 28) февраля ». – Henders

+0

Вам нужен месяц или месяц?! –

+0

Я ответил сам себе. Спасибо за вашу помощь! –

Смежные вопросы