用于检查字符串是否为日期的函数


Function to check if a string is a date

我正在尝试编写一个函数来使用 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;
        }
    }
}

我使用此函数作为 PHP filter_var函数的参数。

  • 它检查yyyy-mm-dd hh:mm:ss格式的日期
  • 它拒绝与模式匹配但仍无效的日期(例如 4 月 31 日)

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;
}

一个简单的解决方案是:

echo is_numeric( strtotime( $string ) ) ? 'Yes' : 'No';

尽管这有一个公认的答案,但它并非在所有情况下都能有效工作。例如,我在使用日期"10/38/2013"的表单字段上测试日期验证,并返回了一个有效的DateObject,但该日期是PHP所说的"溢出",因此"10/38/2013"变为"11/07/2013"。有道理,但是我们应该只接受改革后的日期,还是强迫用户输入正确的日期?对于我们这些表单验证纳粹分子,我们可以使用此肮脏的修复程序:https://stackoverflow.com/a/10120725/486863 并在对象引发此警告时返回 false。

另一种解决方法是将字符串日期与格式化日期匹配,并将两者进行比较以获得相等的值。这似乎同样混乱。哦,好吧。这就是PHP开发的本质。

if (strtotime($date) > strtotime(0)) {
    echo 'it is a date'
}

我在这里找到了答案 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 */

如果你的心是使用 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 validateDate($date, $format = 'Y-m-d H:i:s') 
 {    
     $d = DateTime::createFromFormat($format, $date);    
     return $d && $d->format($format) == $date; 
 } 

函数是从这个答案或 php.net 复制的

这为我解决了问题,但也提出了我认为的其他各种问题。

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;
    }
}

strtotime ?列表?正则表达式?

PHP 的原生日期时间对象有什么问题?

http://www.php.net/manual/en/datetime.construct.php