it-swarm.com.de

PHP Das Datum, an dem Regex überprüft wird, hat das Format JJJJ-MM-TT

Ich versuche zu prüfen, ob die von Endbenutzern eingegebenen Daten im JJJJ-MM-TT angegeben sind. Regex war noch nie meine Stärke, ich bekomme immer einen falschen Rückgabewert für das von mir eingerichtete preg_match ().

Ich gehe also davon aus, dass ich den Regex durcheinander gebracht habe.

$date="2012-09-12";

if (preg_match("^[0-9]{4}-[0-1][0-9]-[0-3][0-9]$",$date))
    {
        return true;
    }else{
        return false;
    }

Irgendwelche Gedanken?

76
cosmicsafari

Versuche dies.

$date="2012-09-12";

if (preg_match("/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/",$date)) {
    return true;
} else {
    return false;
}
156
Avin Varghese

Es ist wahrscheinlich besser, einen anderen Mechanismus dafür zu verwenden.

Die moderne Lösung mit DateTime :

$dt = DateTime::createFromFormat("Y-m-d", $date);
return $dt !== false && !array_sum($dt::getLastErrors());

Dies bestätigt auch die Eingabe: $dt !== false stellt sicher, dass das Datum mit dem angegebenen Format analysiert werden kann. Der array_sum-Trick ist eine knappe Methode, um sicherzustellen, dass PHP keine "Monatsverschiebung" vorgenommen hat (z. B., der 32. Januar sei der 1. Februar ). Weitere Informationen finden Sie unter DateTime::getLastErrors() .

Old School-Lösung mit explode und checkdate :

list($y, $m, $d) = array_pad(explode('-', $date, 3), 3, 0);
return ctype_digit("$y$m$d") && checkdate($m, $d, $y);

Dies bestätigt, dass die Eingabe auch ein gültiges Datum ist. Sie können das natürlich mit einem Regex tun, aber das wird mehr Aufregung - und der 29. Februar kann überhaupt nicht mit einem Regex bestätigt werden.

Der Nachteil dieses Ansatzes ist, dass Sie sehr vorsichtig sein müssen, um alle möglichen "schlechten" Eingaben abzulehnen, während Sie unter keinen Umständen eine Benachrichtigung ausgeben. Hier ist wie:

  • explode kann nur 3 Token zurückgeben (damit bei Eingabe von "1-2-3-4" $d "3-4" wird)
  • ctype_digit wird verwendet, um sicherzustellen, dass die Eingabe keine nicht numerischen Zeichen enthält (abgesehen von den Bindestrichen)
  • array_pad wird verwendet (mit einem Standardwert, der dazu führt, dass checkdate fehlschlägt), um sicherzustellen, dass genügend Elemente zurückgegeben werden, damit list() bei einer Eingabe von "1-2" keine Benachrichtigung ausgibt
84
Jon

JJJJ-MM-TT:/^((((19|[2-9]\d)\d{2})\-(0[13578]|1[02])\-(0[1-9]|[12]\d|3[01]))|(((19|[2-9]\d)\d{2})\-(0[13456789]|1[012])\-(0[1-9]|[12]\d|30))|(((19|[2-9]\d)\d{2})\-02\-(0[1-9]|1\d|2[0-8]))|(((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))\-02\-29))$/g

JJJJ/MM/TT:/^((((19|[2-9]\d)\d{2})\/(0[13578]|1[02])\/(0[1-9]|[12]\d|3[01]))|(((19|[2-9]\d)\d{2})\/(0[13456789]|1[012])\/(0[1-9]|[12]\d|30))|(((19|[2-9]\d)\d{2})\/02\/(0[1-9]|1\d|2[0-8]))|(((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))\/02\/29))$/g

MM-TT-JJJJ:/^(((0[13578]|1[02])\-(0[1-9]|[12]\d|3[01])\-((19|[2-9]\d)\d{2}))|((0[13456789]|1[012])\-(0[1-9]|[12]\d|30)\-((19|[2-9]\d)\d{2}))|(02\-(0[1-9]|1\d|2[0-8])\-((19|[2-9]\d)\d{2}))|(02\-29\-((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))))$/g

MM/TT/JJJJ:/^(((0[13578]|1[02])\/(0[1-9]|[12]\d|3[01])\/((19|[2-9]\d)\d{2}))|((0[13456789]|1[012])\/(0[1-9]|[12]\d|30)\/((19|[2-9]\d)\d{2}))|(02\/(0[1-9]|1\d|2[0-8])\/((19|[2-9]\d)\d{2}))|(02\/29\/((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))))$/g

TT/MM/JJJJ:/^(((0[1-9]|[12]\d|3[01])\/(0[13578]|1[02])\/((19|[2-9]\d)\d{2}))|((0[1-9]|[12]\d|30)\/(0[13456789]|1[012])\/((19|[2-9]\d)\d{2}))|((0[1-9]|1\d|2[0-8])\/02\/((19|[2-9]\d)\d{2}))|(29\/02\/((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))))$/g

TT-MM-JJJJ:/^(((0[1-9]|[12]\d|3[01])\-(0[13578]|1[02])\-((19|[2-9]\d)\d{2}))|((0[1-9]|[12]\d|30)\-(0[13456789]|1[012])\-((19|[2-9]\d)\d{2}))|((0[1-9]|1\d|2[0-8])\-02\-((19|[2-9]\d)\d{2}))|(29\-02\-((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))))$/g

35
Shyju KP

Kriterien:

Jedes durch 4 teilbare Jahr ist ein Schaltjahr, es sei denn, es ist durch 100 teilbar, es sei denn, es ist durch 400 teilbar.

2004 - leap year - divisible by 4
1900 - not a leap year - divisible by 4, but also divisible by 100
2000 - leap year - divisible by 4, also divisible by 100, but divisible by 400

Februar hat 29 Tage in einem Schaltjahr und 28, wenn kein Schaltjahr

30 Tage im April, Juni, September und November

31 Tage im Januar, März, Mai, Juli, August, Oktober und Dezember

Prüfung:

Die folgenden Daten sollten alle gültig sein:

1976-02-29
2000-02-29
2004-02-29
1999-01-31

Die folgenden Daten sollten alle die Validierung nicht bestanden haben:

2015-02-29
2015-04-31
1900-02-29
1999-01-32
2015-02-00

Angebot:

Wir werden Datumsangaben vom 1. Januar 1000 bis zum 31. Dezember 2999 testen. Technisch wurde der derzeit verwendete Gregorianische Kalender erst 1753 für das Britische Empire und zu verschiedenen Jahren im 17. Jahrhundert für Länder in Europa verwendet, aber ich bin nicht dabei werde mir darüber Sorgen machen.

Regex testet auf ein Schaltjahr:

Die durch 400 teilbaren Jahre:

1200|1600|2000|2400|2800
can be shortened to:
(1[26]|2[048])00

if you wanted all years from 1AD to 9999 then this would do it:
(0[48]|[13579][26]|[2468][048])00
if you're happy with accepting 0000 as a valid year then it can be shortened:
([13579][26]|[02468][048])00

Die durch 4 teilbaren Jahre:

[12]\d([02468][048]|[13579][26])

Die durch 100 teilbaren Jahre:

[12]\d00

Nicht teilbar durch 100:

[12]\d([1-9]\d|\d[1-9])

Die Jahre sind durch 100 teilbar, nicht durch 400:

((1[1345789])|(2[1235679]))00

Teilbar durch 4 aber nicht durch 100:

[12]\d([2468][048]|[13579][26]|0[48])

Die Schaltjahre:

divisible by 400 or (divisible by 4 and not divisible by 100)
((1[26]|2[048])00)|[12]\d([2468][048]|[13579][26]|0[48])

Nicht teilbar durch 4:

[12]\d([02468][1235679]|[13579][01345789])

Kein Schaltjahr:

Not divisible by 4 OR is divisible by 100 but not by 400
([12]\d([02468][1235679]|[13579][01345789]))|(((1[1345789])|(2[1235679]))00)

Gültiger Monat und Tag außer Februar (MM-DD):

((01|03|05|07|08|10|12)-(0[1-9]|[12]\d|3[01]))|((04|06|09|11)-(0[1-9]|[12]\d|30))
shortened to:
((0[13578]|1[02])-(0[1-9]|[12]\d|3[01]))|((0[469]|11)-(0[1-9]|[12]\d|30))

Februar mit 28 Tagen:

02-(0[1-9]|1\d|2[0-8])

Februar mit 29 Tagen:

02-(0[1-9]|[12]\d)

Gültiges Datum:

(leap year followed by (valid month-day-excluding-february OR 29-day-february)) 
OR
(non leap year followed by (valid month-day-excluding-february OR 28-day-february))

((((1[26]|2[048])00)|[12]\d([2468][048]|[13579][26]|0[48]))-((((0[13578]|1[02])-(0[1-9]|[12]\d|3[01]))|((0[469]|11)-(0[1-9]|[12]\d|30)))|(02-(0[1-9]|[12]\d))))|((([12]\d([02468][1235679]|[13579][01345789]))|((1[1345789]|2[1235679])00))-((((0[13578]|1[02])-(0[1-9]|[12]\d|3[01]))|((0[469]|11)-(0[1-9]|[12]\d|30)))|(02-(0[1-9]|1\d|2[0-8]))))

Da gibt es also einen Regex für Daten zwischen dem 1. Januar 1000 und dem 31. Dezember 2999 im Format JJJJ-MM-DD.

Ich vermute, es kann etwas verkürzt werden, aber das überlasse ich jemand anderem.

Das wird allen gültigen Terminen entsprechen. Wenn Sie möchten, dass es nur gültig ist, wenn es nur ein Datum und nichts anderes enthält, verpacken Sie es wie folgt in ^( )$:

^(((((1[26]|2[048])00)|[12]\d([2468][048]|[13579][26]|0[48]))-((((0[13578]|1[02])-(0[1-9]|[12]\d|3[01]))|((0[469]|11)-(0[1-9]|[12]\d|30)))|(02-(0[1-9]|[12]\d))))|((([12]\d([02468][1235679]|[13579][01345789]))|((1[1345789]|2[1235679])00))-((((0[13578]|1[02])-(0[1-9]|[12]\d|3[01]))|((0[469]|11)-(0[1-9]|[12]\d|30)))|(02-(0[1-9]|1\d|2[0-8])))))$

Wenn Sie es für eine optionale Datumseingabe wünschen (dh es kann ein leeres oder ein gültiges Datum sein), fügen Sie am Anfang ^$| hinzu, wie folgt:

^$|^(((((1[26]|2[048])00)|[12]\d([2468][048]|[13579][26]|0[48]))-((((0[13578]|1[02])-(0[1-9]|[12]\d|3[01]))|((0[469]|11)-(0[1-9]|[12]\d|30)))|(02-(0[1-9]|[12]\d))))|((([12]\d([02468][1235679]|[13579][01345789]))|((1[1345789]|2[1235679])00))-((((0[13578]|1[02])-(0[1-9]|[12]\d|3[01]))|((0[469]|11)-(0[1-9]|[12]\d|30)))|(02-(0[1-9]|1\d|2[0-8])))))$
33
Graham

Sie können es so machen:

if (preg_match("/\d{4}\-\d{2}-\d{2}/", $date)) {
    echo 'true';
} else {
    echo 'false';
}

aber du solltest besser diesen verwenden:

$date = DateTime::createFromFormat('Y-m-d', $date);
if ($date) {
    echo $date -> format('Y-m-d');
}

in diesem Fall erhalten Sie ein Objekt, das einfacher zu verwenden ist als nur Strings.

12
k102

Sie können preg_match mit einer checkdate-PHP-Funktion verwenden

$date  = "2012-10-05";
$split = array();
if (preg_match ("/^([0-9]{4})-([0-9]{2})-([0-9]{2})$/", $date, $split))
{
    return checkdate($split[2], $split[3], $split[1]);
}

return false;
7
Jonathan Muller

Ich weiß, dass dies eine alte Frage ist. Aber ich denke, ich habe eine gute Lösung.

$date = "2016-02-21";
$format = "Y-m-d";

if(date($format, strtotime($date)) == date($date)) {
    echo "true";
} else {
    echo "false";
}

Du kannst es versuchen. Wenn Sie das Datum auf 21.02.2016 ändern, ist das Echo falsch. Wenn Sie das Format danach in d.m.Y ändern, ist das Echo wahr.

Mit diesem einfachen Code sollten Sie in der Lage sein zu prüfen, welches Datumsformat verwendet wird, ohne dass es vom regulären Ausdruck geprüft wird.

Vielleicht gibt es eine Person, die es in jedem Fall testen wird. Ich glaube aber, dass meine Idee allgemein gültig ist. Für mich erscheint es logisch.

6
Micha93

preg_match benötigt ein/oder ein anderes Zeichen als Trennzeichen.

preg_match("/^[0-9]{4}-[0-1][0-9]-[0-3][0-9]$/",$date)

sie sollten auch die Gültigkeit dieses Datums überprüfen, um nicht mit 9999-19-38 zu enden

bool checkdate ( int $month , int $day , int $year )
4
marianboda

sie können verwenden 

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

$date="2012-09-12";    
echo validateDate($date, 'Y-m-d'); // true or false
3
jack

YYYY-MM-DD Datum in einer Zeile prüfen und validieren

function isValidDate($date) {
    return preg_match("/^(\d{4})-(\d{1,2})-(\d{1,2})$/", $date, $m)
        ? checkdate(intval($m[2]), intval($m[3]), intval($m[1]))
        : false;
}

Die Ausgabe wird sein:

var_dump(isValidDate("2018-01-01")); // bool(true)
var_dump(isValidDate("2018-1-1"));   // bool(true)
var_dump(isValidDate("2018-02-28")); // bool(true)
var_dump(isValidDate("2018-02-30")); // bool(false)

Tag und Monat ohne führende Null sind erlaubt. Wenn Sie dies nicht zulassen möchten, sollte der reguläre Ausdruck folgendermaßen lauten:

"/^(\d{4})-(\d{2})-(\d{2})$/"
1

Dies sollte Ihnen sagen, ob das Format gültig ist und ob das Eingabedatum gültig ist.

    $datein = '2012-11-0';

    if(preg_match('/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/', $datein)){
        echo 'good';
    }else{
        echo 'no good';
    }
1
Kenzo

Wenn dies hilfreich ist, finden Sie hier einen Regex für das Format j-n-Y (das Jahr muss größer als 2018 sein):

if (preg_match('/^([1-9]|[1-2][0-9]|[3][0-1])\-([1-9]|[1][0-2])\-(?:20)([1][8-9]|[2-9][0-9])$/', $date)) {
   // Do stuff
}
1
Filip

Du könntest es auch so machen:

if (DateTime::createFromFormat('Y-m-d', $date)->format('Y-m-d') === $date) {

    // date is correctly formatted and valid, execute some code

}

Dies überprüft nicht nur das Format, sondern auch die Gültigkeit des Datums selbst, da DateTime nur gültige Datumsangaben erstellt, und dies muss mit der Eingabe übereinstimmen.

1
kasimir

Wenn Sie diesem Datumstyp entsprechen möchten, verwenden Sie Folgendes:

preg_match("~^\d{4}-\d{2}-\d{2}$~", $date)
1
ujovlado

Um mit Datumsangaben in PHP arbeiten zu können, sollten Sie dem PHP-Standard folgen, damit der angegebene Regex sicherstellen kann, dass Sie ein gültiges Datum haben, das mit PHP funktionieren kann.

    preg_match("/^([0-9]{4})-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/",$date)
0
Pratik Soni

Format 1: $ format1 = "2012-12-31";

Format 2: $ format2 = "31-12-2012";

if (preg_match("/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/",$format1)) {
    return true;
} else {
    return false;
}

if (preg_match("/^(0[1-9]|[1-2][0-9]|3[0-1])-(0[1-9]|1[0-2])-[0-9]{4}$/",$format2)) {
    return true;
} else {
    return false;
}
0
Hasib Kamal

Von Laravel 5.7 und Datumsformat d. H .: 31.12.2013

function checkDateFormat(string $date): bool
{
    return preg_match("/^(0[1-9]|1[0-2])\/(0[1-9]|[1-2][0-9]|3[0-1])\/[0-9]{4}$/", $date);
}
0
Mexidense

Es hängt alles davon ab, wie streng diese Funktion sein soll. Wenn Sie beispielsweise keine Monate über 12 und Tage über 31 einplanen möchten (dies würde, abhängig von dem Monat, das Schreiben von Datumslogik erfordern), kann ziemlich kompliziert werden:

function checkDate($date)
{
  $regex = '/^' . 
    '(' .

    // Allows years 0000-9999
    '(?:[0-9]{4})' .
    '\-' .

    // Allows 01-12
    '(?:' .
    '(?:01)|(?:02)|(?:03)|(?:04)|(?:05)|(?:06)|(?:07)|(?:08)|(?:09)|(?:10)|' .
    '(?:11)|(?:12)' .
    ')' .
    '\-' .

    // Allows 01-31
    '(?:' .
    '(?:01)|(?:02)|(?:03)|(?:04)|(?:05)|(?:06)|(?:07)|(?:08)|(?:09)|(?:10)|' .
    '(?:11)|(?:12)|(?:13)|(?:14)|(?:15)|(?:16)|(?:17)|(?:18)|(?:19)|(?:20)|' .
    '(?:21)|(?:22)|(?:23)|(?:24)|(?:25)|(?:26)|(?:27)|(?:28)|(?:29)|(?:30)|' .
    '(?:31)' .
    ')' .

    '$/';

  if ( preg_match($regex, $date) ) {
    return true;
  }

  return false;
}

$result = checkDate('2012-09-12');

Persönlich würde ich einfach gehen: /^([0-9]{4}\-([0-9]{2}\-[0-9]{2})$/

0
Ariaan

[Wenn Sie Symfony 4.1.2 verwenden, versuchen Sie Folgendes] [1]

  $validDate = explode("-",$request->get('date'));
        if (checkdate(filter_var($validDate[1],FILTER_SANITIZE_NUMBER_INT),filter_var($validDate[0],FILTER_SANITIZE_NUMBER_INT),filter_var($validDate[2],FILTER_SANITIZE_NUMBER_INT))){
            $date = date_create(filter_var($request->get('date'),FILTER_SANITIZE_SPECIAL_CHARS));
        }else{
            return $this->redirectToRoute('YOUR_ROUTE');
        }
0
DIDIT B

Diese Methode kann nützlich sein, um das Datum in PHP zu überprüfen. Die derzeitige Methode ist für das Format MM/TT/JJJJ. Sie müssen die Parameterfolge in checkdate entsprechend Ihrem Format und Trennzeichen in explode aktualisieren.

    function isValidDate($dt)
    {
        $dtArr = explode('/', $dt);
        if (!empty($dtArr[0]) && !empty($dtArr[1]) && !empty($dtArr[2])) {
            return checkdate((int) $dtArr[0], (int) $dtArr[1], (int) $dtArr[2]);
        } else {
            return false;
        }
    }
0
Amit Garg