我有以下内容循环浏览一年中的每个月。但是,它似乎跳过二月。
$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。
答案 0 :(得分:3)
为什么不使用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
答案 1 :(得分:0)
这是因为二月有28天而你的间隔是一个月(30天)。所以它从1月30日到3月2日跳过了30天。然后它移动到三月的最后一天。
更改
$start->modify('last day of this month');
到
$start->modify('first day of this month');
答案 2 :(得分:-1)
您的第一次约会是2015年1月31日。自2月份没有第31届以来,它将持续到3月3日。然后你告诉它到那个月末,这就是为什么你要在1月而不是2月之后到达3月底。