我有一个接受用户提交的系统,收到提交后,系统将遍历所有时间段以找到合适的时间段。问题是,如果结束时间圈到第二天,它需要能够检查开始和结束时间。
举个例子:时间段从当天晚上 10:30 开始,到第二天下午 4:00 结束。如果当前时间介于晚上 10:30 和晚上 11:59:59 之间,则提交将分配到该时间段。但是,如果当前时间在上午 12:00 至下午 4:00 之间,则它将跳过该时间段。
这是我到目前为止所拥有的:
function check_time($from, $to, $time) {
$time = strtotime($time);
$from = strtotime($from);
$to_ = strtotime($to);
$to = $to_ <= $from ? strtotime($to . " tomorrow") : $to_;
return ($time >= $from && $time <= $to);
}
$timeslots = array(
array("16:00:00", "22:30:00"),
array("22:30:00", "16:00:00")
);
foreach ($timeslots as $slot) {
if (check_time($slot[0], $slot[1], date("H:i:s")))
{
echo "true'n";
}
else
{
echo "false'n";
}
}
如果当前时间为 23:00:00,则结果将是
false
true
但是,如果当前时间为 12:00:00,则结果将是
false
false
即使它在技术上介于两个时间之间。
我知道这与这样一个事实有关,如果这是新的一天,那么$from
strtotime
结果将在当天晚些时候。因此,它不是检查昨天晚上 10:30,而是检查今晚晚上 10:30。
我的问题是,如果需要的话,我似乎想不出一种方法来让$from
时间切换到前一天,类似于我强迫$to
时间切换到第二天。
这比您预期的要容易得多。假设您有三个时间,t1
、t2
和 tn
,分别表示从、到和用户时间。将这些时间视为六位数字(从 000000 到 235959(,并检查:
- 如果
t1
和t2
存在于午夜边界的同一侧- 检查
tn
是否介于t1
和t2
之间
- 检查
- 还
- 检查
tn
是否不在t2
和t1
之间
- 检查
代码和测试:
function check_time($t1, $t2, $tn) {
$t1 = +str_replace(":", "", $t1);
$t2 = +str_replace(":", "", $t2);
$tn = +str_replace(":", "", $tn);
if ($t2 >= $t1) {
return $t1 <= $tn && $tn < $t2;
} else {
return ! ($t2 <= $tn && $tn < $t1);
}
}
$tests = array(
array("16:00:00", "22:30:00", "15:00:00"),
array("16:00:00", "22:30:00", "16:00:00"),
array("16:00:00", "22:30:00", "22:29:59"),
array("16:00:00", "22:30:00", "22:30:00"),
array("16:00:00", "22:30:00", "23:59:59"),
array("22:30:00", "16:00:00", "22:29:59"),
array("22:30:00", "16:00:00", "22:30:00"),
array("22:30:00", "16:00:00", "15:59:59"),
array("22:30:00", "16:00:00", "16:00:00"),
array("22:30:00", "16:00:00", "17:00:00")
);
foreach($tests as $test) {
list($t1, $t2, $t0) = $test;
echo "$t1 - $t2 contains $t0: " . (check_time($t1, $t2, $t0) ? "yes" : "no") . "'n";
}
// OUTPUT
//
// 16:00:00 - 22:30:00 contains 15:00:00: no
// 16:00:00 - 22:30:00 contains 16:00:00: yes
// 16:00:00 - 22:30:00 contains 22:29:59: yes
// 16:00:00 - 22:30:00 contains 22:30:00: no
// 16:00:00 - 22:30:00 contains 23:59:59: no
// 22:30:00 - 16:00:00 contains 22:29:59: no
// 22:30:00 - 16:00:00 contains 22:30:00: yes
// 22:30:00 - 16:00:00 contains 15:59:59: yes
// 22:30:00 - 16:00:00 contains 16:00:00: no
// 22:30:00 - 16:00:00 contains 17:00:00: no
function check_time($time, $threshold){
$times = array(&$time, &$threshold);
foreach($times as &$ts){
if(!preg_match('~^([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$~', $ts)){
return false;
}
$ts = intval(preg_replace('~[^0-9]+~', null, $ts));
}
return ($time >= $threshold) ? 2 : 1;
}
var_dump(check_time(date("H:i:s"), '12:00:00'));
我作弊了!让我们遵循逻辑:
- 如果我们删除标点符号,任何时间都可以转换为整数。
- 我从要测试的
$time
中删除了标点符号,并将其设置为整数。 - 我对
$threshold
做了同样的事情,这是打破插槽空格的日期。 - 此函数仅检查
$time
整数是在$threshold
之前还是之后。 - 它不关心日期、明天、时间相对论等等。
如果失败(输入错误(,则returns false
.如果成功,则返回一个整数: - 1 如果在阈值之前 - 2 如果在阈值之后
希望它符合您的需求。