Linuchs: Alter einer Person in ganzen Jahren

Moin,

habe gerade ein Brett vor dem Kopf - oder ist das wirklich so kompliziert?

Beispiel: Eine Person ist am 1887-10-24 geboren und am 1959-01-01 gestorben. Die Daten kommen so aus der Datenbank.

Wie alt ist sie geworden?

Gruß, Linuchs

P.S. Ich könnte das auch mit PHP rechnen und die fertige Zahl senden, falls das einfacher ist.

  1. Trick:

    1959-01-01 -> 19590101
    1887-10-24 -> 18871024
    -=              719077
    /10000          71.9077
    -----------------------
    floor           71
    =======================
    
    <?php
    echo floor(
        ( 
            str_replace('-','', '1959-01-01')
          - str_replace('-','', '1887-10-24')
        ) / 10000
    );
    

    Javascript kennt ähnliche Funktionen: math.floor(), str.replace(),...

    Aber es geht auch schon in mysql ...

    1. Javascript:

      console.log(
         Math.floor (
             (
                   parseFloat( '1959-01-01'.replace(/-/g, '') )
                 - parseFloat( '1887-10-24'.replace(/-/g, '') )
             ) / 10000
         )
      );
      
      1. parseInt() statt parseFloat() wäre womöglich sauberer. Ich hatte beim Testen mit den Klammern gehunzt und einen Augenblick gedacht, dass der Interpreter über die ganzen Zahlen stolpert und deshalb nicht rundet…

      2. Hallo Raketenwilli,

        da sprach ich eben noch von Pistolen zum in den Fuß schießen. Dies ist eine. Darum das Minus, nimm's nicht persönlich.

        Wenn die Datümer aus der DB kommen und garantiert im ISO YYYY-MM-DD Format sind, dann geht's Aber das müsste man dann vorher validieren. Ein Datum im Format "2021-9-1" würde diese Methode gründlich abschießen. 💥🔫

        Rolf

        --
        sumpsi - posui - obstruxi
        1. Wenn die Datümer aus der DB kommen und garantiert im ISO YYYY-MM-DD Format sind, dann geht's

          Linuchs schrub wörtlich und explizit: „Die Daten kommen so aus der Datenbank.“

          Hab beschlossen, ihm das zu glauben.

          1. Hallo Raketengenauleser,

            jaaa, okay. Aber der Code läuft im JavaScript. Und solche Funktionen neigen zur Verselbstständigung.

            Programmiererdogma: Traue niemandem. Am wenigsten deinem 3 Monate älteren Selbst.

            Rolf

            --
            sumpsi - posui - obstruxi
            1. Und solche Funktionen neigen zur Verselbstständigung.

              Klar. Soweit auch zu meinem Grund, weshalb ich keine Funktion notiert oder gar beworben habe, sondern nur console.log(…).

    2. SELECT TIMESTAMPDIFF(YEAR, '1887-10-24', '1959-01-01') AS "Alter";
      

      Aber da bin mir noch unsicher, ob ich das Handbuch korrekt verstanden habe.

      1. Hallo Raketenwilli,

        es klingt sehr plausibel. Diese Funktion kannte ich als alter MS SQL Hase nicht, und ich war erstmal angep1sst, dass DATEDIFF in MySQL keinen Unit-Parameter hat (den hat es in MS SQL).

        Rolf

        --
        sumpsi - posui - obstruxi
      2. Danke, sieht gut aus:

        $q = "
        SELECT TIMESTAMPDIFF( YEAR, '1887-10-24', '1959-10-23') as 'alter'";
        $res  = @mysql_query( $q, $conn_id ); zeigSqlFehler( $q, $conn_id );
        $row  = @mysql_fetch_assoc( $res );
        echo  $row['alter']."<br>";
        
        $q = "
        SELECT TIMESTAMPDIFF( YEAR, '1887-10-24', '1959-10-24') as 'alter'";
        $res  = @mysql_query( $q, $conn_id ); zeigSqlFehler( $q, $conn_id );
        $row  = @mysql_fetch_assoc( $res );
        echo  $row['alter']."<br>";
        
        71 Jahre
        72 Jahre
        
        1. Hallo Linuchs,

          nur der Vollständigkeit halber, falls jemand auf diesen Thread stößt: den Code nicht kopieren, der SQL-Query ist ok, der PHP-Code dazu aber nicht:

          $res  = @mysql_query( $q, $conn_id ); zeigSqlFehler( $q, $conn_id );
          $row  = @mysql_fetch_assoc( $res );
          

          Die mysql_*-Funktionen gibt es seit bald 3 Jahren nicht mehr und vorher waren sie schon 5,5 Jahre als veraltet markiert – in heutigem Code muss PDO oder mysqli verwendet werden (ich würde ersteres empfehlen).
          Auch das Unterdrücken von Fehlermeldungen ist wenig sinnvoll, besser wäre es die Rückgabewerte der Funktionen auszuwerten und bei Fehlern entsprechend zu reagieren.

          Gruß
          Tobias

  2. Hallo Linuchs,

    mit PHP kannst Du es auf jeden Fall tun - da dürfte es am einfachsten sein.

    Mit create_date() oder new DateTime() zwei DateTime Objekte erzeugen, date_diff drauf ansetzen (wobei es egal ist, in welcher Reihenfolge Du die Datümer an diff übergibst) und aus dem DateInterval-Objekt, das rauskommt, die y Eigenschaft auslesen.

    In JavaScript gibt es keine fertige Datumsarithmetik, deswegen verweisen die meisten Quellen bei solchen Fragen auf die Standard-Library moment.js. Aber die Probleme der Lib-Seuche hatten wir ja gerade noch 😉

    Hier ist etwas im Bau, was das Problem lindern soll. Aber es ist noch eine sehr unfertige Baustelle, auch wenn es schon einen Polyfill dafür gibt.

    Für eine eigene Lösung müsstest Du zwei Date-Objekte erzeugen, und dann mit getFullYear, getMonth und getDay Jahr, Monat und Tag herausholen. Bis dahin ist die Nummer einfach. Sobald Uhrzeiten und Zeitzonen hinzukommen, solltest Du die eigene Arbeit einstellen und Dir moment.js anschauen.

    Danach kannst Du die Differenz der Jahre bilden und musst ggf. eins abziehen.

    function age(isoBirthDate, isoDeathDate) {
    
       let birth = new Date(isoBirthDate);
       let death = new Date(isoDeathDate);
       if (death < birth)
          return 0;
    
       let age = death.getFullYear() - birth.getFullYear();
    
       let birthMonth = birth.getMonth();
       let deathMonth = death.getMonth();
    
       if (birthMonth < deathMonth) return age;
       if (birthMonth == deathMonth && birth.getDate() <= death.getDate()) return age;
    
       return age - 1;
    }
    

    Ohne Gewehr, nur mit Pistole zum in den Fuß schießen…

    Rolf

    --
    sumpsi - posui - obstruxi
    1. Hab das Skript von oben gelesen, von unten gelesen, von links und von rechts auch und („Ach!“) sogar getestet: Es hat auch bei Angaben wie '1959-1-1' zuverlässig funktioniert.

      Deshalb wüsste ich nunmehr zu gern, was an Rolfs Beitrag zur Abwertung geführt hat.

      War es die Erwähnung von moment.js?

      1. Hallo Raketenwissensbedürftiger,

        sogar getestet

        Lol - ich auch. In viel zu vielen Iterationen, bis es so lief wie es sollte. Manchmal kann man blöd sein.

        Aber bin ich blind? Welche Abwertung? Die einzige, die ich sehe, ist meine an deine Idee, die ich begründet hatte.

        Ein kompensiertes Minus würde man als "+- 0" sehen. Wurde die Abwertung zurückgenommen? Bewertungen tauchen selbst im Audit-Log des Forums nicht auf.

        Ein Minus für moment.js wäre aber berechtigt gewesen. Ich habe nämlich vergessen, dass die Autoren von moment selbst sagen: Nimm es nicht für neue Projekte. Statt dessen empfehlen sie Alternativen.

        Rolf

        --
        sumpsi - posui - obstruxi
        1. Welche Abwertung?

          Hm. Wurde offensichtlich zurückgenommen.

          1. @@Raketenwissensbedürftiger

            Welche Abwertung?

            Hm. Wurde offensichtlich zurückgenommen.

            Ja. Ich war’s.

            Mein Gedanke war: Warum so kompliziert? Einfach Differenz death.getTime() - birth.getTime() nehmen, Millisekunden in Jahre umrechnen, abrunden.

            Je nachdem, wie die Schaltjahre liegen, kann man sich damit aber auch um ein Jahr verrechnen. Als mir dieses Licht aufging, hab ich meine Bewertung zurückgenommen.

            Hier haben wir so einen Fall: 1900-02-28 – 2000-02-28 ergibt 99.

            Wenn Geburts- und Todestag (fast) auf denselben Kalendertag fallen, d.h. wenn die Differenz in Tage umgerechnet sehr nah an dem auf Ganzzahl gerundeten Wert liegt, dann muss man sich doch noch die Tage ansehen – und wenn da gerade ein Monatswechsel im Spiel ist auch die Monate und evtl. auch die Jahre.

            Oder auch nicht. Sondern man schaut, ob das Geburtsjahr ein Schaltjahr war – wobei man das zwischen im Januar oder Februar Geborenen und im März bis Dezember Geborenen unterscheiden müsste … 🤔

            Wer kam auf die Schapsidee, den Schalttag mitten im Jahr einzuführen?

            Richtige Antwort: Niemand. Der Schalttag war am Jahresende. Wer kam auf die Schapsidee, den Jahresanfang vom 1. März auf den 1. Januar zu verlegen?

            😷 LLAP

            --
            „Dann ist ja auch schrecklich, dass wir in einem Land leben, in dem nicht nur Bildungswillige leben, sondern auch hinreichende Zahlen von Bekloppten. Das darf ich so locker formulieren, ich bin ja jetzt Rentner und muss nicht mehr auf jedes Wort achten.“
            — Joachim Gauck über Impfgegner
            1. @@Gunnar Bittersmann

              Wenn Geburts- und Todestag (fast) auf denselben Kalendertag fallen, d.h. wenn die Differenz in Tage umgerechnet sehr nah an dem auf Ganzzahl gerundeten Wert liegt, dann muss man sich doch noch die Tage ansehen – und wenn da gerade ein Monatswechsel im Spiel ist auch die Monate und evtl. auch die Jahre.

              Oder auch nicht. Sondern man schaut, ob das Geburtsjahr ein Schaltjahr war – wobei man das zwischen im Januar oder Februar Geborenen und im März bis Dezember Geborenen unterscheiden müsste … 🤔

              Oder einfach einen Offset auf die Differenz addieren? 🤔

              Der Wert 1e8 ergab sich durch Probieren; 1e7 war noch zu klein. Um den wirklich benötigten Offset zu ermitteln, müsste man da etwas mehr Gehirnschmalz reinstecken.

              Jetzt wäre zu überprüfen, ob dadurch u.U. ein zu großer Wert berechnet wird.

              Und auch, ob das noch hinhaut, wenn zwischen zwei aufeinanderfolgenden Schaltjahren 8 Jahre liegen (bspw. 1896 – 1904).

              😷 LLAP

              --
              „Dann ist ja auch schrecklich, dass wir in einem Land leben, in dem nicht nur Bildungswillige leben, sondern auch hinreichende Zahlen von Bekloppten. Das darf ich so locker formulieren, ich bin ja jetzt Rentner und muss nicht mehr auf jedes Wort achten.“
              — Joachim Gauck über Impfgegner
              1. @@Gunnar Bittersmann

                Oder einfach einen Offset auf die Differenz addieren? 🤔

                Der Wert 1e8 ergab sich durch Probieren; 1e7 war noch zu klein. Um den wirklich benötigten Offset zu ermitteln, müsste man da etwas mehr Gehirnschmalz reinstecken.

                Jetzt wäre zu überprüfen, ob dadurch u.U. ein zu großer Wert berechnet wird.

                Und auch, ob das noch hinhaut, wenn zwischen zwei aufeinanderfolgenden Schaltjahren 8 Jahre liegen (bspw. 1896 – 1904).

                Meh. 1896-02-28 – 1997-02-27 ergibt 101.

                Gibt es einen Offset zwischen 10⁷ und 10⁸, der weder zu klein noch zu groß ist? 🤔

                😷 LLAP

                --
                „Dann ist ja auch schrecklich, dass wir in einem Land leben, in dem nicht nur Bildungswillige leben, sondern auch hinreichende Zahlen von Bekloppten. Das darf ich so locker formulieren, ich bin ja jetzt Rentner und muss nicht mehr auf jedes Wort achten.“
                — Joachim Gauck über Impfgegner
            2. Hallo Gunnar,

              Kalenderarithmetik auf Basis von Millisekunden ist wie click-Handler für divs. Technisch geht es, aber sinnvoll ist es nicht.

              Ups. Ich glaube, ich muss Jürgen noch was stecken 😉 - es sei denn, für seine Bubbling-Visualisierung ist ein div-click akzeptabel.

              31556952000 mag die exakte Länge eines gregorianischen Kalenderjahres in Sekunden sein - aber damit kannst Du nicht rechnen, weil die Kalenderzahlen eine Approximation an diese Länge sind. Korrekturwerte dürften davon abhängen, wie weit der Geburtstag vom nächsten Schalttag weg ist. Für die moderne Zeit kann man das mit "maximal 4 Jahre" limitieren, aber im Stammbaum können es bis zu 8 Jahre sein.

              Schaltsekunden sind immerhin irrelevant. JavaScript verwendet die Posix-Zeitspezifikation, die die Schaltsekunden ignoriert.

              Ob eine Betrachtung des Schaltjahres im Geburtsjahr genügt, müsstest Du erstmal belegen. Dafür musst Du - denke ich - 9 Fälle untersuchen (drei Fälle pro Jahr: kein SJ, SJ Jan/Feb, SJ Mar-Dec). Good Luck. Oder Du machst die Mathematik zum Wochenende draus 🤣. Je nach Ergebnis kannst Du dann ein Minus oder Plus beantragen (selbst geben kannst Du es Dir ja nicht 😉).

              Der vernünftige Programmierer wählt aber den leichter nachvollziehbaren Algorithmus statt den VIELLEICHT schnelleren, aber schwer verständlichen. Das mag Rechenzeit vergeuden. Aber auch beim Programmieren gilt: Don't Make Me Think (Too Much).

              Rolf

              --
              sumpsi - posui - obstruxi
              1. Hallo Rolf,

                Ups. Ich glaube, ich muss Jürgen noch was stecken 😉 - es sei denn, für seine Bubbling-Visualisierung ist ein div-click akzeptabel.

                ich habe da einen Satz zu geschrieben: „Auf dieser Testseite werden Divs als anklickbare Elemente verwendet. Dadurch ist die Seite nicht zugänglich. Das ist aber auf einer Testseite ok.“

                Gruß
                Jürgen

            3. Wer kam auf die Schapsidee, den Jahresanfang vom 1. März auf den 1. Januar zu verlegen?

              Eher eine „Weinidee“. Denn das waren die Römer. Angeblich steht auf der originalen Senatsverordnung „ANNO CLIII PRE CHRISTUS“ (Wegduck)

              1. Hallo Raketenmuseumswärter,

                die Jahresangabe stimmt, aber trotzdem muss diese Verordnung eine Fälschung sein. PRE gips nich, wenn schon, wäre es prae, aber das ist ein räumliches "vor". Das zeitliche "vor", das zusammen mit Datumsangeben verwendet wird, ist ante, und es verlangt den Akkusativ.

                Also: ANNO DOMINI CLIII ANTE CHRISTUM.

                Für diese Analyse darfst Du mich mit einem 30€-Schein bezahlen.

                Rolf

                --
                sumpsi - posui - obstruxi
                1. Hallo Rolf,

                  Also: ANNO DOMINI CLIII ANTE CHRISTUM.

                  Für diese Analyse darfst Du mich mit einem 30€-Schein bezahlen.

                  komisch, mich machen sie immer dumm an, wenn ich im Supermarkt mit meinem 30-Euro-Schein ankomme ... 😉

                  Live long and pros healthy,
                   Martin

                  --
                  Bei Erwärmung steigt das Thermometer, bei Erkältung singt es.
                  1. komisch, mich machen sie immer dumm an, wenn ich im Supermarkt mit meinem 30-Euro-Schein ankomme ... 😉

                    Wechsle ihn vorher im Tabakladen.

                    1. @@Raketenmuseumswärter

                      komisch, mich machen sie immer dumm an, wenn ich im Supermarkt mit meinem 30-Euro-Schein ankomme ... 😉

                      Wechsle ihn vorher im Tabakladen.

                      Da frage ich mich, wer dümmer ist. Die an der Kasse, die tatsächlich einen 30-Euro-Schein als bare Münze – äh bares Geld – annimmt?

                      Oder doch der Fälscher? Mit demselben oder gar weniger Aufwand ließen sich ja auch 20-Euro-Scheine fälschen, die man womöglich unerkannt in Umlauf bringen könnte – auch ohne auf besonders dumme Kassiererïnnen zu treffen.

                      Oder hatte er aus einem echen 20er einen falschen 50er 30er gemacht?

                      😷 LLAP

                      --
                      „Dann ist ja auch schrecklich, dass wir in einem Land leben, in dem nicht nur Bildungswillige leben, sondern auch hinreichende Zahlen von Bekloppten. Das darf ich so locker formulieren, ich bin ja jetzt Rentner und muss nicht mehr auf jedes Wort achten.“
                      — Joachim Gauck über Impfgegner
                      1. Der Fälscher kannte den genauen Wortlaut von 146 Abs. 1 StGB offenbar nicht.

                        Juristen dürfte meine Vermutung hinsichtlich seines Berufes nicht gefallen…

                2. Das zeitliche "vor", das zusammen mit Datumsangeben verwendet wird, ist ante, und es verlangt den Akkusativ.

                  Ja so ist das:

                  • IT-Leute kritisieren zu Recht mein Latein.
                  • Juristen entgegen der Logik mein „französisch“.

                  „Seufz“ 😀

                3. Hi,

                  die Jahresangabe stimmt, aber trotzdem muss diese Verordnung eine Fälschung sein. PRE gips nich, wenn schon, wäre es prae, aber das ist ein räumliches "vor".

                  nicht nur.

                  Laut Stowasser:
                  prae: vor, vorn als Vorsilbe aber auch vor(zeitig) (z.B: praedicere = vorhersagen)

                  cu,
                  Andreas a/k/a MudGuard

                  1. Hallo MudGuard,

                    mag sein. Prae = vorn gibt's auch, dann ist prae aber ein Adverb und keine Präposition. Und Prae als Vorsilbe ist auch keine Präposition.

                    Ich hab ja eh keine Ahnung, ich hab nur diesen Österreicher dazu gefunden. Der sagt dann übrigens noch, dass prae den Ablativ regiert, also wenn, dann prae christo, nicht -us.

                    Wo ist ein Lateinlehrer, wenn man ihn braucht?

                    Rolf

                    --
                    sumpsi - posui - obstruxi
                    1. Hi,

                      Wo ist ein Lateinlehrer, wenn man ihn braucht?

                      Cum Latino meo ad finitem sum.

                      cu,
                      Andreas a/k/a MudGuard

  3. Hi,

    habe gerade ein Brett vor dem Kopf - oder ist das wirklich so kompliziert?

    alter = todesjahr - geburtsjahr;
    if ((todesmonat < geburtsmonat) 
        || ((todesmonat == geburtsmonat) && (todestag < geburtstag))) {
      alter--
    }
    

    ist das kompliziert?

    Ist halt nur noch zu klären: ist ein am 29.02.2020 geborenes Kind am 28.02.2021 schon 1 Jahr alt oder erst am 01.03.2021?

    cu,
    Andreas a/k/a MudGuard

    1. Ist halt nur noch zu klären: ist ein am 29.02.2020 geborenes Kind am 28.02.2021 schon 1 Jahr alt oder erst am 01.03.2021?

      Erst am 01.03.2021. Denn am 28.02.2021 ist es ja per Definition noch kein Jahr alt. Das ist wichtig, denn Vorfeieren bringt Unglück.

      1. Hi,

        Erst am 01.03.2021. Denn am 28.02.2021 ist es ja per Definition noch kein Jahr alt.

        Per welcher Definition?

        Das Kind ist doch am Tag vor dem 01.03. geboren, also ist es doch im Folgejahr am Tag vor dem 01.03. ein Jahr alt.

        Oder nach Anwendung von s/Tag vor dem 01.03./letzten Februartag/g auf den vorherigen Satz:

        Das Kind ist doch am letzten Februartag geboren, also ist es doch im Folgejahr am letzten Februartag ein Jahr alt.

        cu,
        Andreas a/k/a MudGuard

        1. Hallo MudGuard,

          nein, in Nichtschaltjahren werden Ereignisse des 29.02. am 01.03. durchgeführt.

          Rolf

          --
          sumpsi - posui - obstruxi
          1. Hello,

            nein, in Nichtschaltjahren werden Ereignisse des 29.02. am 01.03. durchgeführt.

            Das ist die gesetzliche Regelung in DE.

            "JR" (Jörg Rakete) war aber auch logisch (Gesetze sind selten logisch) schon ziemlich dicht dran. Das Problem: das Jahr hat keine konstante Länge. Wenn man also die sprachliche Form "ein Jahr älter" auf das Schaltjahr anwendet, dann findet das Ereignis im Beispiel eben erst mit Ablauf des 29. Februar (oder eben der Geburtsstunde) statt.

            Glück Auf
            Tom vom Berg

            --
            Es gibt nichts Gutes, außer man tut es!
            Das Leben selbst ist der Sinn.
        2. Per welcher Definition?

          „Ein Jahr alt“.

          Das es am 28.2.2021 nicht ein Jahr alt sein kann, weil es ja am erst 29.2. des Vorjahres geboren wurde, steht per Definition

          1. von „alt“ als Zeitspanne (meinetwegen Differenz) überhaupt und
          2. einem Jahr als konkrete Zeitspanne (Differenz) fest.

          Also kommt in Nichtschaltjahren nur der 1.3. als Geburtstag in Betracht.