Domanda

Esiste un modo per verificare se una data / ora è valida si potrebbe pensare che siano facili da controllare:

$date = '0000-00-00';
$time = '00:00:00';
$dateTime = $date . ' ' . $time;

if(strtotime($dateTime)) {
    // why is this valid?
}

ciò che mi prende davvero è questo:

echo date('Y-m-d', strtotime($date)); 

risulta in: "1999-11-30",

eh? sono passato dal 30-30 al 1999-11-30 ???

So che potrei fare un confronto per vedere se la data è uno di quei valori è uguale alla data che ho ma non è un modo molto affidabile per verificare. C'è un buon modo per verificare se ho una data valida? Qualcuno ha una buona funzione per controllare questo?

Modifica: Le persone chiedono cosa sto correndo: Esecuzione di PHP 5.2.5 (cli) (costruito il 23 luglio 2008 11:32:27) su Linux localhost 2.6.18-53.1.14.el5 # 1 SMP mer 5 mar 11:36:49 EST 2008 i686 i686 i386 GNU / Linux

È stato utile?

Soluzione

Da php.net

<?php
function isValidDateTime($dateTime)
{
    if (preg_match("/^(\d{4})-(\d{2})-(\d{2}) ([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$/", $dateTime, $matches)) {
        if (checkdate($matches[2], $matches[3], $matches[1])) {
            return true;
        }
    }

    return false;
}
?>

Altri suggerimenti

Come menzionato qui: https://bugs.php.net/bug.php? id = 45647

  

Non ci sono bug qui, 00-00-00 significa 2000-00-00, ovvero 1999-12-00,   che è il 1999-11-30. Nessun bug, perfettamente normale.

E come mostrato da alcuni test, il rollback è un comportamento previsto, se un po 'inquietante:

>> date('Y-m-d', strtotime('2012-03-00'))
string: '2012-02-29'
>> date('Y-m-d', strtotime('2012-02-00'))
string: '2012-01-31'
>> date('Y-m-d', strtotime('2012-01-00'))
string: '2011-12-31'
>> date('Y-m-d', strtotime('2012-00-00'))
string: '2011-11-30'
  

data dell'eco ('Y-m-d', strtotime ($ date));

     

risulta in: "1999-11-30"

Il risultato di strtotime è 943920000 - questo è il numero di secondi, approssimativamente, tra Unix epoch (base da cui viene misurato il tempo) fino al 1999-11-30.

Esiste un documentato mysql bug su mktime (), localtime (), strtotime () restituiscono tutti questo valore dispari quando provi un periodo pre-epoca (incluso " 0000-00-00 00: 00: 00 "). C'è qualche dibattito sul thread collegato sul fatto che si tratti effettivamente di un bug:

  

Poiché il timestamp è iniziato dal 1970, non credo che dovrebbe   lavorare comunque.

Di seguito è una funzione che uso per convertire dateTimes come sopra in un timestamp per confronti, ecc., che potrebbe essere di qualche utilità per te, per date oltre "0000-00-00 00: 00: 00";

/**
 * Converts strings of the format "YYYY-MM-DD HH:MM:SS" into php dates
 */
function convert_date_string($date_string)
{
    list($date, $time) = explode(" ", $date_string);
    list($hours, $minutes, $seconds) = explode(":", $time);
    list($year, $month, $day) = explode("-", $date);
    return mktime($hours, $minutes, $seconds, $month, $day, $year);
}

Non aspettarti risultati coerenti quando sei fuori portata:

cf strtotime

cf Gnu Calendar-date-items .html

  

" Per mesi numerici, ISO 8601   formato & # 8216; anno-mese-giorno & # 8217; È permesso,   dove l'anno è un numero positivo,   Il mese è un numero compreso tra 01   e 12 e giorno è a   numero tra 01 e 31 . UN   lo zero iniziale deve essere presente se a   il numero è inferiore a dieci. "

Quindi 'registrazione' dà risultati strani, questo è logico!


  

" Inoltre, non tutti   le piattaforme supportano timestamp negativi,   pertanto l'intervallo di date potrebbe essere   limitato a non prima di Unix   epoca . Ciò significa che ad es.   % e,% T,% R e% D (potrebbero esserci   più) e date precedenti a gennaio   1, 1970 non funzionerà su Windows, alcuni   Distribuzioni Linux e poche altre   sistemi operativi . "

cf strftime


Utilizza invece la funzione checkdate (più affidabile):

  

mese:       Il mese è compreso tra 1 e 12 inclusi .

     

giorno:       Il giorno è entro il numero di giorni consentito per il dato   mese. Gli anni bisestili sono presi   in considerazione.

     

Anno:       L'anno è compreso tra 1 e 32767 inclusi .

Questa versione consente di svuotare il campo, ha le date nel formato mm / gg / aa o mm / gg / aaaa, consente ore a cifra singola, aggiunge am / pm opzionali e corregge alcuni impercettibili imperfezioni nella corrispondenza temporale .

Permette ancora alcuni periodi patologici come '23: 14 AM '.

function isValidDateTime($dateTime) {
    if (trim($dateTime) == '') {
        return true;
    }
    if (preg_match('/^(\d{1,2})\/(\d{1,2})\/(\d{2,4})(\s+(([01]?[0-9])|(2[0-3]))(:[0-5][0-9]){0,2}(\s+(am|pm))?)?$/i', $dateTime, $matches)) {
        list($all,$mm,$dd,$year) = $matches;
        if ($year <= 99) {
            $year += 2000;
        }
        return checkdate($mm, $dd, $year);
    }
    return false;
}

Se vuoi solo gestire una conversione di data senza l'ora per un campo di data mysql, puoi modificare questo fantastico codice come ho fatto io. Nella mia versione di PHP senza eseguire questa funzione ottengo " 0000-00-00 " ogni volta. Fastidioso.

function ConvertDateString ($DateString)
{
    list($year, $month, $day) = explode("-", $DateString);
    return date ("Y-m-d, mktime (0, 0, 0, $month, $day, $year));
}
<?php
function is_valid_date($user_date=false, $valid_date = "1900-01-01") {
    $user_date = date("Y-m-d H:i:s",strtotime($user_date));
    return strtotime($user_date) >= strtotime($valid_date) ? true : false;
}

echo is_valid_date("00-00-00") ? 1 : 0;    // return 0

echo is_valid_date("3/5/2011") ? 1 : 0;    // return 1

Ho appena cambiato la risposta martin sopra, che convaliderà qualsiasi tipo di data e tornerà nel formato che ti piace.

Cambia semplicemente il formato modificando la riga sotto lo script strftime (" 10-10-2012 " ;, strtotime ($ dt));

<?php
echo is_date("13/04/10");

function is_date( $str ) {
    $flag = strpos($str, '/');

    if(intval($flag)<=0){
        $stamp = strtotime( $str );
    } else {
        list($d, $m, $y) = explode('/', $str);    
        $stamp = strtotime("$d-$m-$y");
    } 
    //var_dump($stamp) ;

    if (!is_numeric($stamp)) {
        //echo "ho" ;
        return "not a date" ;        
    }

    $month = date( 'n', $stamp ); // use n to get date in correct format
    $day   = date( 'd', $stamp );
    $year  = date( 'Y', $stamp );

    if (checkdate($month, $day, $year)) {
        $dt = "$year-$month-$day" ;
        return strftime("%d-%b-%Y", strtotime($dt));
        //return TRUE;
    } else {
        return "not a date" ;
    }
}
?>

Ho usato il seguente codice per convalidare le date provenienti dalle applicazioni ExtJS.

function check_sql_date_format($date) {
    $date = substr($date, 0, 10);
    list($year, $month, $day) = explode('-', $date);
    if (!is_numeric($year) || !is_numeric($month) || !is_numeric($day)) {
        return false;
    }
    return checkdate($month, $day, $year);
}
<?php

function is_date( $str ) {
    $stamp = strtotime( $str );

    if (!is_numeric($stamp)) {
        return FALSE;
    }
    $month = date( 'm', $stamp );
    $day   = date( 'd', $stamp );
    $year  = date( 'Y', $stamp );

    if (checkdate($month, $day, $year)) {
        return TRUE;
    }
    return FALSE;
}
?>
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top