我想检查最终用户输入的日期格式是否为YYYY-MM-DD。正则表达式从来不是我的强项,我设置的preg_match()一直返回false。
所以我认为我在正则表达式上搞砸了,详见下文。
$date="2012-09-12";
if (preg_match("^[0-9]{4}-[0-1][0-9]-[0-3][0-9]$",$date))
{
return true;
}else{
return false;
}
有什么想法吗?
我想检查最终用户输入的日期格式是否为YYYY-MM-DD。正则表达式从来不是我的强项,我设置的preg_match()一直返回false。
所以我认为我在正则表达式上搞砸了,详见下文。
$date="2012-09-12";
if (preg_match("^[0-9]{4}-[0-1][0-9]-[0-3][0-9]$",$date))
{
return true;
}else{
return false;
}
有什么想法吗?
试试这个。
$date="2012-09-12";
if (preg_match("/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/",$date)) {
return true;
} else {
return false;
}
return (bool)preg_match("/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/",$date);
,意思是验证$date是否符合YYYY-MM-DD日期格式的正则表达式,并返回布尔值。 - oxygen$date_pattern = '/^(19|20)\d{2}\-(0[1-9]|1[0-2])\-(0[1-9]|[12][0-9]|3[01])$/';
if (empty($date) || (!preg_match("$date_pattern", $date, $m) || (!checkdate($m[2], $m[3], $m[1])))) {
$echo '无效的开始日期,例如YYYY-MM-DD';
}
- webcoder.co.uk对于此事,使用另一种机制可能会更好。
使用DateTime
的现代解决方案:
$dt = DateTime::createFromFormat("Y-m-d", $date);
return $dt !== false && !array_sum($dt::getLastErrors());
这也验证了输入:$dt !== false
确保日期可以使用指定的格式解析,而 array_sum
技巧是一种简洁的方式,确保 PHP 没有进行“月份移位”(例如,将1月32日视为2月1日)。有关更多信息,请参阅 DateTime::getLastErrors()
。
list($y, $m, $d) = array_pad(explode('-', $date, 3), 3, 0);
return ctype_digit("$y$m$d") && checkdate($m, $d, $y);
这也会验证输入是否为有效日期。当然,您可以使用正则表达式来实现,但这可能会更麻烦--而且根本无法使用正则表达式验证2月29日。
这种方法的缺点是您必须非常小心地拒绝所有可能的“错误”输入,同时在任何情况下都不发出通知。如下:
explode
仅返回3个标记(因此如果输入为“1-2-3-4”,$d
将变为“3-4”)ctype_digit
用于确保输入不包含任何非数字字符(除了破折号)array_pad
被使用(使用一个默认值将导致 checkdate
失败),以确保返回足够的元素,因此如果输入为“1-2” ,list()
将不会发出通知DateTime
,从未听说过checkdate
...真丢人。 - k102DateTime
也可以实现这个功能。我刚刚完善了答案,如果您愿意可以再看一遍。 - JongetLastErrors
文档链接吗? - Jon$dt = DateTime::createFromFormat("Y-m-d", $date);
return $dt !== false && (false === $dt::getLastErrors() || !array_sum($dt::getLastErrors()));
- paaacman/^(0[1-9]|1[012])\-(0[1-9]|[12]\d|3[01])\-(19|[2-9]\d)\d{2}$/g
mm/dd/yyyy :
/^(0[1-9]|1[012])\/(0[1-9]|[12]\d|3[01])\/(19|[2-9]\d)\d{2}$/g
/^(((0[1-9]|[12]\d|3[01])\/(0[13578]|1[02])\/((19|[2-9]\d)\d{2}))|((30|[12]\d|0[1-9])\/(0[13456789]|1[012])\/((19|[2-9]\d)\d{2}))|(29\/02\/((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))))$/g
这些是日期格式的正则表达式,其中/g
表示全局匹配。第一个正则表达式是指匹配格式为 年-月-日 的日期,第二个和第三个正则表达式分别是指匹配格式为 月/日/年 和 日/月/年 的日期。请注意保留所有HTML标签。
PS:由于该内容并非IT技术内容,因此我需要推荐您联系中文机器翻译API或寻找专业人员进行翻译。
日期格式验证正则表达式:
/^(((0[1-9]|[12]\d|3[01])\/(0[13578]|1[02])\/((19|[2-9]\d)\d{2}))|((0[1-9]|[12]\d|30)\/(0[13456789]|1[012])\/((19|[2-9]\d)\d{2}))|((0[1-9]|1\d|2[0-8])\/02\/((19|[2-9]\d)\d{2}))|(29\/02\/((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))))$/g
对应的dd-mm-yyyy格式验证正则表达式:
/^(((0[1-9]|[12]\d|3[01])\-(0[13578]|1[02])\-((19|[2-9]\d)\d{2}))|((0[1-9]|[12]\d|30)\-(0[13456789]|1[012])\-((19|[2-9]\d)\d{2}))|((0[1-9]|1\d|2[0-8])\-02\-((19|[2-9]\d)\d{2}))|(29\-02\-((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))))$/g
标准:
每个能被4整除的年份都是闰年,但被100整除的年份除外,除非它能被400整除。因此:
2004 - leap year - divisible by 4
1900 - not a leap year - divisible by 4, but also divisible by 100
2000 - leap year - divisible by 4, also divisible by 100, but divisible by 400
闰年二月有29天,非闰年为28天
四月、六月、九月和十一月每月30天
一月、三月、五月、七月、八月、十月和十二月每月31天
测试:
以下日期都应通过验证:
1976-02-29
2000-02-29
2004-02-29
1999-01-31
以下日期都应该无法通过验证:2015-02-29
2015-04-31
1900-02-29
1999-01-32
2015-02-00
范围:
我们将测试从公元1000年1月1日到2999年12月31日的日期。技术上,目前使用的公历仅在1753年开始用于英国帝国,在17世纪的不同年份用于欧洲国家,但我不会担心这个。
用于测试闰年的正则表达式:
能被400整除的年份:
1200|1600|2000|2400|2800
can be shortened to:
(1[26]|2[048])00
if you wanted all years from 1AD to 9999 then this would do it:
(0[48]|[13579][26]|[2468][048])00
if you're happy with accepting 0000 as a valid year then it can be shortened:
([13579][26]|[02468][048])00
可以被4整除的年份:
[12]\d([02468][048]|[13579][26])
可被100整除的年份:
[12]\d00
不能被100整除:
[12]\d([1-9]\d|\d[1-9])
能被100整除但不能被400整除的年份:
((1[1345789])|(2[1235679]))00
能被4整除但不能被100整除:
[12]\d([2468][048]|[13579][26]|0[48])
闰年:
divisible by 400 or (divisible by 4 and not divisible by 100)
((1[26]|2[048])00)|[12]\d([2468][048]|[13579][26]|0[48])
不可以被4整除:
[12]\d([02468][1235679]|[13579][01345789])
非闰年:
Not divisible by 4 OR is divisible by 100 but not by 400
([12]\d([02468][1235679]|[13579][01345789]))|(((1[1345789])|(2[1235679]))00)
除了二月份以外的有效月份和日期(MM-DD):
((01|03|05|07|08|10|12)-(0[1-9]|[12]\d|3[01]))|((04|06|09|11)-(0[1-9]|[12]\d|30))
shortened to:
((0[13578]|1[02])-(0[1-9]|[12]\d|3[01]))|((0[469]|11)-(0[1-9]|[12]\d|30))
二月有28天:
02-(0[1-9]|1\d|2[0-8])
二月有29天:
02-(0[1-9]|[12]\d)
有效日期:
(leap year followed by (valid month-day-excluding-february OR 29-day-february))
OR
(non leap year followed by (valid month-day-excluding-february OR 28-day-february))
((((1[26]|2[048])00)|[12]\d([2468][048]|[13579][26]|0[48]))-((((0[13578]|1[02])-(0[1-9]|[12]\d|3[01]))|((0[469]|11)-(0[1-9]|[12]\d|30)))|(02-(0[1-9]|[12]\d))))|((([12]\d([02468][1235679]|[13579][01345789]))|((1[1345789]|2[1235679])00))-((((0[13578]|1[02])-(0[1-9]|[12]\d|3[01]))|((0[469]|11)-(0[1-9]|[12]\d|30)))|(02-(0[1-9]|1\d|2[0-8]))))
这里有一个针对日期在公元1000年1月1日至公元2999年12月31日之间,使用YYYY-MM-DD格式的正则表达式。
我猜它可以被缩短很多,但我会把它留给其他人来完成。
它将匹配所有有效的日期。如果你希望它只在包含一个日期且没有其他内容时才有效,则像这样将其包裹在^( )$
中:
^(((((1[26]|2[048])00)|[12]\d([2468][048]|[13579][26]|0[48]))-((((0[13578]|1[02])-(0[1-9]|[12]\d|3[01]))|((0[469]|11)-(0[1-9]|[12]\d|30)))|(02-(0[1-9]|[12]\d))))|((([12]\d([02468][1235679]|[13579][01345789]))|((1[1345789]|2[1235679])00))-((((0[13578]|1[02])-(0[1-9]|[12]\d|3[01]))|((0[469]|11)-(0[1-9]|[12]\d|30)))|(02-(0[1-9]|1\d|2[0-8])))))$
如果您希望它用于可选日期输入(即可以为空或为有效日期),则在开头添加^$|
,如下所示:^$|^(((((1[26]|2[048])00)|[12]\d([2468][048]|[13579][26]|0[48]))-((((0[13578]|1[02])-(0[1-9]|[12]\d|3[01]))|((0[469]|11)-(0[1-9]|[12]\d|30)))|(02-(0[1-9]|[12]\d))))|((([12]\d([02468][1235679]|[13579][01345789]))|((1[1345789]|2[1235679])00))-((((0[13578]|1[02])-(0[1-9]|[12]\d|3[01]))|((0[469]|11)-(0[1-9]|[12]\d|30)))|(02-(0[1-9]|1\d|2[0-8])))))$
你可以这样做:
if (preg_match("/\d{4}\-\d{2}-\d{2}/", $date)) {
echo 'true';
} else {
echo 'false';
}
但你最好使用这个:
$date = DateTime::createFromFormat('Y-m-d', $date);
if ($date) {
echo $date -> format('Y-m-d');
}
在这种情况下,您将获得一个对象,它比仅使用字符串要容易得多。
在这种情况下,您将获得一个对象,它比仅使用字符串要容易得多。
0175-44-19927
将会通过。 - Attila Naghi^
和 $
。 - Ismail我知道这是一个老问题。但我认为我有一个好的解决方案。
$date = "2016-02-21";
$format = "Y-m-d";
if(date($format, strtotime($date)) == date($date)) {
echo "true";
} else {
echo "false";
}
你可以试试。如果你将日期更改为2016年2月21日,那么echo就是false。而且如果你在此之后更改格式为d.m.Y,echo就会是true。$date = "2012-10-05";
$split = array();
if (preg_match ("/^([0-9]{4})-([0-9]{2})-([0-9]{2})$/", $date, $split))
{
return checkdate($split[2], $split[3], $split[1]);
}
return false;
验证通用日期格式的函数:
function validateDate($date, $format = 'Y-m-d') {
$d = DateTime::createFromFormat($format, $date);
return $d && $d->format($format) == $date;
}
执行示例:
var_dump(validateDate('2021-02-28')); // true
var_dump(validateDate('2021-02-29')); // false
对某些人可能有用:
$patterns = array(
'Y' =>'/^[0-9]{4}$/',
'Y-m' =>'/^[0-9]{4}(-|\/)([1-9]|0[1-9]|1[0-2])$/',
'Y-m-d' =>'/^[0-9]{4}(-|\/)([1-9]|0[1-9]|1[0-2])(-|\/)([1-9]|0[1-9]|[1-2][0-9]|3[0-1])$/',
'Y-m-d H' =>'/^[0-9]{4}(-|\/)([1-9]|0[1-9]|1[0-2])(-|\/)([1-9]|0[1-9]|[1-2][0-9]|3[0-1])\s(0|[0-1][0-9]|2[0-4])$/',
'Y-m-d H:i' =>'/^[0-9]{4}(-|\/)([1-9]|0[1-9]|1[0-2])(-|\/)([1-9]|0[1-9]|[1-2][0-9]|3[0-1])\s(0|[0-1][0-9]|2[0-4]):?(0|[0-5][0-9]|60)$/',
'Y-m-d H:i:s' =>'/^[0-9]{4}(-|\/)([1-9]|0[1-9]|1[0-2])(-|\/)([1-9]|0[1-9]|[1-2][0-9]|3[0-1])\s(0|[0-1][0-9]|2[0-4]):?((0|[0-5][0-9]):?(0|[0-5][0-9])|6000|60:00)$/',
);
echo preg_match($patterns['Y'], '1996'); // true
echo preg_match($patterns['Y'], '19966'); // false
echo preg_match($patterns['Y'], '199z'); // false
echo preg_match($patterns['Y-m'], '1996-0'); // false
echo preg_match($patterns['Y-m'], '1996-09'); // true
echo preg_match($patterns['Y-m'], '1996-1'); // true
echo preg_match($patterns['Y-m'], '1996/1'); // true
echo preg_match($patterns['Y-m'], '1996/12'); // true
echo preg_match($patterns['Y-m'], '1996/13'); // false
echo preg_match($patterns['Y-m-d'], '1996-11-1'); // true
echo preg_match($patterns['Y-m-d'], '1996-11-0'); // false
echo preg_match($patterns['Y-m-d'], '1996-11-32'); // false
echo preg_match($patterns['Y-m-d H'], '1996-11-31 0'); // true
echo preg_match($patterns['Y-m-d H'], '1996-11-31 00'); // true
echo preg_match($patterns['Y-m-d H'], '1996-11-31 24'); // true
echo preg_match($patterns['Y-m-d H'], '1996-11-31 25'); // false
echo preg_match($patterns['Y-m-d H:i'], '1996-11-31 2400'); // true
echo preg_match($patterns['Y-m-d H:i'], '1996-11-31 24:00'); // true
echo preg_match($patterns['Y-m-d H:i'], '1996-11-31 24:59'); // true
echo preg_match($patterns['Y-m-d H:i'], '1996-11-31 24:60'); // true
echo preg_match($patterns['Y-m-d H:i'], '1996-11-31 24:61'); // false
echo preg_match($patterns['Y-m-d H:i'], '1996-11-31 24:61'); // false
echo preg_match($patterns['Y-m-d H:i:s'], '1996-11-31 24:6000'); // true
echo preg_match($patterns['Y-m-d H:i:s'], '1996-11-31 24:60:00'); // true
echo preg_match($patterns['Y-m-d H:i:s'], '1996-11-31 24:59:59'); // true
echo preg_match($patterns['Y-m-d H:i:s'], '1996-11-31 24:59:60'); // false
echo preg_match($patterns['Y-m-d H:i:s'], '1996-11-31 24:60:01'); // false
preg_match需要一个/或其他字符作为分隔符。
preg_match("/^[0-9]{4}-[0-1][0-9]-[0-3][0-9]$/",$date)
你还应该检查日期的有效性,以免出现像9999-19-38这样的情况。
bool checkdate ( int $month , int $day , int $year )
date("Y-m-d", strtotime("2012-09-12"))=="2012-09-12";
或者 PHP 的checkdate ( int $month , int $day , int $year )
。 - oxygen