2012-06-14 32 views
33

Sto provando a scrivere una funzione per determinare se una stringa è una data/ora che utilizza PHP. Fondamentalmente una data/ora valida sarebbe simile:Funzione per verificare se una stringa è una data

2012-06-14 01:46:28 

Ovviamente se il suo completamente dinamico qualsiasi valore può cambiare, ma dovrebbe sempre essere in forma di XXXX-XX-XX XX:XX:XX, come posso scrivere un espressione regolare per verificare la presenza di questo pattern e restituisce true se abbinato.

+2

Possibile dupli cate: http://stackoverflow.com/questions/37732/what-is-the-regex-pattern-for-datetime-2008-09-01-123545 – Fabian

risposta

56

Se questo è tutta la stringa, quindi prova ad analizzarlo:

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

Questa non è una soluzione. Ho 'DateTime :: createFromFormat ('m/d/Y', '10/38/2013 ')' e questo produce un oggetto DateTime valido e non falso. La data viene convertita in 'object (DateTime) # 39 (3) { [" date "] => string (19)" 2013-11-07 23:45:55 " [" timezone_type "] => int (3) ["fuso orario"] => stringa (3) "UTC" } ' – cj5

+1

Yikes. Adoro come queste cose non siano mai indicate nella documentazione ... Non hai trovato un'alternativa? (Modifica: [Formato data] (http://www.php.net/manual/en/datetime.formats.date.php) documenti che puoi sovra/underflow mesi e giorni, ma non dà un suggerimento da fare quando * non * vuole questo comportamento – Joey

+0

Okay, non c'è alcuna soluzione o impostazione per sovrascriverlo in PHP. Ho notato una soluzione alternativa nelle risposte http://stackoverflow.com/a/19666600/486863 – cj5

4

Io uso questa funzione come parametro per la funzione PHP filter_var.

  • Si verifica la presenza di date in formato yyyy-mm-dd hh:mm:ss
  • Respinge le date che corrispondono al modello, ma ancora non validi (ad es apr 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

Non vorrei usare un Regex per questo, ma piuttosto solo dividere la stringa e controllare che la data è valida:

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

Ecco un approccio diverso senza usare un espressione regolare:

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

Questo è ottimo, grazie –

0

Se il vostro cuore è impostata sull'utilizzo Regex allora txt2re.com è sempre una buona risorsa:

<?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

Anche se questa è una risposta accettata, non è andare a lavorare in modo efficace in tutta la casi. Ad esempio, ho verificato la convalida della data su un campo modulo che ho utilizzato la data "30/10/2013" e ho ricevuto un DateObject valido restituito, ma la data era ciò che PHP chiama "overflow", quindi "10/38/2013 "diventa" 11/07/2013 ". Ha senso, ma dovremmo semplicemente accettare la data riformata o obbligare gli utenti a inserire la data corretta? Per quelli di noi che sono nazisti di convalida della forma, possiamo usare questa soluzione sporca: https://stackoverflow.com/a/10120725/486863 e restituire semplicemente false quando l'oggetto lancia questo avvertimento.

L'altra soluzione alternativa consiste nel far corrispondere la data della stringa a quella formattata e confrontare i due per lo stesso valore. Questo sembra altrettanto disordinato. Oh bene. Questa è la natura dello sviluppo di PHP.

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

funzione è stata copiato da questo answer o php.net

0

Se avete la risposta PHP 5.2 di Joey non funzionerà.È necessario estendere la classe DateTime di PHP:

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

e di quanto si può utilizzare questa classe senza problemi:

ExDateTime::createFromFormat('d.m.Y G:i',$timevar); 
11

Nel caso in cui non si conosce il formato della data:

/** 
* 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 ('ieri')); // true – Pocketsand

+1

Fai attenzione ai numeri interi! isDate ('123456') == true e isDate (123456) == true – Pocketsand

0

Una versione più piccola potrebbe essere d'aiuto:

if(strtotime($date_string)){ 
    // it's in date format 
} 
Problemi correlati