2010-03-26 16 views
57

Ho una stringa e ho bisogno di scoprire se è un timestamp unix o meno, come posso farlo in modo efficace?Verificare se la stringa è un timestamp unix

Ho trovato this thread tramite Google, ma non mi viene in mente una risposta molto solida, temo. (E sì, ho cribato la domanda dal poster originale sul thread di cui sopra).

+0

dalla lettura del thread direi che la risposta breve è no. potresti essere in grado di controllare qualcosa che non è sicuramente valido ma valido, non sembra. – PurplePilot

+0

Puoi aggiungere qualche spiegazione in più sul motivo per cui è necessario convalidare la stringa o cosa si intende fare con essa, una volta convalidata. – Gordon

risposta

77

Ok, dopo giocherellare con questo per un po ', mi ritiro la soluzione con date('U') e suggerisco di utilizzare questa invece:

function isValidTimeStamp($timestamp) 
{ 
    return ((string) (int) $timestamp === $timestamp) 
     && ($timestamp <= PHP_INT_MAX) 
     && ($timestamp >= ~PHP_INT_MAX); 
} 

Questo controllo sarà solo restituire true se la data $timestamp è una stringae consiste esclusivamente di cifre e un carattere meno facoltativo. Il numero deve essere compreso nell'intervallo di bit di un numero intero (EDIT: actually unneeded as shown here).

var_dump(isValidTimeStamp(1)   ); // false 
var_dump(isValidTimeStamp('1')   ); // TRUE 
var_dump(isValidTimeStamp('1.0')  ); // false 
var_dump(isValidTimeStamp('1.1')  ); // false 
var_dump(isValidTimeStamp('0xFF')  ); // false 
var_dump(isValidTimeStamp('0123')  ); // false 
var_dump(isValidTimeStamp('01090')  ); // false 
var_dump(isValidTimeStamp('-1000000') ); // TRUE 
var_dump(isValidTimeStamp('+1000000') ); // false 
var_dump(isValidTimeStamp('2147483648') ); // false 
var_dump(isValidTimeStamp('-2147483649')); // false 

Il controllo per PHP_INT_MAX è assicurare che la stringa può essere utilizzato correttamente date e simili, ad esempio assicura questo non accade *:

echo date('Y-m-d', '2147483648'); // 1901-12-13 
echo date('Y-m-d', '-2147483649'); // 2038-01-19 

Nei sistemi a 64 bit del numero intero è ovviamente maggiore di quello e la funzione non sarà più tornare false per "2147483648" e "-2.147,483649 millions", ma per i corrispondenti numeri più grandi .


(*) Nota: Io non sono sicuro al 100%, la gamma di bit corrisponde con quello che la data può usare anche se

+1

I * think * timestamp negativi sono validi. 'time_t' è firmato almeno in Linux. – Yacoby

+1

Non ha funzionato per un valore di 1276664400, probabilmente a causa del ritorno del valore come stringa anziché di un intero. –

+1

@jtyost Funziona come spiegato e richiesto dall'OP. Controlla se la ** stringa ** è un timestamp Unix valido. Passare un ** intero ** ovviamente non restituirà true. Passando in '" 1276664400 "' sarà. – Gordon

34

Poiché un timestamp unix è un numero intero, utilizzare is_int(). Tuttavia, poiché is_int() non funziona sulle stringhe, controlliamo se è numerico e la sua forma intergal è uguale alla sua forma originale. Esempio:

(is_numeric($stamp) && (int)$stamp == $stamp) 
+0

Per esprimere timestamp con millisecondi, l'unixtimestamp può anche essere un punto mobile in alcune aree, giusto? –

+0

@Patrick Una marca temporale Unix è solitamente un numero intero a causa della precisione in virgola mobile. Non l'ho mai visto rappresentato come un numero reale. – Yacoby

+1

L'OP ha una stringa, quindi is_int non lo farà. Deve essere is_numeric se presente. – Gordon

1

Si desidera verificare se una stringa contiene un numero elevato?

is_numeric() è la chiave

oppure convertirla in DateTime e fare alcuni controlli con esso come un intervallo di date prevista.

2

Questo non tiene conto per i tempi negativi (prima del 1970) , né tiene conto di intervalli prolungati (è possibile utilizzare interi a 64 bit in modo che un timestamp può rappresentare un valore di gran lunga dopo 2038)

$valid = ctype_digit($str) && $str <= 2147483647; 
0

Altra possibilità:

$date_arg = time(); 
$date_is_ok = ($date_arg === strtotime(date('c', $date_arg))); 
+1

Stai convalidando $ date_arg contro se stesso? Come si convalida se un'altra stringa è una data? –

0
//if anything else than digits inside the string then your string is no timestamp 
    //in which case maybe try to get the timestamp with strtotime 

    if(preg_match('/[^\d]/', $str)) { 
     $str = strtotime($str); 

     if (false === $str) { 
      //conversion failed - invalid time - invalid row 
      return; 
     } 
    } 
4

questo appare come la strada da percorrere:

function is_timestamp($timestamp) { 
    if(strtotime(date('d-m-Y H:i:s',$timestamp)) === (int)$timestamp) { 
     return $timestamp; 
    } else return false; 
} 

si potrebbe anche aggiungere un is_numeric() controllare e ogni sorta di altri controlli.
ma questo dovrebbe/potrebbe essere le basi.

+0

Questo codice funziona, ma genererà un avviso se si passa a qualcosa di diverso da un timestamp valido. –

+0

Qual è l'avviso di? (Ho avuto un errore di battitura in esso. utilizzare d-m-Y anziché americano m-d-Y !!) è possibile modificarlo con eccezioni di lancio in roba. –

+0

È un E_NOTICE che hai passato un valore non valido. La formattazione di date() non influisce su questo.Ad alcune persone non importa gli script che lanciano le notifiche e basta disattivare la segnalazione degli errori per quel livello ma molti (me compreso) preferiscono non lanciare o mettere a tacere nemmeno le notifiche E_STRICT a meno che non sia necessario. –

0

o

if ($startDate < strtotime('-30 years') || $startDate > strtotime('+30 years')) { 
    //throw exception 
} 
0

Se si potrebbe pensare di sostituire this soluzione is_numeric(), si prega di considerare che la funzione nativa PHP fornisce falsi positivi per le stringhe di input come "1.1", "0123", "0xFF", che non sono in formato timestamp.

2

Risposta migliorata a @ TD_Nijboer.

Ciò eviterà un'eccezione essere generata se la stringa fornita non è un timestamp:

function isTimestamp($timestamp) { 
    if(ctype_digit($timestamp) && strtotime(date('Y-m-d H:i:s',$timestamp)) === (int)$timestamp) { 
     return true; 
    } else { 
     return false; 
} 
7

mi sono imbattuto la stessa domanda e ha creato la seguente soluzione per la mia auto, dove non c'è bisogno di pasticcio con espressioni regolari o clausole if disordinate:

/** 
* @param string $string 
* @return bool 
*/ 
public function isTimestamp($string) 
{ 
    try { 
     new DateTime('@' . $string); 
    } catch(Exception $e) { 
     return false; 
    } 
    return true; 
}