如何获得下个月的同一天?

时间:2014-03-10 12:55:23

标签: php date

定期付款(每月)我需要下一个月的相同日期, o.n.,每月1日或每月15日(每月)

但它也应保持31,30,28和29日期。

例如,2014年1月31日(第一个定期付款日期),2014年2月28日或2014年2月29日(第2个日期),2014年3月31日(第3个)......等等)

例如.1 / 15/2014,2/15 / 2014,3 / 15 / 2014,4 / 15 / 2014,5 / 15/2014 ..等等

2 个答案:

答案 0 :(得分:5)

编辑答案:

您可以使用DatePeriod类:

这部分有效:

d >= 29时出现问题,然后FEBRUARY之后的所有月份都会将付款注册到最后一天。

<?php
error_reporting(E_ALL);
$begin = new DateTime('2014-01-29');
$lastDayInterval = DateInterval::createFromDateString('last day of next month');
$monthInterval = new DateInterval('P1M');
$lastDays = new DatePeriod(clone $begin, $lastDayInterval, 12,
                            DatePeriod::EXCLUDE_START_DATE);
$addedMonthDays = new DatePeriod(clone $begin, $monthInterval, 12,
                            DatePeriod::EXCLUDE_START_DATE);

$lastDaysArray = array();
foreach ($lastDays as $lastDay) {
    $lastDaysArray[] = $lastDay;
}

$addedMonthDaysArray = array();
foreach ($addedMonthDays as $addedMonthDay) {
    $addedMonthDaysArray[] = $addedMonthDay;
}

for ($i = 0; $i < 12; $i++) {
    if ($addedMonthDaysArray[$i] > $lastDaysArray[$i]) {
        echo $lastDaysArray[$i]->format('Y-m-d') . PHP_EOL;
    } else {
        echo $addedMonthDaysArray[$i]->format('Y-m-d') . PHP_EOL;
    }
}

输出:

2014-02-28
2014-03-31
2014-04-30
2014-05-31
2014-06-30
2014-07-31
2014-08-31
2014-09-30
2014-10-31
2014-11-30
2014-12-31
2015-01-31

使用:

$begin = new DateTime('2014-01-28');

输出:

2014-02-28
2014-03-28
2014-04-28
2014-05-28
2014-06-28
2014-07-28
2014-08-28
2014-09-28
2014-10-28
2014-11-28
2014-12-28
2015-01-28

答案 1 :(得分:0)

这是一个古老的问题,但在问了相同的问题here之后,我刚刚使用Carbon提出了一个解决方案。

DatePeriod()不起作用的原因是,它总是依赖于循环中的前一个日期。这就是为什么您在2月29日停留在29/28,然后在整个循环的其余部分重复的原因。

这是我的解决方案:

$endDate = CarbonImmutable::parse('10 april 2020')->startOfDay();
$startDate = CarbonImmutable::parse('31 january 2020')->startOfDay();
$interval = CarbonInterval::create('P1M'); // this only works for round months, not composite intervals

$workingDate = $startDate->copy();

for ($i = 1; $workingDate <= $endDate; $i = $i + $interval->m) {
    echo = $workingDate->format('Y-m-d') . "\n";
    $workingDate = $startDate->addMonthsNoOverflow($i);
}

我与Carbon代码库的贡献者一起参与了一些代码关闭工作。如果他找到了更好的解决方案,那么我将更新我的答案。目前,这可行。