2012-06-14 3 views
33

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

2012-06-14 01:46:28 

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

+2

Возможный дубликат cate: http://stackoverflow.com/questions/37732/what-is-the-regex-pattern-for-datetime-2008-09-01-123545 – Fabian

ответ

56

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

if (DateTime::createFromFormat('Y-m-d G:i:s', $myString) !== FALSE) { 
    // it's a date 
} 
+4

Это не решение. У меня есть 'DateTime :: createFromFormat ('m/d/Y', '10/38/2013 ')' и который создает допустимый объект DateTime, а не false. Дата преобразуется в 'object (DateTime) # 39 (3) { [" date "] => string (19)" 2013-11-07 23:45:55 " [" timezone_type "] => int (3) ["timezone"] => string (3) "UTC" } ' – cj5

+1

Yikes. Мне нравится, как эти вещи никогда не упоминаются в документации ... Вы, похоже, не нашли альтернативы? (Изменить: [Форматы даты] (http://www.php.net/manual/en/datetime.formats.date.php) документы, которые вы можете переместить/замять месяцы и дни, но не дают намека на то, что делать, когда вы * не хотите этого поведения. – Joey

+0

Хорошо, что нет решения или настройки для переопределения этого в PHP. Я заметил обходное решение в ответах http://stackoverflow.com/a/19666600/486863 – cj5

4

Я использую эту функцию как параметр функции 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)[email protected]', $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; 
} 
+5

^(\ d {4} (?: \ - \ d {2}) {2} \ d {2} (?: \: \ D {2}) {2}) $ – kioopi

1

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

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

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

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

Это замечательно, спасибо –

0

Если ваше сердце на использование 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"; 
    } 

?> 
2

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

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

0
function validateDate($date, $format = 'Y-m-d H:i:s') 
{  
    $d = DateTime::createFromFormat($format, $date);  
    return $d && $d->format($format) == $date; 
} 

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

0

Если у вас есть ответ PHP 5.2 Джоуи не будет работать.Вы должны расширить РНР 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); 
11

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

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

var_dump (isDate ('now')); // true var_dump (isDate ('tomorrow')); // true var_dump (isDate ('вчера')); // true – Pocketsand

+1

Остерегайтесь целых чисел! isDate ('123456') == true и isDate (123456) == true – Pocketsand

0

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

if(strtotime($date_string)){ 
    // it's in date format 
} 
Смежные вопросы