Question

Existe-t-il un moyen de vérifier si une date / heure est valide? Vous penseriez que ce serait facile à vérifier:

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

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

Ce qui me rend vraiment, c'est ceci:

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

entraîne: "1999-11-30",

hein? je suis passé de 0000-00-00 à 1999-11-30 ???

Je sais que je pourrais faire une comparaison pour voir si la date est l'une de ces valeurs est égale à la date que j'ai mais ce n'est pas un moyen très robuste de vérifier. Y a-t-il un bon moyen de vérifier si j'ai une date valide? Quelqu'un at-il une bonne fonction pour vérifier cela?

Modifier: Les gens demandent ce que je cours: Exécution de PHP 5.2.5 (cli) sous Linux localhost 2.6.18-53.1.14.el5 # 1 SMP mer 5 mar 11:36:49 EST 2008 i686 i686 i386 GNU / Linux

Était-ce utile?

La solution

De 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;
}
?>

Autres conseils

Comme mentionné ici: https://bugs.php.net/bug.php? id = 45647

  

Il n’ya pas de bogue ici, 00-00-00 signifie 2000-00-00, c’est-à-dire 1999-12-00,   qui est 1999-11-30. Aucun bug, parfaitement normal.

Et comme le montrent quelques tests, revenir en arrière est un comportement attendu, même si un peu dérangeant:

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

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

     

entraîne: "1999-11-30"

Le résultat de strtotime est 943920000 - nombre de secondes, approximativement, entre époque Unix (base à partir de laquelle le temps est mesuré) au 1999-11-30.

Un bogue mysql est documenté. sur mktime (), localtime (), strtotime () renvoient tous cette valeur impaire lorsque vous essayez une heure antérieure à la période (y compris "0000-00-00 00: 00: 00"). Il y a un débat sur le fil lié pour savoir s'il s'agit réellement d'un bogue:

  

Puisque l'horodatage a commencé à partir de 1970, je ne pense pas qu'il soit supposé   travailler de toute façon.

Ci-dessous, une fonction que j’utilise pour convertir dateTimes, comme celle ci-dessus, en un horodatage pour les comparaisons, etc., qui peut vous être utile pour des dates au-delà de "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);
}

Ne vous attendez pas à des résultats cohérents lorsque vous êtes hors de portée:

cf strtotime

cf Gnu Calendar-date-items .html

  

"Pour les mois numériques, l'ISO 8601   le format «année-mois-jour» est autorisé,   où année est un nombre positif,    mois est un nombre compris entre 01   et 12 , et le jour est un   nombre compris entre 01 et 31 . UNE   le zéro principal doit être présent si un   le nombre est inférieur à dix. "

Donc, '0000-00-00' donne des résultats étranges, c'est logique!

  

" En outre, pas tous   les plateformes supportent des horodatages négatifs,   par conséquent, votre plage de dates peut être   limité à pas plus tôt que l'Unix   époque . Cela signifie par exemple que   % e,% T,% R et% D (il pourrait y avoir   plus) et dates antérieures à janvier   1, 1970 ne fonctionnera pas sous Windows, certains   Distributions Linux et quelques autres   systèmes d'exploitation . "

cf strftime

Utilisez plutôt la fonction checkdate (plus robuste):

  

mois:       Le mois est compris entre 1 et 12 inclus .

     

jour:       Le jour est dans le nombre de jours autorisé pour le donné   mois. Les années bissextiles sont prises   en considération.

     

année:       L'année est comprise entre 1 et 32767 .

Cette version permet que le champ soit vide, comporte des dates au format mm / jj / aa ou mm / jj / aaaa, autorise des heures à un chiffre, ajoute facultatif am / pm et corrige quelques failles dans la correspondance temporelle. .

Autorise toujours certains moments pathologiques comme '23: 14 heures '.

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

Si vous voulez juste gérer une conversion de date sans l'heure pour un champ de date mysql, vous pouvez modifier ce code génial comme je l'ai fait. Sur ma version de PHP sans utiliser cette fonction, le message "0000-00-00" est affiché. à chaque fois. Ennuyeux.

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

Je viens de changer la réponse martin ci-dessus, ce qui validera tout type de date et renverra dans le format de votre choix.

Changez simplement le format en éditant sous la ligne de 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" ;
    }
}
?>

J'ai utilisé le code suivant pour valider les dates provenant d'applications 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;
}
?>
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top