我需要在 php 中验证精确的日期格式。
在我的情况下,最佳日期格式应该是:例如1/1/2017
(没有前导零)并且代码应该允许我避免日期格式的其余部分。
以下代码是我写的,但没有结果:
if(preg_match("/([1-9]|[1-2][0-9]|3[0-1]-([1-9]|1[0-2])-^[0-9]{4})$/", $date){
// insert into etc. etc....
}else{
// update etc. etc....
}
问题是代码没有正确验证日期;它接受各种日期格式。
最佳答案
我注意到OP提交的答案不是万无一失的,所以我开始研究问题下评论中提到的一些功能和我自己的一些想法。
我同意 apokryfos 的观点 使用正则表达式验证日期表达式不是最佳实践 .一个纯粹的正则表达式解决方案将是一个越来越冗长和越来越难以理解的模式,因为它必须考虑过去和 future 的闰年。为此,我研究了 php 提供的一些日期函数。
format
参数遵守 DateTime::createFromFormat() 的语法/规则:看看如何
d
和 j
被分组在一起,就像 m
和 n
.因此,此函数将捕获无效日期,但不会捕获不需要的前导零。%e
提供没有前导零的匹配天数.此函数没有匹配非零前导月份数字的字符。此外,此功能可能会因操作系统而出现问题。 if(!DateTime::createFromFormat('j/n/Y', $date))
deceze 关于 a slightly different scenario 的建议在这种情况下将不起作用。 createFromFormat() 会不遗余力地构造一个有效的日期——甚至是像 99/99/9999
这样的字符串。会通过的。 为了创建最简洁的表达式,以下是我可以使用 DateTime 类提供的看似万无一失的解决方案:
if (($d=DateTime::createFromFormat('n/j/Y',$date)) && $date==$d->format('n/j/Y')){
// valid
}else{
// invalid
}
strtotime()
can be used with a single condition for this case because the OP's date format uses slashes as a delimiter and this function will correctly parse the date expression "American-style".This seems to be the simplest way to check for a valid date without leading zeros: Demo Link
if(date('n/j/Y',strtotime($date))==$date){ // valid }else{ // invalid }
如果您正在处理日期时间表达式并且不想检查时间部分,您可以在条件行之前调用此行:
$date = explode(' ', $date)[0]; // create an array of two elements: date and time, then only access date
Demo Link
或者
$date = strstr($date, ' ', true); // extract substring prior to first space
关于php - 如何在日期和月份不带前导零的情况下验证日期?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44549229/