php - DateInterval 超过午夜问题
php - DateInterval over midnight issue
我想用 DateInterval
生成时间段,当我 select 结束时段超过午夜时遇到问题 (00:00)。
如果我的结束时间到“23:59”,一切都会生成。
这是我的带有输入变量的代码:
$duration = 30; // duration interval<br>
$start = '22:00'; // start period<br>
$end = '02:00'; // end period<br>
function generateTimeSlots($duration, $start, $end) {
$start = new DateTime($start);
$end = new DateTime($end);
$interval = new DateInterval("PT" . $duration . "M");
$periods = array();
for ($intStart = $start; $intStart < $end; $intStart->add($interval)) {
$endPeriod = clone $intStart;
$endPeriod->add($interval);
if ($endPeriod > $end) {
$endPeriod = $end;
}
$periods[] = $intStart->format('H:i A');
}
return $periods;
}
$duration = 30;
$start = '22:00'; // 10:00 PM
$end = '02:00'; // 02:00 AM
print_r( generateTimeSlots($duration, $start, $end) );
预期输出:
22:00下午
22:30下午
23:00下午
23:30下午
00:00下午
00:30下午
01:00 下午
01:30 下午
02:00下午
如果我的结束时间已经结束,则不会生成任何时间段 23:59
。
有人知道问题出在哪里吗?
保持简单并使用 strtotime() 函数。这样你只处理一个整数。然后在您的视图端,您可以将其转换回您需要的任何内容。
function generateTimeSlots($duration, $start, $end) {
$periods = array();
for ($intStart = $start; $intStart <= $end; $intStart += $duration) {
// $endPeriod = clone $intStart;
// $endPeriod = $end;
// if ($endPeriod > $end) {
// $endPeriod = $end;
// }
$periods[] = date('H:i A', $intStart);
}
return $periods;
}
$duration = 1800; #1800 seconds (30 minutes)
$start = strtotime('Today 22:00'); // 10:00 PM Today
$end = strtotime('Tomorrow 02:00'); // 02:00 AM Tomorrow
print_r( generateTimeSlots($duration, $start, $end) );
您还需要在 $start
和 $end
参数中包含有关日期的信息。如果未提及,DateTime
将自动 select 当前日期,在您的示例中这意味着您的开始日期是 2018-01-19 22:00:00
,结束日期是 2018-01-19 02:00:00
。由于您的结束日期是 在 之后,您的 for
循环根本就不会迭代。
要解决这个问题,您可以指定整个日期和时间,或者使用 PHP 的本机日期识别。我个人倾向于使用完整的日期,因为我发现它不必解释人类可读的字符串,从而使代码更加健壮。
// using complete dates
$startDateTime = new DateTime('2018-01-19 22:00:00');
$endDateTime = new DateTime('2018-01-20 02:00:00');
// using human readable strings
$startDateTime = new DateTime('today 22pm');
$endDateTime = new DateTime('tomorrow 2am');
我想用 DateInterval
生成时间段,当我 select 结束时段超过午夜时遇到问题 (00:00)。
如果我的结束时间到“23:59”,一切都会生成。
这是我的带有输入变量的代码:
$duration = 30; // duration interval<br>
$start = '22:00'; // start period<br>
$end = '02:00'; // end period<br>
function generateTimeSlots($duration, $start, $end) {
$start = new DateTime($start);
$end = new DateTime($end);
$interval = new DateInterval("PT" . $duration . "M");
$periods = array();
for ($intStart = $start; $intStart < $end; $intStart->add($interval)) {
$endPeriod = clone $intStart;
$endPeriod->add($interval);
if ($endPeriod > $end) {
$endPeriod = $end;
}
$periods[] = $intStart->format('H:i A');
}
return $periods;
}
$duration = 30;
$start = '22:00'; // 10:00 PM
$end = '02:00'; // 02:00 AM
print_r( generateTimeSlots($duration, $start, $end) );
预期输出:
22:00下午
22:30下午
23:00下午
23:30下午
00:00下午
00:30下午
01:00 下午
01:30 下午
02:00下午
如果我的结束时间已经结束,则不会生成任何时间段 23:59
。
有人知道问题出在哪里吗?
保持简单并使用 strtotime() 函数。这样你只处理一个整数。然后在您的视图端,您可以将其转换回您需要的任何内容。
function generateTimeSlots($duration, $start, $end) {
$periods = array();
for ($intStart = $start; $intStart <= $end; $intStart += $duration) {
// $endPeriod = clone $intStart;
// $endPeriod = $end;
// if ($endPeriod > $end) {
// $endPeriod = $end;
// }
$periods[] = date('H:i A', $intStart);
}
return $periods;
}
$duration = 1800; #1800 seconds (30 minutes)
$start = strtotime('Today 22:00'); // 10:00 PM Today
$end = strtotime('Tomorrow 02:00'); // 02:00 AM Tomorrow
print_r( generateTimeSlots($duration, $start, $end) );
您还需要在 $start
和 $end
参数中包含有关日期的信息。如果未提及,DateTime
将自动 select 当前日期,在您的示例中这意味着您的开始日期是 2018-01-19 22:00:00
,结束日期是 2018-01-19 02:00:00
。由于您的结束日期是 在 之后,您的 for
循环根本就不会迭代。
要解决这个问题,您可以指定整个日期和时间,或者使用 PHP 的本机日期识别。我个人倾向于使用完整的日期,因为我发现它不必解释人类可读的字符串,从而使代码更加健壮。
// using complete dates
$startDateTime = new DateTime('2018-01-19 22:00:00');
$endDateTime = new DateTime('2018-01-20 02:00:00');
// using human readable strings
$startDateTime = new DateTime('today 22pm');
$endDateTime = new DateTime('tomorrow 2am');