【发布时间】:2011-04-27 06:29:25
【问题描述】:
我正在尝试使用 preg_match 来验证时间输入是否采用这种格式 - “HH:MM”
【问题讨论】:
标签: php regex validation preg-match
我正在尝试使用 preg_match 来验证时间输入是否采用这种格式 - “HH:MM”
【问题讨论】:
标签: php regex validation preg-match
您可以使用正则表达式来检查。
12 小时:
preg_match("/^(?:1[012]|0[0-9]):[0-5][0-9]$/", $foo)
24 小时:
preg_match("/^(?:2[0-3]|[01][0-9]):[0-5][0-9]$/", $foo)
如果您使用从 01:00 到 24:59 的 24 小时制,请使用
preg_match("/^(?:2[0-4]|[01][1-9]|10):([0-5][0-9])$/", $foo)
【讨论】:
$dateObj = DateTime::createFromFormat('d.m.Y H:i', "10.10.2010 " .$timeStr); if ($dateObj !== false) { // valid time} else { //invalid time} 但是,是的,为重新发明轮子提供 +14 票
preg_match,尽管我不知道其背后的原因。我知道我以前问过问题,有人告诉我我不应该做我要求做的事情(而不是告诉我该怎么做),这让我很困扰——当然我有理由问为了我想要的。我不知道这张海报的理由是什么:也许他们正在使用 GeSHi 以他们的语言格式化日期,因此 DateTime::createFromFormat 不可用。或者也许他们只是在学习正则表达式。我不知道。
验证日期(和/或时间)而不抛出异常的简单函数。它将预期的date format 作为参数:
function isValidDate(string $date, string $format = 'Y-m-d'): bool
{
$dateObj = DateTime::createFromFormat($format, $date);
return $dateObj && $dateObj->format($format) == $date;
}
工作原理:它根据传递的$format将输入的日期转换为PHP的DateTime对象,然后将该对象与原始输入日期进行比较。
如果它们匹配,则日期有效并且具有预期的格式。
一些使用示例:
/* Valid Examples: */
isValidDate("2017-05-31");
isValidDate("23:15:00", 'H:i:s');
isValidDate("2017-05-31 11:15:00", 'Y-m-d h:i:s');
/* Invalid: */
isValidDate("2012-00-21");
isValidDate("25:15:00", 'H:i:s');
isValidDate("Any string that's not a valid date/time");
【讨论】:
if(DateTime::createFromFormat('H:i',$time)) 对很多情况都有好处。
createFromFormat 接受“愚蠢”的值,例如第 13 个月或第 0 天。日期2000-13-00 将被视为有效,因为它将其解析为 2000- 12-31.
假设您要检查的时间是$timeStr,并且根据日期规范必须是H:i 格式。
恕我直言,为此使用正则表达式是愚蠢的。这更容易阅读:
更新
$timeStr = " 02:00"; //example of valid time, note whitespace
test($timeStr);
$timeStr = "23:59"; //valid
test($timeStr);
$timeStr = "24:00"; //invalid
test($timeStr);
$timeStr = "25:00"; //invalid
test($timeStr);
$timeStr = "16:61"; // invalid
test($timeStr);
//tests 23:59 hour format
function test($timeStr){
$dateObj = DateTime::createFromFormat('d.m.Y H:i', "10.10.2010 " . $timeStr);
if ($dateObj !== false && $dateObj && $dateObj->format('G') ==
intval($timeStr)){
//return true;
echo 'valid <br/>';
}
else{
//return false;
echo 'invalid <br/>';
}
}
【讨论】:
这是一个检查字符串是否为 00:00 到 23:59 之间的一个小时的代码
$checked = false;
if (preg_match('/^\d{2}:\d{2}$/', $str)) {
if (preg_match("/(2[0-3]|[0][0-9]|1[0-9]):([0-5][0-9])/", $str)) {
$checked = true;
}
}
var_dump($checked );die;
【讨论】:
24:15 但不匹配 10:15
根据所需格式验证小时、分钟和秒的函数:
function validTime($time, $format='H:i:s') {
$d = DateTime::createFromFormat("Y-m-d $format", "2017-12-01 $time");
return $d && $d->format($format) == $time;
}
$valid = validTime("23","H");
$valid = validTime("23:59","H:i");
$valid = validTime("23:59:59","H:i:s");
$valid = validTime("23:59:59");
$valid = validTime("25","H");
$valid = validTime("01:60","H:i");
$valid = validTime("01:20:61","H:i:s");
$valid = validTime("01:20:61");
【讨论】:
你可以这样做:
if(preg_match('/^(?:[01][0-9]|2[0-3]):[0-5][0-9]$/',$input)) {
// $input is valid HH:MM format.
}
【讨论】:
对于可以进行上午和下午的 12 小时比赛,请使用此
/^(1[0-2]|0?[1-9]):[0-5][0-9] (AM|PM)$/i
它将处理 01:20 am 或 1:20 AM。 上面 12 小时的示例不正确,因为您可能会这样做:
00:20
这不是有效的 12 小时格式。
【讨论】:
扩展 @Toskan 所写的内容,您可以这样做以 00:00 格式进行验证。如果有效且介于 00:00 和 23:59 之间,则返回 true。
这也允许使用不同的时间格式...
function isTimeValid($time_str, $format = 'H:i')
{
$DateTime = \DateTime::createFromFormat( "d/m/Y {$format}", "10/10/2010 {$time_str}" );
return $DateTime && $DateTime->format( "d/m/Y {$format}" ) == "10/10/2010 {$time_str}";
}
【讨论】:
如果您不需要preg_match,这是另一种新颖的方法:
$thetime = "20:15" // set the time
$timecheck = explode(":", filter_var($thetime, FILTER_SANITIZE_URL));
$hourvalid = $minvalid = false;
if (count($timecheck) > 1 && count($timecheck) < 4) {
$hourvalid = ((abs(filter_var($timecheck[0], FILTER_SANITIZE_NUMBER_INT)) < 24)
&& (abs(filter_var($timecheck[0], FILTER_SANITIZE_NUMBER_INT)) === (INT) $timecheck[0]))
? true : false;
$minvalid = ((abs(filter_var($timecheck[1], FILTER_SANITIZE_NUMBER_INT)) < 60)
&& (abs(filter_var($timecheck[1], FILTER_SANITIZE_NUMBER_INT)) === (INT) $timecheck[1]))
? true : false;
}
if ($hourvalid && $minvalid) {//valid time
echo $thetime . " is a valid time<br />";
} else {//invalid time
echo $thetime . " is NOT a valid time<br />";
}
可能不是世界上最有效的方法,但它可以做到。仅对从 00:00 到 23:59 的时间有效。此外,8:0 验证为时间(假设您的意思是 08:00)。
【讨论】:
FILTER_SANITIZE_URL。
如果您只想验证 HH:MM 字符串,请更正 @Toskan 的答案
protected function isValidTime($timeStr){
$dateObj = DateTime::createFromFormat('d.m.Y H:i', "10.10.2010 " . $timeStr);
$dateObjOffset = DateTime::createFromFormat('d.m.Y H:i', "10.10.2010 " . '24:00');
if($dateObjOffset <= $dateObj){
return false;
}
if ($dateObj !== false) {
return true;
}
else{
return false;
}
}
【讨论】:
基于 Charles 用正则表达式的优雅回答。如果您需要对 "HH:MM" 和 "H:MM"(即 "9:45"/"09:45")进行单行验证,请使用以下正则表达式来匹配 24 小时格式:
preg_match("/^(?(?=\d{2})(?:2[0-3]|[01][0-9])|[0-9]):[0-5][0-9]$/", $time)
(?代表conditional subpattern,语法为:
(?(条件)是模式|无模式)
?= in 条件是regexp assertion
?: in yes-pattern 是可选 以获得更好的性能,您可以放弃它。这意味着我们不需要任何 capturing 括号内的 (),我们只需要替代功能。
所以,我们只描述以下内容:
$time 字符串以两位数字(?=\d{2}) 开头,则使用(2[0-3]|[01][0-9]) 模式来匹配HH 小时表示法("09:45" 大小写)[0-9] 模式来匹配 H 小时表示法("9:45" 大小写)正如他们所说,简单是天才的姐妹。我们不一定需要上述条件模式。 24 小时 格式的"HH:MM/H:MM" 更简单的验证:
preg_match("/^(?:2[0-3]|[01][0-9]|[0-9]):[0-5][0-9]$/", $time)
同样,分组括号中的?: () 是禁用捕获的可选选项,您可以删除它。
因此,在这个正则表达式中,() 的替代子模式试图在第一个 (20..23) 和第二个 (01..19) 模式中匹配两位数小时,然后在最后一个 (@987654346) 模式中匹配一位数@)。
另外,验证"HH:MM/H:MM"为12小时格式:
preg_match("/^(?:0?[1-9]|1[012]):[0-5][0-9]$/", $time);
在这里,我们尝试将第一个数字 (1..9) 与可能的前零 (0?) 进行匹配,然后再匹配两个数字 (10..12)。
【讨论】:
如果您正在寻找秒数(24 小时)。这对我来说就像一个魅力。
$time = "23:59:60";
preg_match("/^([0-1][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$/", $time)
【讨论】:
另一种不使用正则表达式的方法。
if(is_string($foo) && (strlen($foo) == 4 || strlen($foo) == 5) && intval(str_replace(':','',$foo)) > -1 && intval(str_replace(':','',$foo)) < 2360){
stuff to do if valid time
}
else{
stuff to do if invalid time
}
首先我检查数据类型是否为字符串。如果不是很明显,这不是一个有效时间。然后我检查字符串是否有 4 / 5 个字母的正确长度。 使用 str_replace,我删除了 ':',然后将结果转换为一个整数,我可以轻松地将其与所需的时间范围进行比较(在我的示例中为 00:00 - 23:59)。
【讨论】: