获取给定DateTime的下一个,如果天不相同则跳过

时间:2019-02-27 01:32:24

标签: php date datetime time

我想从给定的日期和时间中获取下个月的日期和时间。这是我现在拥有的:

$dt = new DateTime('2019-01-31');

for ($i=0; $i < 10; $i++) {
    $dt->add(new DateInterval('P1M'));
    $final = $dt->format('Y-m-d');
    echo $final."\n";
}

// Output:
// 2019-03-03
// 2019-04-03
// 2019-05-03
// 2019-06-03
// 2019-07-03

问题是,它将日期从“ 31”更改为“ 02”,因为在二月份没有日期31。因此在没有30或31的月份中,我想跳过那些几个月,但日子不变。

因此,应该是预期的输出:

// 2019-03-31
// 2019-05-31
// 2019-07-31
// 2019-08-31
// 2019-10-31

我该怎么做?

2 个答案:

答案 0 :(得分:3)

这有点棘手,因为您的DateTime()对象不断变化。但基本上,您需要:

  1. 保持每月的日子
  2. 修改日期,使其到达本月的第一天,这样您就不会跳过任何月份
  3. 添加一个月
  4. 检查月份的长度,如果太短则跳过
  5. 设置日期格式并返回正确的日期。

<?php
$dt = new DateTime('2019-01-31');
$day = $dt->format('d');
for ($i=0; $i < 10; $i++) {
    $dt->modify('first day of this month')->add(new DateInterval('P1M'));
    if ($dt->format('t') < $day) {
        continue;
    }
    $final = $dt->format('Y-m-' . $day);
    echo $final."\n";
}

输出

2019-03-31
2019-05-31
2019-07-31
2019-08-31
2019-10-31

Demo

下面是显示10个结果的示例。有很多方法可以通过循环执行此操作。我选择了一个do / while循环,因为我认为它们使用得还不够。 :)

<?php

$dt = new DateTime('2019-01-31');
$day = $dt->format('d');
$i = 0;
do {
    $dt->modify('first day of this month')->add(new DateInterval('P1M'));
    if ($dt->format('t') < $day) {
        continue;
    }
    $final = $dt->format('Y-m-' . $day);
    echo $final."\n";
    $i++;
} while ($i < 10);

Demo

答案 1 :(得分:3)

可靠地执行此操作的一种方法是,将开始日期再增加几个月,而不是连续增加一个月。然后,您可以将新日期的日期与开始日期的日期进行比较,如果它们相同,则回显结果:

path('', include('personal.urls', namespace="personal")),  

输出:

$dt = new DateTime('2019-01-31');
$day = $dt->format('d');
for ($i=1; $i <= 10; $i++) {
    $next = clone $dt;
    $next->add(new DateInterval("P{$i}M"));
    if ($next->format('d') != $day) continue;
    echo $next->format('Y-m-d') ."\n";
}

Demo on 3v4l.org

更新

如果要从开始输出10个月(满足日条件),则可以使用此代码,该代码计算输出数量:

2019-03-31
2019-05-31 
2019-07-31 
2019-08-31 
2019-10-31

输出:

$dt = new DateTime('2019-01-31');
$day = $dt->format('d');
$months = 0;
for ($i=1; $months < 10; $i++) {
    $next = clone $dt;
    $next->add(new DateInterval("P{$i}M"));
    if ($next->format('d') != $day) continue;
    echo $next->format('Y-m-d') ."\n";
    $months++;
}

Demo on 3v4l.org