Datum Überprüfen auf ECHTHEIT
Kasandra
- php
0 Georg0 Bobby0 suit0 Gunnar Bittersmann
Ich möchte ein Datum auf Korrektheit überprüfen, mit diesem Code geht es:
list ($y, $m, $d) = explode ( '-', ‘2011-1-2’ );
if ( ! checkdate ( $m, $d, $y ) )
{
print ( 'Datum ist ungültig!' );
}
else
{
print ( 'Datum ist gültig!' );
}
Doch wenn das Datum in einem falschen Format kommt, Beispiel: 2011c1-2 statt 2011-1-2
Bekomme ich folgende Fehlermeldung „Notice: Undefined offset“ bei der ersten Zeile, wie kann ich diese Fehlermeldung abfangen, bzw. korrekt verfahren…
Weiter kommt die Korrekte Meldung „Datum ist ungültig!“
Danke
Kasi
Doch wenn das Datum in einem falschen Format kommt, Beispiel: 2011c1-2 statt 2011-1-2
Bekomme ich folgende Fehlermeldung „Notice: Undefined offset“ bei der ersten Zeile, wie kann ich diese Fehlermeldung abfangen, bzw. korrekt verfahren…
Stichwort Regular Expressions
@@Georg:
nuqneH
Stichwort Regular Expressions
Ähm ja, das geht sogar. Und nein, das sollte man auf keinen Fall tun.
Qapla'
Hi!
Stichwort Regular Expressions
Ähm ja, das geht sogar. Und nein, das sollte man auf keinen Fall tun.
Nunja, man kann ja einen Regulären Ausdruck für die Findung der Bestandteile verwenden und diese dann mit checkdate() prüfen.
Lo!
Ähm ja, das geht sogar. Und nein, das sollte man auf keinen Fall tun.
Nunja, man kann ja einen Regulären Ausdruck für die Findung der Bestandteile verwenden und diese dann mit checkdate() prüfen.
Und nach welchem Muster soll der die Bestandteile finden? Das wird dann schon wieder kompliziert.
Ein einfacher \d{4}-\d{1,2}-\d{1,2} scheitert bereits, weil es ein Datum wie z.B. 2011-13-13 nicht gibt.
@@suit:
nuqneH
Nunja, man kann ja einen Regulären Ausdruck für die Findung der Bestandteile verwenden und diese dann mit checkdate() prüfen.
Ein einfacher \d{4}-\d{1,2}-\d{1,2} scheitert bereits, weil es ein Datum wie z.B. 2011-13-13 nicht gibt.
„[…] und diese [Bestandteile] dann mit checkdate() prüfen.“
Qapla'
@@suit:
nuqneH
Nunja, man kann ja einen Regulären Ausdruck für die Findung der Bestandteile verwenden und diese dann mit checkdate() prüfen.
Ein einfacher \d{4}-\d{1,2}-\d{1,2} scheitert bereits, weil es ein Datum wie z.B. 2011-13-13 nicht gibt.
„[…] und diese [Bestandteile] dann mit checkdate() prüfen.“
Ja, aber damit kommt eben Mist zustande wenn dann ein 2001-0101 daherkommt - was bei der dafür gedachten Funktion schon abgefangen wird und einwandfrei hinhaut:
<?php
$foo = array(
'2011-01-02',
'2011-1-2',
'2011c1-2'
);
function bar($str) {
if(!$out = strptime ($str , '%Y-%m-%d')) {
echo "$str: fail\n";
} else {
echo "$str: \n";
print_r($out);
}
}
echo '<pre>';
bar($foo[0]);
bar($foo[1]);
bar($foo[2]);
?>
Hi!
Ein einfacher \d{4}-\d{1,2}-\d{1,2} scheitert bereits, weil es ein Datum wie z.B. 2011-13-13 nicht gibt.
„[…] und diese [Bestandteile] dann mit checkdate() prüfen.“
Ja, aber damit kommt eben Mist zustande wenn dann ein 2001-0101 daherkommt - was bei der dafür gedachten Funktion schon abgefangen wird und einwandfrei hinhaut:
Jetzt wechselst du aber schnell das Thema. Geht es dir nun um eine Plausibiltätsprüfung der Bestandteile? Da kommst du mit strptime() allein auch nicht weiter. Oder geht es dir um das Extrahieren der Bestandteile bei falscher/unvorhergesehener Schreibweise? Man muss da auch einfach mal aufgeben können. Wenn der Anwender Mist eingibt, muss er sich nicht wundern, wenn der nicht doch noch irgendwie interpretiert sondern abgelehnt wird. Bei blöden Schreibweisen scheitern alle drei bisher genannten Lösungen (explode(), strptime(), RegExp) - die einen früher, die anderen später.
Lo!
Jetzt wechselst du aber schnell das Thema.
Nein :)
Geht es dir nun um eine Plausibiltätsprüfung der Bestandteile?
Nein, dafür verwendet der OP ja checkdate() - wir reden hier aber immer noch um den Teil "String in Datum überführen".
Bei blöden Schreibweisen scheitern alle drei bisher genannten Lösungen (explode(), strptime(), RegExp) - die einen früher, die anderen später.
Ja, genau aus dem Grund schlug ich vor, dass man einen Datepicker anbietet (HTML5 kann das ja schon nativ) um eine Fehleingabe des Benutzers zu minimieren.
Und genau das Datumsformat welches der Datepicker liefert, zerlegt man PHP-Seitig dann nach demselben Muster mit strptime() - das liefert schon eine gewisse Fehlerkorrekturroutine mit, falls es jemand handisch eingibt und zumindest versucht sich daran zu halten. Wenn jemand völlig Blödsinn eingibt, hilft die beste Routine ohnehin nichts.
@@dedlfix:
nuqneH
Nunja, man kann ja einen Regulären Ausdruck für die Findung der Bestandteile verwenden
Man könnte. Sollte man?
Qapla'
Hi!
Nunja, man kann ja einen Regulären Ausdruck für die Findung der Bestandteile verwenden
Man könnte. Sollte man?
Ja, weil das Auseinandernehmen mit Stringfunktionen aufwendiger ist, wenn man sich nicht auf ein einziges Format (genauer gesagt: Trennzeichen zwischen den Bestandteilen) beschränken will.
Eingaben nach dem Format t.m.j kann man mit explode() trennen lassen, sollte dann aber die Bestandteile in einem Array fangen und dieses auf die Länge 3 testen. Die Verwendung von strptime() ist nicht wirklich besser, weil auch damit ein checkdate() notwendig ist und das Trennzeichen fest vorgegeben ist.
Die Beschränkung auf den Punkt bringt aber eine eingeschränkte Benutzerfreundlichkeit mit. Wenn man <del>Kein Martin</del><ins>Schnelltipper auf dem Ziffernblock</ins> ist, hemmt es die Geschwindigkeit, wenn man für den Punkt rüber zum Haupttastaturfeld wechseln muss und wieder zurück. Auch das Hinzunehmen der zweiten Hand ist keine ideale Lösung. Besser wäre es, wenn man irgendein Trennzeichen verwenden kann. Und dafür macht sich ein Regexp besser als ein explode() oder strptime() oder selbst geschriebener Parser mit einfachen Stringfunktionen. Die Reihenfolge der Bestandteile muss allerdings weiterhin vorgegeben sein, um Aufwand und Fehlerquote beim Erraten nicht zu hoch werden zu lassen. (Vorstehende Ausführungen beziehen sich auf eine einzelne Anordnungsweise. Für Anwendungen, die mehrere Anordnungen unterstützen sollen, muss man sich noch entsprechenden Aufwand fürs Umsortieren einbauen, aber das kann einem auch keine einzelne RegExp-Lösung abnehmen.)
Lo!
@@dedlfix:
nuqneH
Ja, weil das Auseinandernehmen mit Stringfunktionen aufwendiger ist, wenn man sich nicht auf ein einziges Format (genauer gesagt: Trennzeichen zwischen den Bestandteilen) beschränken will.
OK. Hm, dann kann man ja das Datum auch japanisch eingeben: 2011年6月9日 ;-)
Die Beschränkung auf den Punkt bringt aber eine eingeschränkte Benutzerfreundlichkeit mit. Wenn man <del>Kein Martin</del><ins>Schnelltipper auf dem Ziffernblock</ins> ist […]
*g*
[…] hemmt es die Geschwindigkeit, wenn man für den Punkt rüber zum Haupttastaturfeld wechseln muss und wieder zurück.
Ich weiß nicht, was du für einen Ziffernblock hast, aber ich habe einen mit [-]. ;-)
Qapla'
@@Gunnar Bittersmann:
nuqneH
OK. Hm, dann kann man ja das Datum auch japanisch eingeben: 2011年6月9日 ;-)
Äh, die Rechnung ohne den Wirt (PHP) gemacht?
Man muss natürlich Stringfunktionen einsetzten, die diesen Namen verdienen; nicht den nutzlosen Krempel, der auch unter Stringfunktionen aufgelistet ist.
Qapla'
Hi!
Ja, weil das Auseinandernehmen mit Stringfunktionen aufwendiger ist, wenn man sich nicht auf ein einziges Format (genauer gesagt: Trennzeichen zwischen den Bestandteilen) beschränken will.
OK. Hm, dann kann man ja das Datum auch japanisch eingeben: 2011年6月9日 ;-)
Kannst man. Die Frage ist allerdings, was es für Vorteile bringt. Zumindest kann man solche Angaben anderswo kopieren und ins das Feld einfügen. Zu Fuß tippen ist ja wegen des notwendigen IME noch aufwendiger als ein Zeichen der Haupttastatur aufzusuchen.
Ich weiß nicht, was du für einen Ziffernblock hast, aber ich habe einen mit [-]. ;-)
Ich habe nicht immer meine persönlichen Tastaturtreiber dabei.
Lo!
Moin
Doch wenn das Datum in einem falschen Format kommt, Beispiel: 2011c1-2 statt 2011-1-2
Bekomme ich folgende Fehlermeldung „Notice: Undefined offset“ bei der ersten Zeile, wie kann ich diese Fehlermeldung abfangen, bzw. korrekt verfahren…
Is ja klar. list() erwartet 3 Werte. Du lieferst aber nur 2.
Prüf doch den Unix Timestamp ob er 0 oder gültig ist. Dazu wandelst du das übergebene Datum 1:1 mittels strtotime() in einen solchen um.
Gruß Bobby
strptime() ist geeigneter als dein selbst gezimmertes explode.
Allgemein um Fehler zu vermeiden wäre es noch schlauer gleich bei der Eingabe zu verhindern, dass sowas daherkommt.
z.B. mittels einem Datumseingabefeld oder einem JavaScript-Datepicker.
Was ist das übrigens für ein Datumsformat?
2011-1-2 ist nach ISO 8601 übrigens nicht der 2. Jänner 2011 sondern ungültig.
@@Kasandra:
nuqneH
[…] mit diesem Code geht es:
list ($y, $m, $d) = explode ( '-', ‘2011-1-2’ );
▲ ▲
Kann ich nicht glauben.
Qapla'