date — Как рассчитать месяц или год спустя

Я хотел бы рассчитать следующую дату выставления счетов по плану Recurly в PHP.
Существует 2 типа цикла выставления счетов: годовой | ежемесячно.
Я пытался использовать классы DateTime и DateInterval, но не получил ожидаемых результатов.

<?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 января дает мне второе марта, а не 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'

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

Благодарю.

1

Решение

Попробуйте это, если date > 28 use last 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

2

Другие решения

Ты можешь позвонить 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;
}
1

Может быть что-то вроде этого:

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'));
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
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
По вопросам рекламы [email protected]