我有两个日期。假设它们看起来像这样。
$start = 2010/12/24;
$end = 2012/01/05;
我查询数据库以查找这两个日期之间的访问。我找到了一些。然后我填充一个名为stats的数组。
$stats['2010/12/25'] = 50;
$stats['2010/12/31'] = 25;
...
正如你所看到的,还有几天不见了我需要用零值填充缺失的日期我在想这样的事情。(我已经从开始日期和结束日期中提取了天/月/年。
for($y=$start_year; $y <= $end_year; $y++) {
for($m=$start_month; $m <=$end_month; $m++) {
for($d=$start_day; $d <= $end_day; $d++) {
这在一年中会很好,但几个月和几天都不起作用。如果开始日期是15号。随后每个月的第1-14天将被错过。我可以有这样的解决方案。。。
for($y=$start_year; $y <= $end_year; $y++) {
for($m=1; $m <13; $m++) {
$total_days = cal_days_in_month(CAL_GREGORIAN, $m, $y) + 1;
for($d=1; $d <= $total_days; $d++) {
然后我需要一堆if语句来确保开始和结束的月份和日期是有效的。
有更好的方法吗?或者这甚至可以在我的mysql查询中完成吗?
只是为了展示PHP的一些更新的间隔处理方法的威力(pgl在他的回答中提到):
$startDate = DateTime::createFromFormat("Y/m/d","2010/12/24",new DateTimeZone("Europe/London"));
$endDate = DateTime::createFromFormat("Y/m/d","2012/01/05",new DateTimeZone("Europe/London"));
$periodInterval = new DateInterval( "P1D" ); // 1-day, though can be more sophisticated rule
$period = new DatePeriod( $startDate, $periodInterval, $endDate );
foreach($period as $date){
echo $date->format("Y-m-d") , PHP_EOL;
}
是否需要PHP>=5.3.0
编辑
如果您需要包括实际的结束日期,那么您需要在foreach()循环之前向$endDate添加一天:
$endDate->add( $periodInterval );
编辑#2
$startDate = new DateTime("2010/12/24",new DateTimeZone("Europe/London"));
$endDate = new DateTime("2012/01/05",new DateTimeZone("Europe/London"));
do {
echo $startDate->format("Y-m-d") , PHP_EOL;
$startDate->modify("+1 day");
} while ($startDate <= $endDate);
对于PHP 5.2.0(或更早版本,如果启用了dateTime对象)
如果您使用的是PHP5.3,那么Mark Baker的答案就是您要使用的答案。如果(正如你在评论中所说)你仍在PHP5.2上,这样的东西应该会对你有所帮助:
$startdate = strtotime( '2010/12/24' );
$enddate = strtotime( '2012/01/05' );
$loopdate = $startdate;
$datesArray = array();
while( $loopdate <= $enddate ) {
$datesArray[$loopdate] = 0;
$loopdate = strtotime( '+1 day', $loopdate );
}
它将创建一个unix时间戳数组,其中包含起始日期和结束日期之间的每个日期作为索引,每个值都设置为零。然后,您可以用正确的值覆盖任何实际结果。
$start_date = DateTime::createFromFormat('Y/m/d', '2010/12/24');
$end_date = DateTime::createFromFormat('Y/m/d', '2012/01/05');
$current_date = $start_date;
while($current_date <= $end_date) {
$current_date = $current_date->add(new DateInterval('P1D'));
// do your array work here.
}
请参阅DateTime::add()以获取有关此操作的更多信息。
$i = 1;
while(date("Y/m/d", strtotime(date("Y/m/d", strtotime($start)) . "+ $i days")) < $end) {
... code here ...
$i++;
}
我会以天为单位计算开始日期和结束日期之间的差异,并在每次迭代中向时间戳中添加一天。
$start = strtotime("2010/12/24");
$end = strtotime("2012/01/05");
// start and end are seconds, so I convert it to days
$diff = ($end - $start) / 86400;
for ($i = 1; $i < $diff; $i++) {
// just multiply 86400 and add it to $start
// using strtotime('+1 day' ...) looks nice but is expensive.
// you could also have a cumulative value, but this was quicker
// to type
$date = $start + ($i * 86400);
echo date('r', $date);
}
我保存了这段可怕的代码:
while (($tmptime = strtotime('+' . (int) $d++ . ' days', strtotime($from))) && ($tmptime <= strtotime($to))) // this code makes baby jesus cry
$dates[strftime('%Y-%m-%d', $tmptime)] = 0;
(将$from
和$to
设置为适当的值。)这可能也会让你哭——但它有点管用。
当然,正确的方法是使用DateInterval
。