检查字符串是不是为日期的函数

Posted

技术标签:

【中文标题】检查字符串是不是为日期的函数【英文标题】:Function to check if a string is a date检查字符串是否为日期的函数 【发布时间】:2012-06-17 06:57:10 【问题描述】:

我正在尝试使用 php 编写一个函数来确定字符串是否为日期/时间。基本上一个有效的日期/时间看起来像:

 2012-06-14 01:46:28

显然,尽管它完全动态的任何值都可以更改,但它应该始终采用XXXX-XX-XX XX:XX:XX 的形式,我如何编写正则表达式来检查此模式并在匹配时返回 true。

【问题讨论】:

可能重复:***.com/questions/37732/… 【参考方案1】:

一个简单的解决方案是:

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

【讨论】:

【参考方案2】:

当我使用非常规的 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('/^(\d4)\-(\d2)-(\d2)$/', $inputStringDate, $result);
        if (!empty($result)) 
            return DateTime::createFromFormat('Y-m-d', $inputStringDate);
        
        preg_match('/^(\d2)\-(\d2)-(\d4)$/', $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;
    

【讨论】:

【参考方案3】:

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

function validateTimeString($datetime, $format = "Y-m-d H:i:s")
   return ($datetime == date($format, strtotime($datetime)));
 

【讨论】:

【参考方案4】:

如果这是你的整个字符串,那么尝试解析它:

if (DateTime::createFromFormat('Y-m-d H:i:s', $myString) !== false) 
  // it's a date

【讨论】:

这不是解决方案。我有DateTime::createFromFormat('m/d/Y', '10/38/2013'),它产生一个有效的 DateTime 对象而不是假的。日期转换为object(DateTime)#39 (3) ["date"]=> string(19) "2013-11-07 23:45:55" ["timezone_type"]=> int(3) ["timezone"]=> string(3) "UTC" 哎呀。我喜欢文档中从未指出这些事情的方式……您碰巧没有找到替代方法吗? (编辑:Date formats 文档表明您可以在几个月和几天内上溢/下溢,但没有提示您想要这种行为时该怎么做。 好吧,在 PHP 中没有解决方案或设置来覆盖它。我在答案***.com/a/19666600/486863 中注意到了一种解决方法 这个解决方案确实不适用于 cj5 指定的日期。这可能非常令人沮丧。我也使用了这个解决方案***.com/questions/10120643/… 这是我的格式Tue Oct 30 05:51:41 GMT+05:30 2018怎么查啊,有没有常用的方法?【参考方案5】:

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

【讨论】:

【参考方案6】:

检查字符串是否为日期的最简单方法:

if(strtotime($date_string))
    // it's in date format

【讨论】:

我不明白为什么这不是公认的答案。这是 PHP 手册,特别说明如果不是日期字符串,它将返回 FALSE:php.net/manual/en/function.strtotime.php 这是迄今为止我见过的最好的、优雅的、简单有效的方法。谢谢 Yogesh Mistry 不适用于strtotime('a string'); -> 返回当前时间。 给出不正确的结果是字符串以+开头 strtotime("2021-02-31 08:00:00") 将返回 int(1614787200),其计算结果为 TRUE,但它不是 OP 要求的有效日期时间字符串【参考方案7】:

if (strtotime($date)>strtotime(0)) echo '这是一个日期'

【讨论】:

strtotime('a string') > strtotime(0) 将返回 true【参考方案8】:

在我的项目中这似乎可行:

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;
        
    

【讨论】:

什么是 date_parse 和 checkdate? 这些是 PHP 给定的函数:php.net/manual/en/function.date-parse.phpphp.net/manual/en/function.checkdate.php'date_parse' 通过尝试识别可能的日期部分,从给定的字符串创建一个数组。如果您以整数格式将变量传递为 ($month, $day, $year),“checkdate”会验证日期。所以这里真正的问题是 date_parse 的工作情况如何。在我的测试中,它比用户在此页面上建议的其他功能效果更好。 效果很好。需要一种方法来决定我是要尝试解析日期,还是仅将其显示为纯文本。效果很好。 验证任何日期的最佳解决方案。谢谢!【参考方案9】:

如果您不知道日期格式:

/**
 * 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

【讨论】:

var_dump(isDate('now')); //true var_dump(isDate('tomorrow')); //true var_dump(isDate('yesterday')); //真 小心整数! isDate('123456') == true 和 isDate(123456) == true var_dump(isDate("R")) = true。可能不是预期的。我认为它与时区或其他东西匹配。 如果你知道你在传递什么,那就太好了。就我而言,我这样做【参考方案10】:
 function validateDate($date, $format = 'Y-m-d H:i:s') 
     
     $d = DateTime::createFromFormat($format, $date);    
     return $d && $d->format($format) == $date; 
  

函数是从 answer 或 php.net 复制而来的

【讨论】:

【参考方案11】:

如果您有 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);

【讨论】:

【参考方案12】:

这是一种不使用正则表达式的不同方法:

function check_your_datetime($x) 
    return (date('Y-m-d H:i:s', strtotime($x)) == $x);

【讨论】:

【参考方案13】:

虽然这有一个公认的答案,但它并不是在所有情况下都有效。例如,我在使用日期“10/38/2013”​​的表单字段上测试日期验证,我得到了一个有效的 DateObject 返回,但日期是 PHP 所说的“溢出”,所以“10/38/ 2013 年”变为“2013 年 7 月 11 日”。有道理,但我们应该接受修改后的日期,还是强制用户输入正确的日期?对于我们这些表单验证纳粹分子,我们可以使用这个肮脏的修复方法:https://***.com/a/10120725/486863,并在对象抛出此警告时返回 false。

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

【讨论】:

【参考方案14】:

我将此函数用作 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;

【讨论】:

^(\d4(?:\-\d2)2 \d2(?:\:\d2)2)$ 【参考方案15】:

如果您决定使用 regEx,那么 txt2re.com 始终是一个很好的资源:

<?php

  $txt='2012-06-14 01:46:28';
  $re1='((?:2|1)\\d3(?:-|\\/)(?:(?: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";
  

?>

【讨论】:

【参考方案16】:

strtotime?列表?正则表达式?

PHP 的原生 DateTime 对象有什么问题?

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

【讨论】:

【参考方案17】:

我不会为此使用正则表达式,而只是拆分字符串并检查日期是否有效:

list($year, $month, $day, $hour, $minute, $second) = preg_split('%( |-|:)%', $mydatestring);
if(!checkdate($month, $day, $year)) 
     /* print error */
 
/* check $hour, $minute and $second etc */

【讨论】:

以上是关于检查字符串是不是为日期的函数的主要内容,如果未能解决你的问题,请参考以下文章

如何检查字符串是不是为有效日期

php 验证(检查)日期格式是否正确

Python Pandas 检查字符串是不是只有“日期”或只有“时间”或“日期时间”

Python Pandas 检查字符串是不是只有“日期”或只有“时间”或“日期时间”

如何检查字符串是不是匹配某种日期格式?? JAVA [重复]

为啥检查字符串是不是为空的函数总是返回true? [关闭]