cos*_*ari 82 php regex date-format
我正在尝试检查最终用户输入的日期是否在YYYY-MM-DD中.正则表达式从来都不是我的强项,我不断为我设置的preg_match()获得错误的返回值.
所以我假设我弄乱了正则表达式,详情如下.
$date="2012-09-12";
if (preg_match("^[0-9]{4}-[0-1][0-9]-[0-3][0-9]$",$date))
{
return true;
}else{
return false;
}
Run Code Online (Sandbox Code Playgroud)
有什么想法吗?
Avi*_*ese 177
试试这个.
$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;
}
Run Code Online (Sandbox Code Playgroud)
Jon*_*Jon 88
为此使用另一种机制可能更好.
现代解决方案,包括DateTime:
$dt = DateTime::createFromFormat("Y-m-d", $date);
return $dt !== false && !array_sum($dt::getLastErrors());
Run Code Online (Sandbox Code Playgroud)
这也验证了输入:$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);
Run Code Online (Sandbox Code Playgroud)
这验证输入也是有效日期.当然,你可以用正则表达式做到这一点,但它会更加大惊小怪 - 2月29日根本无法使用正则表达式进行验证.
这种方法的缺点是你必须非常小心地拒绝所有可能的"坏"输入而不在任何情况下发出通知.这是如何做:
explode仅限返回3个令牌(如果输入为"1-2-3-4",$d则变为"3-4")ctype_digit 用于确保输入不包含任何非数字字符(除了破折号)array_pad使用(具有将导致checkdate失败的默认值)以确保返回足够的元素,以便如果输入为"1-2" list()将不会发出通知小智 39
yyyy-mm-dd:
/^((((19|[2-9]\d)\d{2})\-(0[13578]|1[02])\-(0[1-9]|[12]\d|3[01]))|(((19|[2-9]\d)\d{2})\-(0[13456789]|1[012])\-(0[1-9]|[12]\d|30))|(((19|[2-9]\d)\d{2})\-02\-(0[1-9]|1\d|2[0-8]))|(((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))\-02\-29))$/g
yyyy/mm/dd:
/^((((19|[2-9]\d)\d{2})\/(0[13578]|1[02])\/(0[1-9]|[12]\d|3[01]))|(((19|[2-9]\d)\d{2})\/(0[13456789]|1[012])\/(0[1-9]|[12]\d|30))|(((19|[2-9]\d)\d{2})\/02\/(0[1-9]|1\d|2[0-8]))|(((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))\/02\/29))$/g
mm-dd-yyyy:
/^(((0[13578]|1[02])\-(0[1-9]|[12]\d|3[01])\-((19|[2-9]\d)\d{2}))|((0[13456789]|1[012])\-(0[1-9]|[12]\d|30)\-((19|[2-9]\d)\d{2}))|(02\-(0[1-9]|1\d|2[0-8])\-((19|[2-9]\d)\d{2}))|(02\-29\-((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))))$/g
mm/dd/yyyy:
/^(((0[13578]|1[02])\/(0[1-9]|[12]\d|3[01])\/((19|[2-9]\d)\d{2}))|((0[13456789]|1[012])\/(0[1-9]|[12]\d|30)\/((19|[2-9]\d)\d{2}))|(02\/(0[1-9]|1\d|2[0-8])\/((19|[2-9]\d)\d{2}))|(02\/29\/((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
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
Gra*_*ham 35
标准:
每年可被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
Run Code Online (Sandbox Code Playgroud)
2月在闰年有29天,在闰年有28天
四月,六月,九月和十一月30天
1月,3月,5月,7月,8月,10月和12月31天
测试:
以下日期应全部通过验证:
1976-02-29
2000-02-29
2004-02-29
1999-01-31
Run Code Online (Sandbox Code Playgroud)
以下日期都应验证失败:
2015-02-29
2015-04-31
1900-02-29
1999-01-32
2015-02-00
Run Code Online (Sandbox Code Playgroud)
范围:
我们将测试从1000年1月1日到2999年12月31日的日期.从 技术上讲,目前使用的公历仅在1753年用于大英帝国,在17世纪的欧洲各国的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
Run Code Online (Sandbox Code Playgroud)
可被4整除的年份:
[12]\d([02468][048]|[13579][26])
Run Code Online (Sandbox Code Playgroud)
可被100整除的年份:
[12]\d00
Run Code Online (Sandbox Code Playgroud)
不能被100整除:
[12]\d([1-9]\d|\d[1-9])
Run Code Online (Sandbox Code Playgroud)
这些年可被100整除但不会被400整除:
((1[1345789])|(2[1235679]))00
Run Code Online (Sandbox Code Playgroud)
可被4除以100而不是100:
[12]\d([2468][048]|[13579][26]|0[48])
Run Code Online (Sandbox Code Playgroud)
闰年:
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])
Run Code Online (Sandbox Code Playgroud)
不能被4整除:
[12]\d([02468][1235679]|[13579][01345789])
Run Code Online (Sandbox Code Playgroud)
不是闰年:
Not divisible by 4 OR is divisible by 100 but not by 400
([12]\d([02468][1235679]|[13579][01345789]))|(((1[1345789])|(2[1235679]))00)
Run Code Online (Sandbox Code Playgroud)
有效的月份和日期(二月除外)(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))
Run Code Online (Sandbox Code Playgroud)
二月28天:
02-(0[1-9]|1\d|2[0-8])
Run Code Online (Sandbox Code Playgroud)
2月29日:
02-(0[1-9]|[12]\d)
Run Code Online (Sandbox Code Playgroud)
有效日期:
(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]))))
Run Code Online (Sandbox Code Playgroud)
因此,您可以在YYYY-MM-DD格式的1000年1月1日到2999年12月31日之间使用它.
我怀疑它可以缩短很多,但我会把它留给其他人.
这将匹配所有有效日期.如果你希望它只在一个日期只包含一个日期时才有效,那么^( )$就像这样包装它:
^(((((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])))))$
Run Code Online (Sandbox Code Playgroud)
如果你想要一个可选的日期条目(即它可以是空白或有效日期),那么^$|在开头添加,如下所示:
^$|^(((((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])))))$
Run Code Online (Sandbox Code Playgroud)
k10*_*102 16
你可以这样做:
if (preg_match("/\d{4}\-\d{2}-\d{2}/", $date)) {
echo 'true';
} else {
echo 'false';
}
Run Code Online (Sandbox Code Playgroud)
但你最好使用这个:
$date = DateTime::createFromFormat('Y-m-d', $date);
if ($date) {
echo $date -> format('Y-m-d');
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,你会得到一个比简单的字符串更容易使用的对象.
你可以使用preg_match和checkdate php函数
$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;
Run Code Online (Sandbox Code Playgroud)
小智 7
验证通用日期格式的函数:
function validateDate($date, $format = 'Y-m-d') {
$d = DateTime::createFromFormat($format, $date);
return $d && $d->format($format) == $date;
}
Run Code Online (Sandbox Code Playgroud)
执行示例:
var_dump(validateDate('2021-02-28')); // true
var_dump(validateDate('2021-02-29')); // false
Run Code Online (Sandbox Code Playgroud)
我知道这是一个老问题.但我认为我有一个很好的解决方案.
$date = "2016-02-21";
$format = "Y-m-d";
if(date($format, strtotime($date)) == date($date)) {
echo "true";
} else {
echo "false";
}
Run Code Online (Sandbox Code Playgroud)
你可以尝试一下.如果将日期更改为21.02.2016,则回显为假.如果你之后将格式更改为dmY,则回显为真.
使用这个简单的代码,你应该能够检查使用哪种日期格式而不用正则表达式进行检查.
也许有人会在每个案例中对其进行测试.但我认为我的想法通常是有效的.对我来说似乎合乎逻辑.
preg_match 需要一个 / 或另一个字符作为分隔符。
preg_match("/^[0-9]{4}-[0-1][0-9]-[0-3][0-9]$/",$date)
Run Code Online (Sandbox Code Playgroud)
你还应该检查那个日期的有效性,这样你就不会得到像 9999-19-38 这样的结果
bool checkdate ( int $month , int $day , int $year )
Run Code Online (Sandbox Code Playgroud)
可能对某人有用:
$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
Run Code Online (Sandbox Code Playgroud)