Функция для проверки, является ли строка датой


Я пытаюсь написать функцию, чтобы определить, является ли строка датой/временем, используя PHP. В основном действительная дата/время будет выглядеть так:

 2012-06-14 01:46:28

Очевидно, что, хотя его полностью динамическое любое значение может измениться, но оно всегда должно быть в форме XXXX-XX-XX XX:XX:XX, как я могу написать регулярное выражение, чтобы проверить этот шаблон и вернуть значение true, если оно совпадает.

Author: Housy, 2012-06-14

12 answers

Если это вся ваша строка, то просто попробуйте разобрать ее:

if (DateTime::createFromFormat('Y-m-d G:i:s', $myString) !== FALSE) {
  // it's a date
}
 68
Author: Joey, 2012-06-14 09:10:02

Вот другой подход без использования регулярного выражения:

function check_your_datetime($x) {
    return (date('Y-m-d H:i:s', strtotime($x)) == $x);
}
 26
Author: Bjoern, 2013-12-21 10:10:00

На случай, если вы не знаете формат даты:

/**
 * 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
 13
Author: John Linhart, 2017-01-06 10:48:34

Я использую эту функцию в качестве параметра PHP filter_var функция.

  • Он проверяет наличие дат в формате yyyy-mm-dd hh:mm:ss
  • Он отклоняет даты, соответствующие шаблону, но все еще недействительные (например, 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;
}
 4
Author: Salman A, 2013-01-09 17:03:03

Хотя на этот вопрос есть общепринятый ответ, он не будет эффективно работать во всех случаях. Например, я проверяю проверку даты в поле формы, которое у меня есть, используя дату "10/38/2013", и я получил возвращенный действительный объект DateObject, но дата была такой, которую PHP называет "переполненной", так что "10/38/2013" становится "11/07/2013". Имеет смысл, но должны ли мы просто принять измененную дату или заставить пользователей вводить правильную дату? Для тех из нас, кто является нацистами по проверке форм, мы можем использовать это грязное исправление: https://stackoverflow.com/a/10120725/486863 и просто возвращайте false, когда объект выдает это предупреждение.

Другим обходным решением было бы сопоставить строковую дату с отформатированной и сравнить их для равного значения. Это кажется таким же беспорядочным. Ну что ж. Такова природа PHP-разработчика.

 2
Author: cj5, 2017-05-23 12:34:19

Я бы не стал использовать для этого регулярное выражение, а просто разделил строку и проверил, что дата действительна:

list($year, $month, $day, $hour, $minute, $second) = preg_split('%( |-|:)%', $mydatestring);
if(!checkdate($month, $day, $year)) {
     /* print error */
} 
/* check $hour, $minute and $second etc */
 1
Author: Artefact2, 2012-06-14 08:59:52

Уменьшенная версия, это может помочь:

if(strtotime($date_string)){
    // it's in date format
}
 1
Author: Yogesh Mistry, 2017-12-02 12:23:33

strtotime? Списки? Регулярные выражения?

Что не так с собственным объектом PHP DateTime?

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

 0
Author: Sherlock, 2012-06-14 09:03:36

Если ваше сердце настроено на использование регулярного выражения, то 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";
  }

?>
 0
Author: PT114, 2012-06-14 09:05:25

Если у вас есть PHP 5.2, ответ Джоуи не сработает. Вам нужно расширить класс 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);
 0
Author: MERT DOĞAN, 2014-10-27 19:59:19
 function validateDate($date, $format = 'Y-m-d H:i:s') 
 {    
     $d = DateTime::createFromFormat($format, $date);    
     return $d && $d->format($format) == $date; 
 } 

функция была скопирована из этого ответа или php.net

 0
Author: José Rodrigues, 2017-05-23 10:31:34

В моем проекте это, кажется, работает:

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;
        }
    }
}
 0
Author: Gabor, 2018-04-12 12:36:11