6 Question: PHP DateTime acceptant la date invalide

question créée à Mon, Apr 4, 2011 12:00 AM

Je ne parviens pas à utiliser la classe PHP DateTime, et plus particulièrement la classe DateTime::createFromFormat().

J'obtiens une date d'une chaîne, puis j'essaie d'instancier un objet DateTime à l'aide de DateTime::createFromFormat(). Mais, lorsque je donne à cette fonction une date qui ne peut pas exister, elle fonctionne toujours et me renvoie un objet DateTime valide, avec une date valide, qui n'est pas la date que je lui ai indiquée .

Exemple de code:

 
$badDate = '2010-13-03';
$date = DateTime::createFromFormat('Y-m-d', $badDate);

var_dump($date);

/*
object(DateTime)#284 (3) {
["date"]=>
string(19) "2011-01-03 10:01:20"
["timezone_type"]=>
int(3)
["timezone"]=>
string(13) "Europe/Berlin"
}
*/

Des idées? J'ai vraiment besoin d'un moyen de vérifier la validité de la date.

Merci.

Modifier:

Je viens de trouver pourquoi, voir ma réponse.

    
11
6 réponses                              6                         

Vous devez utiliser DateTime::getLastErrors() qui contiendra l'erreur The parsed date was invalid.

 
$badDate = '2010-13-03';
$date = DateTime::createFromFormat('Y-m-d', $badDate);
if( DateTime::getLastErrors()['warning_count'] > 0 ){
 //not a correct date
}else{
 //correct date
 print $date->format('Y-m-d');
}
    
13
2011-04-04 15: 23: 22Z

DateTime::createFromFormat ne jette pas exception /retour faux lorsque la date donnée est impossible. Il essaie de deviner la date prévue.

Si vous lui donnez '2010-01-32' (comme dans Januar, le 32), il retournera un objet DateTime contenant Februar, 1st (31 janvier + 1 jour). Doit être logique ... d'une manière bizarre tordue.

Pour vérifier la validité, vous devez vérifier le DateTime::getLastErrors() qui contient un avertissement, comme pour mon cas:

 
array(4) {
  ["warning_count"]=>
  int(1)
  ["warnings"]=>
  array(1) {
    [10]=>
    string(27) "The parsed date was invalid"
  }
  ["error_count"]=>
  int(0)
  ["errors"]=>
  array(0) {
  }
}

Ce problème semble provenir de l'horodatage UNIX calculé par PHP, en fonction de l'année, du mois et de la date que vous lui indiquez (même si la date n'est pas valide).

    
10
2011-04-04 08: 28: 58Z
  1. "Ce doit être logique ... d'une façon bizarre et tordue." == > Oh, on le voit souvent en PHP.
    2015-11-15 20: 07: 17Z
  2. Tous ceux qui liront ceci se souviendront de rechercher à la fois les avertissements ET les erreurs, en particulier si vous écrivez votre propre fonction isValidDate pour en finir.
    2018-05-25 15: 35: 01Z

J'ai trouvé un exemple où la validation basée sur DateTime::getLastErrors() échouera. Il serait donc préférable de comparer la date saisie à la date générée.

Code:

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

Exemple d'utilisation:

 
var_dump(validateDate('2012-02-28')); # true
var_dump(validateDate('2012-02-30')); # false

# you can validate and date/time format
var_dump(validateDate('14:50', 'H:i')); # true
var_dump(validateDate('14:99', 'H:i')); # false

# this is the example where validation with `DateTime::getLastErrors()` will fail
var_dump(validateDate('Tue, 28 Feb 2012 12:12:12 +0200', DateTime::RSS)); # true
var_dump(validateDate('Tue, 27 Feb 2012 12:12:12 +0200', DateTime::RSS)); # false
    
10
2013-09-29 18: 49: 09Z
  1. ouch, belle prise. Quelle version de PHP utilisez-vous pour ce test? Peut-être que cela a été corrigé en cours de route?
    2013-09-30 14: 41: 29Z
  2. @ ClementHerreman: ce résultat est valable pour toutes les versions de PHP prenant en charge DateTime::createFromFormat, c'est-à-dire au-dessus de php > = 5.3.0. Regardez-le en action ici . Je n'ai jamais dit que DateTime::getLastErrors() devrait signaler un avertissement ou une erreur dans ce cas, cela fonctionne probablement comme prévu (en ignorant les jours de chaîne), mais si vous exécutez une fonction de validation, cela devrait avoir de l'importance, car 27 Feb 2012 n'est pas Tuesday, c'est Monday. /div>
    2013-09-30 14: 54: 20Z
  3. Dans cet exemple, DateTime::getLastErrors() signale une erreur uniquement si le jour textuel est introuvable ou invalide, voir .
    2013-09-30 14: 59: 59Z
  4. Une solution beaucoup plus agréable, car elle devrait gérer les erreurs et les avertissements. Merci!
    2014-12-31 12: 25: 54Z

Recherchez la fonction checkdate() dans la documentation php. Cela vous aidera:)

    
3
2019-03-21 04: 13: 16Z
  1. Cela aurait dû être la réponse.
    2019-03-21 04: 11: 43Z

Vous pouvez le faire:

 
DateTime::getLastErrors()
    
0
2011-04-04 08: 21: 12Z

changer

 
$date = DateTime::createFromFormat('Y-m-d', $badDate);

dans

 
$date = DateTime::createFromFormat('Y-d-m', $badDate);

Votre format donné est incorrect , vous avez correctement mélangé jours et mois ...

Pour comprendre ce qui se cache derrière le calcul magique des dates, lisez ceci: bon article de Derick Rethans et tous les commentaires;)

    
- 1
2011-04-04 15: 13: 33Z
  1. Le format n'est pas mauvais, c'est vraiment «Y-m-d», je veux m'assurer que la validité de la date est vérifiée.
    2011-04-04 09: 07: 06Z
  2. Mais quand m est la deuxième partie et que vous passez 13: son calculé en janvier de l'année suivante. Tout va bien ici! C’est ainsi que PHP calcule avec des nombres qui se chevauchent sur des dates.
    2011-04-04 09: 18: 52Z
  3. En effet, c'est ce que je viens de découvrir, mais 2 questions se posent: 1. où diable est-il documenté? 2. Suis-je le seul à ne pas trouver ce comportement logique /attendu?
    2011-04-04 13: 18: 55Z
  4. J'ai ajouté un lien vers un article.
    2011-04-04 15: 15: 26Z
  5. Bel article, mais vous devriez peut-être aussi modifier votre réponse à mon sujet en utilisant un mauvais format =).
    2011-04-05 10: 00: 22Z
source placée ici
D\'autres questions