web-dev-qa-db-fra.com

preg_match: vérifie le format d'anniversaire (jj/mm/aaaa)

Comment créer l'expression qui vérifie l'entrée anniversaire pour qu'elle corresponde à un format comme celui-ci jj/mm/aaaa? Ci-dessous est ce que je suis sorti jusqu'à présent, mais cela prend aussi si je mets 99/99/9999!

if (!preg_match("/[0-9]{2}\/[0-9]{2}\/[0-9]{4}/", $cnt_birthday))
  {
   $error = true;
   echo '<error elementid="cnt_birthday" message="BIRTHDAY - Only this birthday format - dd/mm/yyyy - is accepted."/>';
  }

Comment puis-je m'assurer que c'est seulement 01 à 31 pour dd et 01 à 12 pour mm? mais je suis sûr que vous devriez limiter yyyy ... Je pense que 9999 théorique devrait être acceptable ... faites-moi savoir si vous avez une meilleure idée!

merci Lau

10
laukok

Basé sur Tim s checkdate based solution:

L'extraction du jour, du mois et de l'année peut facilement être effectuée à l'aide de explode comme:

list($dd,$mm,$yyyy) = explode('/',$cnt_birthday);
if (!checkdate($mm,$dd,$yyyy)) {
        $error = true;
}
22
codaddict

Je suggérerais d'utiliser checkdate () pour cela à la place:

if (preg_match("/([0-9]{2})\/([0-9]{2})\/([0-9]{4})/", $cnt_birthday, $matches)) {
    if (!checkdate($matches[2], $matches[1], $matches[3])) {
        $error = true;
        echo '<error elementid="cnt_birthday" message="BIRTHDAY - Please enter a valid date in the format - dd/mm/yyyy"/>';
    }
} else {
    $error = true;
    echo '<error elementid="cnt_birthday" message="BIRTHDAY - Only this birthday format - dd/mm/yyyy - is accepted."/>';
}

Donc, regexp valide le format, checkdate valide la date réelle.

25
Tim Fountain

Pensez à utiliser strtotime() et reformatez-le avec date(). Il offrira plus de flexibilité aux utilisateurs lors de la saisie d'une date et vous permettra d'utiliser les formats dont vous avez besoin à différents endroits.

Personnellement, je suis assez paresseux quand il s’agit de calculer la date avec précision et d’en abuser comme strtotime("-10 day",$timestamp). Cela a l'avantage de réduire les risques de poursuites en justice par un parent contrarié, car vous avez calculé que l'âge de leur petite fille était juste au-dessus de 18 ans, sans tenir compte des années bissextiles correctement, et que vous la laissiez sur votre site Web pour adultes, aussi ridicule que cela puisse paraître.

3
artificialidiot
if(preg_match("/(\d{2})\/(\d{2})\/(\d{4})$/", $date,$matches)){         
return (checkdate((int) $matches[2],(int)$matches[1],(int) $matches[3]) );
}else{
return false ;
}
  • preg_match pour valider le motif jj/mm/aaaa
  • checkdate pour valider les valeurs de date
3
Yehia
$ok  = DateTime::createFromFormat('d/m/Y',$datestring)->format('d/m/Y') == $datestring;

PHP> = 5.3

2
Wrikken

Pour être vraiment anal-rétentif, il peut être plus facile d’utiliser votre expression rationnelle actuelle, d’analyser les nombres, puis de vérifier qu’ils se trouvent bien dans la plage avec checkdate () , mais pour les amateurs, voici l’expression rationnelle qui assure dates = 01-31 (et 1-9) , et mois = 01-12 (et 1-9) .

preg_match("/([012]?[1-9]|[12]0|3[01])\/(0?[1-9]|1[012])\/([0-9]{4})/", $date_string)

Quelques choses à noter

  • J'ai utilisé le regroupement sur tous, requis pour l'ORing (|) au sein de, mais aussi utile pour extraire ces valeurs si vous voulez faire des choses spécifiques avec elles
  • 0000 n'a pas beaucoup de sens en tant que date, mais j'ai laissé l'explosion de cette regex comme excersise au lecteur. Si vous voulez vraiment que cela vérifie les dates de naissance (et vous vous attendez à des personnes décédées actuellement ou relativement récemment), limitez-vous à 1900+ ou 1800+, ou à une autre plage acceptable pour vous. Si vous analysez les anniversaires de personnages historiques ... votre appel.
  • Cela ne vérifie toujours pas que la plage de dates est correcte pour le mois en question! donc pour cette utilisation checkdate ()
1
Chadwick

peut-être que quelque chose comme ça aiderait

 list($month,$day,$year)=explode("/",$date);
if(checkdate($month,$day,$year))
{
echo "good";
}
else{echo "bad";}
1
Sujay sreedhar

Essayez cette regex: ([0-9]{2}\/[0-9]{2}\/[0-9]{4})

0
dialyy

Accepter uniquement une chaîne strictement formatée est probablement une mauvaise pratique. En supposant que vous obteniez des informations d'une page Web, il serait préférable d'avoir des champs distincts pour le mois, le jour et l'année. Il pourrait s’agir simplement de zones de texte, mais il serait peut-être préférable d’avoir des menus déroulants, ce qui résoudrait votre problème de limites (c’est-à-dire que les seuls choix pour les mois sont 1,2, ..., 12). Exiger que les utilisateurs entrent le 01/01/2001 et n'acceptent pas le 1/1/2001 est une programmation paresseuse. Et n'accepter que "/" comme séparateur est gênant.

Mais, pour aborder votre question initiale même si vous décidez de vous en tenir aux chaînes formatées - comme il s'agit d'un champ de date de naissance, vous devriez probablement limiter le aaaa à:

if($yyyy > date('Y')) {
  echo '<error elementid="cnt_birthday" message="BIRTHDAY - Year must be less than or equal to the current year."/>';
}

Sinon, les gens pourraient avoir des âges négatifs :)

0
catgofire

Je suis en retard pour voir cela, mais cela a résolu mon problème

    if (1 !== preg_match('/(0[1-9]|1[0-9]|2[0-9]|3(0|1))\/(0[1-9]|1[0-2])\/\d{4}/',$value)) {
        $this->form_validation->set_message('validate_emaildate','Date needs to have a valid date format - dd/mm/yyyy');
        return FALSE;
    }

Courtesy les messages suivants:

Format regex ici .. merci Abin.

Fonction pour vérifier le format [ici] ( Correspondance rationnelle de Codeigniter ) .. merci Hachem

+ acclamations

0
devak23

Probablement pas la meilleure solution, mais voici mon essai.

Vous le convertissez en heure, puis reformatez-le en m/j/Y. Si la chaîne est inchangée, le format de départ était correct.

$transformedDate = date("m/d/Y", strtotime($myDate));

if($transformedDate == $myDate){        
    return true;    
} else{         
    return false;           
}
0
NL3294