一年中的每个月我都要循环使用以下内容。然而,它似乎跳过了二月。
$start = new DateTime('2015-01-01');
$start->modify('last day of this month');
$current = new DateTime('now');
$end = new DateTime('2018-01-01');
$interval = DateInterval::createFromDateString('1 month');
$period = new DatePeriod($start, $interval, $end);
$timestamps = array();
foreach ($period as $dt) {
$dt->modify('last day of this month');
echo 'C:' . $current->format('d F Y') . '<br>';
echo 'S:' . $start->format('d F Y') . '<br>';
echo 'D:' . $dt->format('d F Y') . '<br>';
echo '<br><br>';
}
然而,上述输出:
C:17 March 2015
S:31 January 2015
D:31 January 2015
C: 17 March 2015
S:31 January 2015
D:31 March 2015
C: 17 March 2015
S:31 January 2015
D:30 April 2015
有人能认出我的错误吗?我期望第二个D
具有28 February 2015
的值。
我只想要一份已经过去的月份的清单。
更新
MLeFevre在评论中强调的问题是,使用日期间隔可能很棘手。参见Example #3 Beware when adding months
http://php.net/manual/en/datetime.add.php.
与其使用DatePeriod
,为什么不使用modify
方法呢
$current = new DateTime('now');
$end = new DateTime('2018-01-01');
while($current < $end) {
$current->modify('last day of next month');
echo 'C:' . $current->format('d F Y') . '<br>';
}
在你的问题中,你首先要加一个月,然后到那个月底。这是行不通的,因为每个月的时间长短各不相同。
样本输出:
C:30 April 2015
C:31 May 2015
C:30 June 2015
C:31 July 2015
C:31 August 2015
C:30 September 2015
C:31 October 2015
C:30 November 2015
C:31 December 2015
C:31 January 2016
C:29 February 2016
C:31 March 2016
// etc.
要从$start
循环到$current
,您可以稍微更改如下逻辑:
$start = new DateTime('2015-01-31'); // start from end of month
$current = new DateTime('now');
do {
echo 'C:' . $start->format('d F Y') . '<br>';
} while($start->modify('last day of next month') < $current);
输出:
C:31 January 2015
C:28 February 2015
发生这种情况是因为二月有28天,而您的间隔时间是1个月(30天)。因此,它从1月30日到3月2日跳过了30天。然后它移动到三月的最后一天。
更改
$start->modify('last day of this month');
至
$start->modify('first day of this month');
您的第一次约会是2015年1月31日。由于2月没有31日,所以它将持续到3月3日。然后你告诉它到那个月底,这就是为什么你在1月之后到3月底,而不是2月。