Ankündigung

Einklappen
Keine Ankündigung bisher.

[Erledigt] Datum - Rangeprüfung in Formatierung oder Validierung?

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • [Erledigt] Datum - Rangeprüfung in Formatierung oder Validierung?

    Ich möchte es dem User ermöglichen "einfache" Datumseingaben zu machen.

    So der grundsätziche Plan:

    Code:
    // Annahme heute ist 03.07.2012
        1          -> 01.07.2012
        01         -> 01.07.2012
        11         -> 11.07.2012
        111        -> 11.01.2012
        1101       -> 11.01.2012
        1.1.       -> 01.01.2012
        1.12.      -> 01.12.2012
        110112     -> 11.01.2012
    Dazu Folgende Funktion weiter unten. Frage dazu: Ist es "richtig" für die Rangeprüfung noch eine eigene Funktion zu machen?

    Speziell ob bei zB diesen Werten nicht schon die FormatDateDE-Funktion zuschlagen sollte, oder ist das dann schon zu viel Validierung? Dieses Datum ist ja gültig aber nicht erwünscht -> dh schon Fall für die Format-Funktion ?? Die Validierung sagt korrekterweise true. Wo fange ich das am besten ab?
    Code:
    Input:    15113
    Formated: 15.11.3
    bool(true)
    Dieses Datum hingegen ist ungültig . Klarer Fall für die Validierung, die sagt hier auch false
    Code:
    Input:    1122
    Formated: 11.22.2012
    bool(false)
    Derzeitige Funkionen
    PHP-Code:
    <?php

    error_reporting
    (-1);
    date_default_timezone_set('Europe/Berlin');

    function 
    formatDateDE($sDate) {
        
    $sDate trim($sDate);
        
    $dateLen strlen($sDate);
        if (
    $dateLen or $dateLen 10) return false;
        
    // wenn bindestrich enthalten, wert genau so wieder zurückgeben
        
    if (strpos($sDate"-") !== false) return $sDate;
        
    $curMonth date("m"$_SERVER['REQUEST_TIME']); // zB 07
        
    $curYear date("Y"$_SERVER['REQUEST_TIME']); // zB 2012
        
        
    if (strpos($sDate".") !== false) {
            
    $aParts explode("."$sDate);
            
    // tag
            
    $day $aParts[0];
            
    // monat
            
    !empty($aParts[1]) ? $month $aParts[1] : $month $curMonth;
            
    // jahr
            
    !empty($aParts[2]) ? $year $aParts[2] : $year $curYear;

        } else {
            
    // kein Punkt zB 0307 oder 151012
            // tag
            
    $day substr($sDate02);
            
    $day str_pad($day2'0'STR_PAD_LEFT);
            
    // monat
            
    $month substr($sDate22);
            if (!
    $month$month $curMonth;
            
    // jahr
            
    $year substr($sDate4);
            if (!
    $year$year $curYear;
        }

        
    // allgemeine formatierungen noch
        
    $month str_pad($month2'0'STR_PAD_LEFT);        
        if (
    strlen($year) == 2$year substr($curYear02).$year;
        
        return 
    $day.".".$month.".".$year;
    }


    function 
    isValidDate($str_date) {
        
    $aDateParts explode("."$str_date);
        if (
    count($aDateParts) != 3) return false;
        return 
    strtotime($str_date) && checkdate($aDateParts[1], $aDateParts[0], $aDateParts[2]);
    }


    // ---- Testcase ------------

    $aDates = array(
        
    "1""12""112""012""102""1111""1122""15113""151113",
        
    "1.12.""01.12.""10-11-12"
    );

    foreach (
    $aDates as $date) {
        echo 
    "Input:    "$date ."\n";
        echo 
    "Formated: " formatDateDE($date). "\n";
        
    var_dump(isValidDate(formatDateDE($date)));
        echo 
    "--------------------\n";
    }


    ?>
    Ausgabe:

    Code:
    Input:    1
    Formated: 01.07.2012
    bool(true)
    --------------------
    Input:    12
    Formated: 12.07.2012
    bool(true)
    --------------------
    Input:    112
    Formated: 11.02.2012
    bool(true)
    --------------------
    Input:    012
    Formated: 01.02.2012
    bool(true)
    --------------------
    Input:    102
    Formated: 10.02.2012
    bool(true)
    --------------------
    Input:    1111
    Formated: 11.11.2012
    bool(true)
    --------------------
    Input:    1122
    Formated: 11.22.2012
    bool(false)
    --------------------
    Input:    15113
    Formated: 15.11.3
    bool(true)
    --------------------
    Input:    151113
    Formated: 15.11.2013
    bool(true)
    --------------------
    Input:    1.12.
    Formated: 1.12.2012
    bool(true)
    --------------------
    Input:    01.12.
    Formated: 01.12.2012
    bool(true)
    --------------------
    Input:    10-11-12
    Formated: 10-11-12
    bool(false)
    --------------------
    The string "()()" is not palindrom but the String "())(" is.

    Debugging: Finde DEINE Fehler selbst! | Gegen Probleme beim E-Mail-Versand | Sicheres Passwort-Hashing | Includes niemals ohne __DIR__
    PHP.de Wissenssammlung | Kein Support per PN

  • #2
    Hab gestern nochmal drüber nachgedacht, ich werd das Zeugs in eine Klasse packen und dann noch eine Methode erstellen, wo man die erlaubte (Jahres-)DateRange vorgibt. Wenns nötig ist kann ich später ja noch einbauen, daß man die per Parameter ausschalten oder cusimozen kann, quasi so in der Art..

    PHP-Code:
    $oDateCheck = new DateChecker();
    $oDateCheck ->setAllowedRange(1900,2200); // optional 
    // oder 
    $oDateCheck ->setAllowedRange(false);     // deaktiviert
    $oDateCheck ->setOutputFormat("d.m.Y");
    // gibt dann normalisiertes Datum zurück oder false wenn irgendwas nicht passt.
    $dateok $oDateCheck ->check($sDate); 
    LG
    The string "()()" is not palindrom but the String "())(" is.

    Debugging: Finde DEINE Fehler selbst! | Gegen Probleme beim E-Mail-Versand | Sicheres Passwort-Hashing | Includes niemals ohne __DIR__
    PHP.de Wissenssammlung | Kein Support per PN

    Kommentar


    • #3
      Hi,

      interessehalber: warum nimmst Du nicht eine einfache & gängige Methode wie z.B. http://www.kelvinluck.com/assets/jqu...icker/v2/demo/

      mfg Wolf29
      while (!asleep()) sheep++;

      Unterschätze nie jemanden der einen Schritt zurück geht! Er könnte Anlauf nehmen.

      Kommentar


      • #4
        Ich möchte es dem User ermöglichen "einfache" Datumseingaben zu machen.
        Soll heissen: Weil ich damit keine Tastatureingaben machen kann, und ich finde das man 1002 halt schneller eingegben hat als den Kalender "auf" zu klicken und dann darin sich durchzuklicken bis man bei Februar ist etc..

        Hab über js schon nachgedacht das mit JS zu lösen, aber ich habs lieber am Server, weil man JS ja immernoch ausschalten kann. Abgesehen davon brauch ich es für die sql-Abfrage sowieso als 2012-06-04 und im Feld ist es als 04.06.2012, also muss ich das vom Form sowieso per PHP angreifen.

        Ausserdem bastle/spiel' ich gerne herum wenn ich Zeit hab
        The string "()()" is not palindrom but the String "())(" is.

        Debugging: Finde DEINE Fehler selbst! | Gegen Probleme beim E-Mail-Versand | Sicheres Passwort-Hashing | Includes niemals ohne __DIR__
        PHP.de Wissenssammlung | Kein Support per PN

        Kommentar


        • #5
          Hi,

          Soll heissen: Weil ich damit keine Tastatureingaben machen kann, und ich finde das man 1002 halt schneller eingegben hat als den Kalender "auf" zu klicken und dann darin sich durchzuklicken bis man bei Februar ist etc..
          ...das ist schon richtig, aber viele sind diese aufklabbaren Kalender gewohnt, z.B. wenn man irgendwas bucht etc.!

          Hab über js schon nachgedacht das mit JS zu lösen, aber ich habs lieber am Server, weil man JS ja immernoch ausschalten kann.
          stimmt. Man kann alternativ eine Lösung anbieten (z.B. mit PHP & Html), oder einen Hinweis ausgeben, dass die Funktionalität eingeschränkt ist von der Webseite, wenn JavaScript ausgeschaltet ist.

          Abgesehen davon brauch ich es für die sql-Abfrage sowieso als 2012-06-04 und im Feld ist es als 04.06.2012, also muss ich das vom Form sowieso per PHP angreifen.
          ...das ist ja kein Problem, wie du das Format bekommst für dein SQL Statement.

          Ausserdem bastle/spiel' ich gerne herum wenn ich Zeit hab
          Ok, das einzige für mich schlagende Argument

          mfg Wolf29
          while (!asleep()) sheep++;

          Unterschätze nie jemanden der einen Schritt zurück geht! Er könnte Anlauf nehmen.

          Kommentar


          • #6
            Datumseingaben wie 1002 oder 2012 als gütige Eingaben zu akzeptieren empfinde ich als ungewöhnlich, da nicht eindeutig. Die Eingabe 112 z.B. 11.2 oder 1.12 ?
            10.2 und 20.12 um das aktuelle Jahr zu ergänzen, das würde ich noch akzeptieren.

            Kommentar


            • #7
              @wolf. Hab da wohl relevantes nicht erwähnt

              - Es gibt derzeit schon einen DatePicker

              - Der erzeugt derzeit noch 2012-06-04 Werte beim Klick auf ein Datum, das werde ich jedenfalls umstellen das 04.06.2012 erzeugt wird (das umwandeln für mysql ist nicht das Problem).

              - Ich wollte eben zusätzlich dann noch die Möglichkeit schaffen, quasi als Goodie die Eingabe von 15 (für 15.07.2012) oder 1510 (für 15.10.2012) etc.. anzugeben. Und da ich Zeit und Laute hatte wollt ich mir das geben.
              The string "()()" is not palindrom but the String "())(" is.

              Debugging: Finde DEINE Fehler selbst! | Gegen Probleme beim E-Mail-Versand | Sicheres Passwort-Hashing | Includes niemals ohne __DIR__
              PHP.de Wissenssammlung | Kein Support per PN

              Kommentar


              • #8
                Zitat von jspit Beitrag anzeigen
                Datumseingaben wie 1002 oder 2012 als gütige Eingaben zu akzeptieren empfinde ich als ungewöhnlich, da nicht eindeutig. Die Eingabe 112 z.B. 11.2 oder 1.12 ?
                10.2 und 20.12 um das aktuelle Jahr zu ergänzen, das würde ich noch akzeptieren.
                112 wäre 11.2. - die ersten beiden sind immer Tage. Natürlich könnte ich auch dreistelliges nicht erlauben, also nur 1002 1512 0101 etc.. Das ist ja nur wie man es für sich definiert.

                Ach.. ich bin mir grad nicht mehr sicher ob es doch eine praktische Sache wäre..

                Ev sollt ich die "Umwandlung" nur noch auf JS-Ebene machen zB beim Feldwechsel wird das dann von JS umgewandelt vor dem submit.. Und php seitig gibts dann keine Sondergeschichte mehr.

                LG
                The string "()()" is not palindrom but the String "())(" is.

                Debugging: Finde DEINE Fehler selbst! | Gegen Probleme beim E-Mail-Versand | Sicheres Passwort-Hashing | Includes niemals ohne __DIR__
                PHP.de Wissenssammlung | Kein Support per PN

                Kommentar


                • #9
                  Abgesehen davon brauch ich es für die sql-Abfrage sowieso als 2012-06-04 und im Feld ist es als 04.06.2012, also muss ich das vom Form sowieso per PHP angreifen.
                  Das ist so nicht richtig. Du kannst dem DatePicker über eine Option das Datumsformat mitgeben, so daß er automatisch Deine SQL-korrekte Formatierung hat.
                  Aber das nur am Rande...
                  Competence-Center -> Enjoy the Informatrix
                  PHProcks!Einsteiger freundliche TutorialsPreComposed Packages

                  Kommentar


                  • #10
                    Zitat von Arne Drews Beitrag anzeigen
                    Du kannst dem DatePicker über eine Option das Datumsformat mitgeben, so daß er automatisch Deine SQL-korrekte Formatierung hat.
                    Ich zeige alle Datum auf der Seite immer als 04.07.2012 an. Wenn der Datepicker nach auswahl das sql Format 2012-07-04 ausgibt find ich das nicht schön - daher .. Picker gibt auch 04.07.2012 aus und bevor das in die query geht wird es gewandelt. Ist aber gar keine Tragik.
                    The string "()()" is not palindrom but the String "())(" is.

                    Debugging: Finde DEINE Fehler selbst! | Gegen Probleme beim E-Mail-Versand | Sicheres Passwort-Hashing | Includes niemals ohne __DIR__
                    PHP.de Wissenssammlung | Kein Support per PN

                    Kommentar


                    • #11
                      Jo, hast Du oben auch schon erwähnt... Hatte ich überlesen...
                      Competence-Center -> Enjoy the Informatrix
                      PHProcks!Einsteiger freundliche TutorialsPreComposed Packages

                      Kommentar


                      • #12
                        Frage am Rande... Irgendwie begreif ich das Thema mit den Exeptions bzw. hier im Fehlerfall nicht ganz.

                        Beispiel aus dem Handbuch - mit absitlich falschem Datum.

                        PHP-Code:
                        <?php

                        $date 
                        date_create('2000-01-32');
                        if (!
                        $date) {
                            
                        $e date_get_last_errors();
                            foreach (
                        $e['errors'] as $error) {
                                echo 
                        "$error<br>\n";
                            }
                            exit(
                        1);
                        }

                        echo 
                        date_format($date'Y-m-d');

                        ?>

                        Da wird in jedem Fall schon vorher eine Warnung ausgegeben. Da brauch ich dann "hinten" nach nicht viel prüfen, oder muss man hier genötigter Weise dann doch
                        PHP-Code:
                        $date = @date_create('2000-01-32'); 
                        machen. Oder zielt es einfach darauf ab das im Produktivsystem eh keine Warungen ausgegben werden sollen? Gilt ebenso für das OO Beispiel zu dem DateTime::__construct() hier mit den Exeptions. Sollte da nicht einfach false oder null zurückkommen? Finde das irgendwie seltsam.

                        ----

                        Weiters ist mir aufgefallen führt sowohl bei strtotime als auch bei date_create von dem 29.02.2011 (kein Schaltjahr) bei beiden Varianten immer den 01.03. ausgibt statt false oder einem Fehler. Kann man das umgehen?

                        PHP-Code:
                        echo date_create('29.02.2011')->format('Y-m-d');
                        // 2011-03-01 
                        Danke!
                        The string "()()" is not palindrom but the String "())(" is.

                        Debugging: Finde DEINE Fehler selbst! | Gegen Probleme beim E-Mail-Versand | Sicheres Passwort-Hashing | Includes niemals ohne __DIR__
                        PHP.de Wissenssammlung | Kein Support per PN

                        Kommentar


                        • #13
                          Dein zweites Problem betrifft nicht nur das Schaltjahr:
                          PHP-Code:
                          echo date_create('31.02.2011')->format('Y-m-d');  //2011-03-03
                          echo date_create('31.04.2012')->format('Y-m-d');  //2012-05-01 

                          Kommentar


                          • #14
                            Nicht gut. Dh es muss noch vor der Formatumwandlung noch eine Prüfung (glaub wir hatten damals strototime() && checkdate() ) stattfinden. Gut das muss ich mir noch merken.

                            Danke!
                            The string "()()" is not palindrom but the String "())(" is.

                            Debugging: Finde DEINE Fehler selbst! | Gegen Probleme beim E-Mail-Versand | Sicheres Passwort-Hashing | Includes niemals ohne __DIR__
                            PHP.de Wissenssammlung | Kein Support per PN

                            Kommentar


                            • #15
                              Zitat von jspit Beitrag anzeigen
                              Dein zweites Problem betrifft nicht nur das Schaltjahr:
                              PHP-Code:
                              echo date_create('31.02.2011')->format('Y-m-d');  //2011-03-03
                              echo date_create('31.04.2012')->format('Y-m-d');  //2012-05-01 
                              So funktioniert es soweit ganz solide:

                              PHP-Code:
                              function DateCheckNormalizeISO($sDate) { 
                                  
                              $aDateParts explode("."$sDate); 
                                  if (
                              count($aDateParts) != 3) return false
                                  
                              $oDate date_create($sDate);
                                  if (
                              $oDate && checkdate($aDateParts[1], $aDateParts[0], $aDateParts[2])) { 
                                      return 
                              $oDate->format('Y-m-d'); 
                                  } else { 
                                      return 
                              false
                                  } 



                              error_reporting(-1);
                              date_default_timezone_set('Europe/Berlin');

                              var_dump(DateCheckNormalizeISO("29.02.2011")); // false
                              var_dump(DateCheckNormalizeISO("31.04.2011")); // false
                              var_dump(DateCheckNormalizeISO("foobar"));     // false
                              var_dump(DateCheckNormalizeISO("29.02.2012")); // 2012-02-29
                              var_dump(DateCheckNormalizeISO("29.02.12"));   // 2012-02-29
                              var_dump(DateCheckNormalizeISO("29.2.12"));    // 2012-02-29 
                              The string "()()" is not palindrom but the String "())(" is.

                              Debugging: Finde DEINE Fehler selbst! | Gegen Probleme beim E-Mail-Versand | Sicheres Passwort-Hashing | Includes niemals ohne __DIR__
                              PHP.de Wissenssammlung | Kein Support per PN

                              Kommentar

                              Lädt...
                              X