我正在尝试编写一个函数来确定字符串是否是使用 PHP 的日期/时间。基本上一个有效的日期/时间看起来像:
2012-06-14 01:46:28
显然,尽管它完全是动态的,任何值都可以改变,但它应该始终采用 的形式XXXX-XX-XX XX:XX:XX
,我如何编写正则表达式来检查这种模式并在匹配时返回 true。
我正在尝试编写一个函数来确定字符串是否是使用 PHP 的日期/时间。基本上一个有效的日期/时间看起来像:
2012-06-14 01:46:28
显然,尽管它完全是动态的,任何值都可以改变,但它应该始终采用 的形式XXXX-XX-XX XX:XX:XX
,我如何编写正则表达式来检查这种模式并在匹配时返回 true。
如果这是您的整个字符串,那么只需尝试解析它:
if (DateTime::createFromFormat('Y-m-d H:i:s', $myString) !== false) {
// it's a date
}
检查字符串是否为日期的最简单方法:
if(strtotime($date_string)){
// it's in date format
}
这是不使用正则表达式的另一种方法:
function check_your_datetime($x) {
return (date('Y-m-d H:i:s', strtotime($x)) == $x);
}
如果您不知道日期格式:
/**
* Check if the value is a valid date
*
* @param mixed $value
*
* @return boolean
*/
function isDate($value)
{
if (!$value) {
return false;
}
try {
new \DateTime($value);
return true;
} catch (\Exception $e) {
return false;
}
}
var_dump(isDate('2017-01-06')); // true
var_dump(isDate('2017-13-06')); // false
var_dump(isDate('2017-02-06T04:20:33')); // true
var_dump(isDate('2017/02/06')); // true
var_dump(isDate('3.6. 2017')); // true
var_dump(isDate(null)); // false
var_dump(isDate(true)); // false
var_dump(isDate(false)); // false
var_dump(isDate('')); // false
var_dump(isDate(45)); // false
在我的项目中,这似乎有效:
function isDate($value) {
if (!$value) {
return false;
} else {
$date = date_parse($value);
if($date['error_count'] == 0 && $date['warning_count'] == 0){
return checkdate($date['month'], $date['day'], $date['year']);
} else {
return false;
}
}
}
我将此函数用作 PHPfilter_var
函数的参数。
yyyy-mm-dd hh:mm:ss
格式的日期function filter_mydate($s) {
if (preg_match('@^(\d\d\d\d)-(\d\d)-(\d\d) (\d\d):(\d\d):(\d\d)$@', $s, $m) == false) {
return false;
}
if (checkdate($m[2], $m[3], $m[1]) == false || $m[4] >= 24 || $m[5] >= 60 || $m[6] >= 60) {
return false;
}
return $s;
}
尽管这有一个公认的答案,但它并不是在所有情况下都有效。例如,我在使用日期“10/38/2013”的表单字段上测试日期验证,我得到了一个有效的 DateObject 返回,但日期是 PHP 所说的“溢出”,所以“10/38/ 2013 年”变为“2013 年 7 月 11 日”。有道理,但我们应该只接受修改后的日期,还是强制用户输入正确的日期?对于我们这些表单验证纳粹分子,我们可以使用这个肮脏的修复:https ://stackoverflow.com/a/10120725/486863,当对象抛出此警告时返回 false。
另一种解决方法是将字符串日期与格式化的日期相匹配,并将两者进行比较以获得相等的值。这似乎同样混乱。那好吧。这就是 PHP 开发者的本质。
我在这里找到了答案https://stackoverflow.com/a/19271434/1363220,基本上
$d = DateTime::createFromFormat($format, $date);
// The Y ( 4 digits year ) returns TRUE for any integer with any number of digits so changing the comparison from == to === fixes the issue.
if($d && $d->format($format) === $date) {
//it's a proper date!
}
else {
//it's not a proper date
}
我不会为此使用正则表达式,而只是拆分字符串并检查日期是否有效:
list($year, $month, $day, $hour, $minute, $second) = preg_split('%( |-|:)%', $mydatestring);
if(!checkdate($month, $day, $year)) {
/* print error */
}
/* check $hour, $minute and $second etc */
if (strtotime($date)>strtotime(0)) { echo '这是一个日期' }
如果您决定使用 regEx,那么 txt2re.com 始终是一个很好的资源:
<?php
$txt='2012-06-14 01:46:28';
$re1='((?:2|1)\\d{3}(?:-|\\/)(?:(?:0[1-9])|(?:1[0-2]))(?:-|\\/)(?:(?:0[1-9])|(?:[1-2][0-9])|(?:3[0-1]))(?:T|\\s)(?:(?:[0-1][0-9])|(?:2[0-3])):(?:[0-5][0-9]):(?:[0-5][0-9]))'; # Time Stamp 1
if ($c=preg_match_all ("/".$re1."/is", $txt, $matches))
{
$timestamp1=$matches[1][0];
print "($timestamp1) \n";
}
?>
如果您有 PHP 5.2 Joey 的答案将不起作用。您需要扩展 PHP 的 DateTime 类:
class ExDateTime extends DateTime{
public static function createFromFormat($frmt,$time,$timezone=null){
$v = explode('.', phpversion());
if(!$timezone) $timezone = new DateTimeZone(date_default_timezone_get());
if(((int)$v[0]>=5&&(int)$v[1]>=2&&(int)$v[2]>17)){
return parent::createFromFormat($frmt,$time,$timezone);
}
return new DateTime(date($frmt, strtotime($time)), $timezone);
}
}
而且你可以毫无问题地使用这个类:
ExDateTime::createFromFormat('d.m.Y G:i',$timevar);
这解决了我,但也提出了我认为的其他各种问题。
function validateTimeString($datetime, $format = "Y-m-d H:i:s"){
return ($datetime == date($format, strtotime($datetime)));
}
当我使用非常规的 API 时,有时会得到一些混乱的返回,而不是明确定义的日期格式。所以我使用了一个相当不雅的课程,我欣然承认它在原则上是残酷和非传统的,但它有时对我有好处^^。
class DateHelper
{
private const DATE_FORMATS = [
DATE_ATOM,
DATE_COOKIE,
DATE_RFC822,
DATE_RFC850,
DATE_RSS,
DATE_W3C,
"Y-m-d\TH:i:s.u",
'Y-m-d\TH:i:s',
"Y-m-d'T'H:i:s.SSS'Z'",
"Y-m-d\TH:i:s.uP",
"Y-m-d\TH:i:sP",
"d/m/Y H:i:s",
];
/**
* @param string $inputStringDate
* @return DateTime|null
*/
public static function createDateFromUnknownFormat(string $inputStringDate): ?DateTime
{
$inputStringDate = str_replace('/', '-', $inputStringDate);
preg_match('/^(\d{4})\-(\d{2})-(\d{2})$/', $inputStringDate, $result);
if (!empty($result)) {
return DateTime::createFromFormat('Y-m-d', $inputStringDate);
}
preg_match('/^(\d{2})\-(\d{2})-(\d{4})$/', $inputStringDate, $result);
if (!empty($result)) {
return DateTime::createFromFormat('d-m-Y', $inputStringDate);
}
foreach (self::DATE_FORMATS as $dateFormat) {
if ($dateObject = DateTime::createFromFormat($dateFormat, $inputStringDate)) {
return $dateObject;
}
}
return null;
}
}
一个简单的解决方案是:
echo is_numeric( strtotime( $string ) ) ? 'Yes' : 'No';