php preg_match: 检查生日格式 (dd/mm/yyyy)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3720977/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 10:51:36  来源:igfitidea点击:

preg_match: check birthday format (dd/mm/yyyy)

phpregexpreg-match

提问by laukok

How do I make the expression which checks the birthday input to match a format like this dd/mm/yyyy? Below is what I came out so far, but it takes this too if I put 99/99/9999!

我如何制作检查生日输入的表达式以匹配这样的 dd/mm/yyyy 格式?以下是我到目前为止得出的结果,但如果我输入 99/99/9999 也需要这个!

if (!preg_match("/[0-9]{2}\/[0-9]{2}\/[0-9]{4}/", $cnt_birthday))
  {
   $error = true;
   echo '<error elementid="cnt_birthday" message="BIRTHDAY - Only this birthday format - dd/mm/yyyy - is accepted."/>';
  }

How can I make sure that its only 01 to 31 for dd and 01 to 12 for mm? but I am sure how to restrict yyyy... I think theoritical 9999 should be acceptable... let me know if you have a better idea!

我怎样才能确保它只有 dd 的 01 到 31 和 mm 的 01 到 12?但我确定如何限制 yyyy ……我认为理论上的 9999 应该是可以接受的……如果您有更好的主意,请告诉我!

thanks, Lau

谢谢,刘

回答by Tim Fountain

I would suggest using checkdate()for this instead:

我建议为此使用checkdate()

if (preg_match("/([0-9]{2})\/([0-9]{2})\/([0-9]{4})/", $cnt_birthday, $matches)) {
    if (!checkdate($matches[2], $matches[1], $matches[3])) {
        $error = true;
        echo '<error elementid="cnt_birthday" message="BIRTHDAY - Please enter a valid date in the format - dd/mm/yyyy"/>';
    }
} else {
    $error = true;
    echo '<error elementid="cnt_birthday" message="BIRTHDAY - Only this birthday format - dd/mm/yyyy - is accepted."/>';
}

So regexp validates the format, checkdate validates the actual date.

因此 regexp 验证格式, checkdate 验证实际日期。

回答by codaddict

Based on Tim's checkdatebased solution:

基于Timcheckdate基于解决方案:

The extraction of day, month and year can easily be done using explodeas:

可以使用以下方式轻松提取日、月和年explode

list($dd,$mm,$yyyy) = explode('/',$cnt_birthday);
if (!checkdate($mm,$dd,$yyyy)) {
        $error = true;
}

回答by artificialidiot

Consider using strtotime()and reformat it with date(). It will provide more flexibility for users while entering a date and let's you use whatever formats you need in different places.

考虑使用strtotime()并重新格式化它date()。它将在输入日期时为用户提供更大的灵活性,让您可以在不同的地方使用您需要的任何格式。

Personally, I am pretty lazy when it comes to accurate date calculation and abuse it like strtotime("-10 day",$timestamp). This has the benefit of lower possibility of getting sued by an annoyed parent becuse you calculated their little daughters age to be just above 18, not accounting for leap years correctly, and let her to your adult themed site, however ridiculous it may sound.

就我个人而言,在准确的日期计算方面我很懒惰,并且像strtotime("-10 day",$timestamp). 这样做的好处是降低被恼怒的父母起诉的可能性,因为您计算出他们的小女儿的年龄刚好超过 18 岁,没有正确考虑闰年,并让她访问您的成人主题网站,无论这听起来多么荒谬。

回答by Yehia

if(preg_match("/(\d{2})\/(\d{2})\/(\d{4})$/", $date,$matches)){         
return (checkdate((int) $matches[2],(int)$matches[1],(int) $matches[3]) );
}else{
return false ;
}
  • preg_match to validate pattern dd/mm/yyyy
  • checkdate to validate date values
  • preg_match 验证模式 dd/mm/yyyy
  • checkdate 验证日期值

回答by Wrikken

$ok  = DateTime::createFromFormat('d/m/Y',$datestring)->format('d/m/Y') == $datestring;

PHP >= 5.3

PHP >= 5.3

回答by Sujay sreedhar

maybe something like this would help

也许这样的事情会有所帮助

 list($month,$day,$year)=explode("/",$date);
if(checkdate($month,$day,$year))
{
echo "good";
}
else{echo "bad";}

回答by Chadwick

To be really anal-retentive it might be easier to use your current regex, parse the numbers, then verify they're in range with checkdate(), but for kicks, here's the regex that ensures dates = 01-31 (and 1-9), and month = 01-12 (and 1-9).

为了真正保持肛门,使用您当前的正则表达式可能更容易,解析数字,然后使用checkdate()验证它们是否在范围内,但对于踢球,这是确保日期 = 01-31(和 1- 9),并且月 = 01-12 (和 1-9)

preg_match("/([012]?[1-9]|[12]0|3[01])\/(0?[1-9]|1[012])\/([0-9]{4})/", $date_string)

Couple things of note

一些注意事项

  • I've used grouping on all, required for the ORing (|) within, but also useful to extract those values if you want to do specific things with them
  • 0000 doesn't make much sense as a date, but I've left the explosion of that regex as an excersise to the reader. If you really want this to verify birthdates (and you're expecting currently or relatively recently deceased people) restrict that to say 1900+ or 1800+, or whatever is an acceptable range for you. If you might be parsing historical figures' birthdays... your call.
  • This still doesn't check that the date range is correct for the month in question!so for that use checkdate()
  • 我已经对所有内容使用了分组,这是其中的 ORing ( |) 所必需的,但如果您想用它们做特定的事情,也可以用于提取这些值
  • 0000 作为日期没有多大意义,但我已经把那个正则表达式的爆炸式作为练习留给了读者。如果您真的希望用它来验证出生日期(并且您期待当前或相对最近的死者),请将其限制为 1900+ 或 1800+,或者您可以接受的任何范围。如果您可能正在解析历史人物的生日……您的电话。
  • 这仍然不会检查日期范围对于相关月份是否正确!所以为此使用checkdate()

回答by catgofire

Only accepting a strictly formatted string is probably a bad practice. Assuming you're getting input from a webpage, it would be better to have separate fields for month, day, and year. They could just be text boxes, but it might be preferable to have drop-down menus, which would solve your limits problem (i.e. the only choices for month are 1,2,...,12). Requiring that users enter 01/01/2001 and not accepting 1/1/2001 is lazy programming. And only accepting "/" as a separator is awkward.

只接受严格格式化的字符串可能是一种不好的做法。假设您从网页获取输入,最好为月、日和年设置单独的字段。它们可能只是文本框,但最好有下拉菜单,这可以解决您的限制问题(即月份的唯一选择是 1,2,...,12)。要求用户输入 01/01/2001 而不接受 1/1/2001 是惰性编程。并且只接受“/”作为分隔符很尴尬。

But, to touch on your original question even if you decide to stick with formatted strings — since it's a birthdate field, you should probably restrict the yyyy to:

但是,即使您决定坚持使用格式化字符串,也要触及您的原始问题 - 由于它是生日字段,您可能应该将 yyyy 限制为:

if($yyyy > date('Y')) {
  echo '<error elementid="cnt_birthday" message="BIRTHDAY - Year must be less than or equal to the current year."/>';
}

Otherwise people could have negative ages :)

否则人们可能会有负年龄:)

回答by NL3294

Probably not the best solution, but here's my try.

可能不是最好的解决方案,但这是我的尝试。

You convert it to a time, and then reformat it back to the m/d/Y. If the string is unchanged, then, it was in the correct format to begin with.

您将其转换为时间,然后将其重新格式化为 m/d/Y。如果字符串未更改,则它的开头格式正确。

$transformedDate = date("m/d/Y", strtotime($myDate));

if($transformedDate == $myDate){        
    return true;    
} else{         
    return false;           
}

回答by dialyy

Try this regex : ([0-9]{2}\/[0-9]{2}\/[0-9]{4})

试试这个正则表达式: ([0-9]{2}\/[0-9]{2}\/[0-9]{4})