Question PHP DateTime acceptant une date invalide


J'ai du mal à utiliser le PHP DateTime classe, et plus précisément la DateTime::createFromFormat().

J'obtiens une date à partir d'une chaîne, puis j'essaie d'instancier un objet DateTime, en utilisant DateTime::createFromFormat(). Mais, quand je donne à cette fonction une date qui n’existe pas, elle fonctionne toujours, en me renvoyant une date valide. DateTime objet, avec une date valide, ce qui n'est pas la date que je lui ai donné.

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é des dates.

Je vous remercie.

Modifier:

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


11
2018-04-04 08:15


origine


Réponses:


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
2018-04-04 08:23



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

Si vous le donnez '2010-01-32' (comme à Januar, 32), il retournera un DateTime objet contenant février, 1er (31 janvier + 1 jour). Ça doit être logique ... d'une certaine manière bizarre.

Pour vérifier la validité, vous devez vérifier la 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 comportement semble provenir de l'horodatage UNIX que PHP calcule, en fonction de l'année, du mois et de la date que vous lui donnez (même si la date n'est pas valide).


10
2018-04-04 08:28



J'ai trouvé l'exemple où la validation basée sur DateTime::getLastErrors() échouera, donc une meilleure solution serait de comparer la date saisie avec la date de création.

Code:

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

Utilisez l'exemple:

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
2017-09-29 18:49



Chercher date de vérification, date du chèque() fonction à la documentation php. Cela vous aidera :)


2
2018-04-04 08:20



Vous pouvez le faire :

DateTime::getLastErrors()

0
2018-04-04 08:21



changement

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

dans

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

Votre format donné est faux, vous avez bien mélangé les jours et les mois ...

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


-1
2018-04-04 08:40