hotti: Führende Null

hi,

Ein User kriegt bei mir die Chance, ein Datum einzugeben. Der Tag.Monat darf ein- oder zweistellig eingegeben werden, zb. 01.01. oder 1.1.

Im selben Format will ich das wieder ausgeben mit printf(). Gibt es eine Möglichkeit den Platzhalter "%02d" variabel zu machen?

--Hotte

  1. Hi,

    Ein User kriegt bei mir die Chance, ein Datum einzugeben. Der Tag.Monat darf ein- oder zweistellig eingegeben werden, zb. 01.01. oder 1.1.

    Im selben Format will ich das wieder ausgeben

    Warum?
    Vereinheitlichen von Angaben fördert doch im allgemeinen die Übersichtlichkeit.

    mit printf(). Gibt es eine Möglichkeit den Platzhalter "%02d" variabel zu machen?

    Da der erste Parameter nur ein Textstring ist, kannst du in diesem gerne dynamisch einen Platzhalter/eine Formatangabe setzen.

    MfG ChrisB

    --
    Light travels faster than sound - that's why most people appear bright until you hear them speak.
    1. Hi,

      Ein User kriegt bei mir die Chance, ein Datum einzugeben. Der Tag.Monat darf ein- oder zweistellig eingegeben werden, zb. 01.01. oder 1.1.

      Im selben Format will ich das wieder ausgeben

      Warum?

      Tja, ich verrate ja nicht gerne alle meine Tricks, aber weil Du's bist:

      Es geht mir um die Prüfung, ob ein eingegebenes Datum gültig ist. Beispiel:

      User gibt ein:
         "1.1.1999"

      Dieses Datum rechne ich nach einem bestimmten Schema um in einen numerischen Wert und dann zurück. Im Ergebnis habe ich "1.1.1999" was eq zur Eingabe ist (gültig).

      Nun gibt der User jedoch ein:
         "01.01.1999"

      Sofern ich das nicht berücksichtige, dass da führende Nullen im Spiel sind, ist mein String "1.1.1999" nicht derselbe. Daher muss ich bei dieser Art der Prüfung _dasselbe_ Format verwenden.

      Vereinheitlichen von Angaben fördert doch im allgemeinen die Übersichtlichkeit.

      Freilich. Bei IP-Adressen verfahre ich genauso (umrechnen und zurückrechnen), da klappt das prima, weil kein Mensch auf die Idee kommt, statt 192.168.0.1 192.168.000.001 zu schreiben.

      mit printf(). Gibt es eine Möglichkeit den Platzhalter "%02d" variabel zu machen?

      Da der erste Parameter nur ein Textstring ist, kannst du in diesem gerne dynamisch einen Platzhalter/eine Formatangabe setzen.

      Jetzt bist Du dran: Mitm Beispiel.

      Hotte

      1. Hallo Hotti,

        Freilich. Bei IP-Adressen verfahre ich genauso (umrechnen und zurückrechnen), da klappt das prima, weil kein Mensch auf die Idee kommt, statt 192.168.0.1 192.168.000.001 zu schreiben.

        ist Dir bekannt, dass viele heute übliche Anwendungen ganz gewaltig zwischen

        192.168.010.001

        und

        192.168.10.1

        machen, dies zwei verschiedene IP-Adressen sind, und

        192.168.001.009

        sogar ablehnen, während übliche Datumsfunktionen mit führenden Nullen auch im September kein Problem haben?

        Freundliche Grüße

        Vinzenz

        1. Hi mein Lieber Vinzenz,

          ist Dir bekannt, [..] während übliche Datumsfunktionen mit führenden Nullen auch im September kein Problem haben?

          Klar. Um mich rum und hierzulande ist so Einiges üblich. Und führende Nullen gibts auch mehr als genug.

          Viele Grüße,
          Horst

          1. Hallo,

            ist Dir bekannt, [..] während übliche Datumsfunktionen mit führenden Nullen auch im September kein Problem haben?

            Klar.

            und warum vergleichst Du dann Äpfel mit Birnen?

            Freundliche Grüße

            Vinzenz

            1. Hallo,

              ist Dir bekannt, [..] während übliche Datumsfunktionen mit führenden Nullen auch im September kein Problem haben?

              Klar.

              und warum vergleichst Du dann Äpfel mit Birnen?

              Ich hab nicht die geringste Ahnung, wo ich Deine Frage ansiedeln könnte (Bezug, Problembeschreibung). Evntl. hilft Dir die Forumshilfe weiter.

              Horst

              1. Hallo,

                ist Dir bekannt, [..] während übliche Datumsfunktionen mit führenden Nullen auch im September kein Problem haben?

                Klar.

                und warum vergleichst Du dann Äpfel mit Birnen?

                Ich hab nicht die geringste Ahnung, wo ich Deine Frage ansiedeln könnte (Bezug, Problembeschreibung).

                wer lesen kann, ist klar im Vorteil:

                führende Nullen bei Datumsangaben := Äpfel
                führende Nullen bei IP-Adressen   := Birnen

                Wer beides gleich behandelt, macht Fehler.

                Grüße

                Vinzenz

                1. hi,

                  führende Nullen bei Datumsangaben := Äpfel
                  führende Nullen bei IP-Adressen   := Birnen

                  Wer beides gleich behandelt, macht Fehler.

                  Richtig. Deswegen wird ein Programmierer auch bestimmte Regeln festlegen, in welchem Format ein Apfel oder eine Birne einzugeben ist. Wer sich nicht daran hält, fliegt raus. Von wegen sprintf() und "meinten Sie vielleicht '1'" und so. Das Entgegenkommen von wegen dämlicher Benutzereingaben hat Grenzen.

                  Btw., wie sowas mit IP-Adressen funktioniert, kannst Du hier testen.

                  Hinweis: Hier gehts um IP-Adressen. Also kein Datum eingeben :D

                  Hotte

              2. Hi,

                Ich hab nicht die geringste Ahnung, wo ich Deine Frage ansiedeln könnte (Bezug, Problembeschreibung). Evntl. hilft Dir die Forumshilfe weiter.

                Dafür, dass die Qualität deiner Problembeschreibungen in letzter Zeit erheblich zu wünschen übrig lässt, hast du eine ziemlich grosse Klappe.

                MfG ChrisB

                --
                Light travels faster than sound - that's why most people appear bright until you hear them speak.
      2. Hi,

        Nun gibt der User jedoch ein:
           "01.01.1999"

        Du koenntest doch da auch einfach die fuehrenden Nullen rausloeschen?

        mit printf(). Gibt es eine Möglichkeit den Platzhalter "%02d" variabel zu machen?

        Da der erste Parameter nur ein Textstring ist, kannst du in diesem gerne dynamisch einen Platzhalter/eine Formatangabe setzen.

        Jetzt bist Du dran: Mitm Beispiel.

        Zum Beispiel so:

        $formatString = '%0'+$anz+'d';

        mfG,
        steckl

        1. hi,

          Zum Beispiel so:

          $formatString = '%0'+$anz+'d';

          Ach du lieber Himmel, Horst!!!! Ja, der +Op, mensch Kinners.

          Danke!
          Horst Haselhuhn

        2. Jetzt bist Du dran: Mitm Beispiel.

          Zum Beispiel so:

          $formatString = '%0'+$anz+'d';

          Nicht in Perl.

          $formatString = "%0${anz}d";

          Struppi.

      3. weil kein Mensch auf die Idee kommt, ...

        Du hast verloren.

        1. weil kein Mensch auf die Idee kommt, ...

          Du hast verloren.

          ;-)

          Ja, es gibt Tage, da gewinnen die Anderen...

      4. Hi,

        User gibt ein:
           "1.1.1999"

        Dieses Datum rechne ich nach einem bestimmten Schema um in einen numerischen Wert und dann zurück. Im Ergebnis habe ich "1.1.1999" was eq zur Eingabe ist (gültig).

        Nun gibt der User jedoch ein:
           "01.01.1999"

        Sofern ich das nicht berücksichtige, dass da führende Nullen im Spiel sind, ist mein String "1.1.1999" nicht derselbe. Daher muss ich bei dieser Art der Prüfung _dasselbe_ Format verwenden.

        Dann wandle die Eingabe des Nutzers in ein definiertes Format um, und führe den Vergleich anschliessend durch.

        Da der erste Parameter nur ein Textstring ist, kannst du in diesem gerne dynamisch einen Platzhalter/eine Formatangabe setzen.

        Jetzt bist Du dran: Mitm Beispiel.

        Für was?
        Wie man in Perl dynamisch einen String zusammensetzt?

        MfG ChrisB

        --
        Light travels faster than sound - that's why most people appear bright until you hear them speak.
  2. hi,

    s. Thema. Dank Perl gehts ja auch so, dass 01 als Zahl anerkannt wird. Also _Zahlen_ vergleichen (mit dem Zahlenvergleichsoperator) und gut is.

    Alles wird gut,
    Hotte

    --
    Führende Nullen haben hier nichts zu sagen.
    1. s. Thema. Dank Perl gehts ja auch so, dass 01 als Zahl anerkannt wird. Also _Zahlen_ vergleichen (mit dem Zahlenvergleichsoperator) und gut is.

      Aber 01.01.1999 ist keine Zahl? Üblich ist eher, die Zahl in einen Timestamp umzuwandeln und zu vergleichen.

      Struppi.

      1. s. Thema. Dank Perl gehts ja auch so, dass 01 als Zahl anerkannt wird. Also _Zahlen_ vergleichen (mit dem Zahlenvergleichsoperator) und gut is.

        Aber 01.01.1999 ist keine Zahl? Üblich ist eher, die Zahl in einen Timestamp umzuwandeln und zu vergleichen.

        Du meinst, das Datum umzuwandeln. Ja klar, mach ich. Gesplittet ergeben sich

        d = 01
        m = 01
        y = 1999

        und nach Umrechnen und Zurückrechnen (Scaliger) ergeben sich

        dx = 1
        mx = 1
        yx = 1999

        Perl findet, dass d == dx und m == mx und y == yx ist und somit das Datum für OK. Isses ja auch ;-)

        Btw., Deine (übliche) Rechnung über den "Timestamp" ist Sekundengenau. Das brauchst eigentlich nicht, wenns nur um Tage geht. Und bei der Prüfung eines Datums like '35.13.1960' gehts mit Time::Local sowieso schon in die Hose.

        Viele Grüße,
        Horst Haselhuhn

        --
        Wenn der Kommentar nicht zum Code passt, kann auch der Code falsch sein.
        1. Btw., Deine (übliche) Rechnung über den "Timestamp" ist Sekundengenau. Das brauchst eigentlich nicht, wenns nur um Tage geht. Und bei der Prüfung eines Datums like '35.13.1960' gehts mit Time::Local sowieso schon in die Hose.

          Was heißt er geht in die Hose? Du kannst vergleichen, ob dieser Wert gültig ist oder nicht, indem du den Timestamp wieder zurück umwandelst.

          Und ob sekundengenau oder nicht - du vergleichst drei Zahlen, nach der Umwandlung hast du nur eine.

          Struppi.

          1. Btw., Deine (übliche) Rechnung über den "Timestamp" ist Sekundengenau. Das brauchst eigentlich nicht, wenns nur um Tage geht. Und bei der Prüfung eines Datums like '35.13.1960' gehts mit Time::Local sowieso schon in die Hose.

            Was heißt er geht in die Hose? Du kannst vergleichen, ob dieser Wert gültig ist oder nicht, indem du den Timestamp wieder zurück umwandelst.

            Ok, sei sogut und rechne hier mal nur den Timestamp für o.g. Datum '35.13.1960' aus. Und zeig uns bitte auch den PerlCode dazu.

            Hotte
            --

            1. IMHO wäre folgendes sinnig:

              use Date::Calc qw(check_date);
              my $tag = '35';
              my $monat = '13';
              my $jahr = '1960';
              if (check_date($jahr, $monat, $tag)) {
                  print "supi!\n";
              }
              else {
                  print "kaputt!\n";
              }

              1. hi,

                use Date::Calc qw(check_date);

                Wenn verfügbar ;-)

                Btw., check mal das Datum '15.10.1582' mit Date::Calc. Ist das gültig?

                Hotti

                --
                Wenn der Kommentar nicht zum Code passt, kann auch der Code falsch sein.
                1. Btw., check mal das Datum '15.10.1582' mit Date::Calc. Ist das gültig?

                  Ja.

                2. hi,

                  use Date::Calc qw(check_date);

                  Wenn verfügbar ;-)

                  Btw., check mal das Datum '15.10.1582' mit Date::Calc. Ist das gültig?

                  Ähm, ich meinte das Datum 5.10.1582. Date::Calc meint, das wäre ok. Ist es aber nicht. Machn Bug-Report an Steffen Beyer ;-)

                  Hotti

                  --
                  Wenn der Kommentar nicht zum Code passt, kann auch der Code falsch sein.
                  1. Ähm, ich meinte das Datum 5.10.1582. Date::Calc meint, das wäre ok. Ist es aber nicht. Machn Bug-Report an Steffen Beyer ;-)

                    Stimmt wohl, das ist geschichtlich nicht einweindfrei...

                    1. Ähm, ich meinte das Datum 5.10.1582. Date::Calc meint, das wäre ok. Ist es aber nicht. Machn Bug-Report an Steffen Beyer ;-)

                      Stimmt wohl, das ist geschichtlich nicht einweindfrei...

                      Ich könnt'n ja auch selber mal wieder schreiben ;-)

                      Also, nach dem 4.10.1582 kommt der 15.10.1582 (Greg. Kal. Reform). Wenn zum Prüfen, ob das Datum 5.10.1582 korrekt ist, über Scaliger gerechnet wird, ergibt sich die Tagesnummer 2299161. Und die ergibt beim Zurückrechnen den 15.10.1582.

                      Diese Art zu prüfen ist verblüffend einfach, nehmen wir noch ein Datum zum Testen: 29.2.1999. Die Tagesnummer errechnet sich mit Scaliger zu 2451239 und ergibt beim Rückrechnen den 1.3.1999. Ergo kann '29.2.1960' kein gültiges Datum darstellen.

                      Ein Datum 35.13.1960 ist natürlich auch Käse, aber Scaliger ergibt die Tagesnummer 2437335 und der zugehörige Tag fällt korrekt auf den 4.2.1961. Bei einem gültigen Datum hingegen ergibt die Rückrechnung stets exact dmy.

                      --Hotti

                3. Btw., check mal das Datum '15.10.1582' mit Date::Calc. Ist das gültig?

                  Ich interessiere mich nicht für geschichtliche Daten. Dafür gibt es ja dein Modul.

                  Ich kann mir aber keine Anwendung vorstellen, wo das wirklich einen Nutzen hat mit einem Datum aus dem Mittelalter zu arbeiten.

                  Wenn ich Daten vergleiche, dann im Rahmen von z.b. gültigen Geburtstagen und Terminen in der näheren Zukunft. wobei aber die Perl Module auch die nächsten 30 Jahre Problemlos bearbeiten könne müßten.

                  Struppi.

            2. Was heißt er geht in die Hose? Du kannst vergleichen, ob dieser Wert gültig ist oder nicht, indem du den Timestamp wieder zurück umwandelst.

              Ok, sei sogut und rechne hier mal nur den Timestamp für o.g. Datum '35.13.1960' aus. Und zeig uns bitte auch den PerlCode dazu.

              Ich hab im Moment nicht die Möglichkeit das auszuprobieren, kann dir also keinen Code zeiegn. Aber es sollte ein Timestamp herauskommen, der nicht mit dem Datum übereinstimmt, den du mit Time:Local ermittelst. In dem Moment weißt du, dass Datum ist ungültig.

              Struppi.