Altersberechnung - Extended!

Eagle3386

Mitglied
Hallo! :)

Ich bin etwas, nun ja, "Statistik-vernarrt" und möchte die exakte Zeit, die seit meinem Geburtstag vergangen ist, anzeigen - und zwar in Jahren, Monaten, Wochen, Tagen, Stunden, Minuten und Sekunden.

Dazu hab ich mir 'n recht primitives Code-Snippet geschrieben:

PHP:
$age_days = explode('.', ((time() - mktime(13, 0, 0, 3, 3, 1986)) / 86400));
$age_ours = explode('.', ($age_days[1] * 0.0000000024));
$age_mins = explode('.', ($age_ours[1] * 0.0000000060));
$age_secs = explode('.', ($age_mins[1] * 0.0000000060));

Das Problem ist jetzt, dass dieses Snippet nur die Tage, Stunden, Minuten und Sekunden ausrechnen kann, da ich bei der Angabe in Jahren ein Problem habe: das Schaltjahr, von dem es bekanntlich einige seit 1986 gab. ;)

Nun würd' ich gern wissen, wie ich's realisieren kann, dass es die exakte Anzahl an Jahren, Monaten, Wochen, Tagen, Stunden, Minuten und Sekunden angibt und dabei Schaltjahre berücksichtigt werden.

Außerdem soll das Ganze unabhängig vom *nix-Datumslimit sein, sprich soll es egal sein, ob jemand 1965 geboren ist oder eben 1986. :)


Danke für eure Mühe im Voraus! ;)

LG, Martin... :D
 
Ich hatte schon mal etwas gelesen, was für dich passend sein dürfte. Du nimmst di aktuelle Zeit als UNIX Timestamp und ziehst deinen geburtstag davon ab. Die übrigen Sekunden lässt du dir im gewünschten Format anzeigen. Ich suche mal eben, ob ich den Thread finde.

EDIT: Habs gefunden hier
 
Danke, aber genau das macht mein Snippet doch schon! - Ich krieg' ja die Differenz zwischen dem 03. 03. 1986 um 13:00 Uhr und der aktuellen Zeit als Rückgabewert in Sekunden.

Ich will bei der Umrechnung dieser Sekundenanzahl jedoch nicht nur durch 84600 rechnen, um die Tage rauszukriegen, sondern auch die Jahre, Monate und Wochen - und hierbei hab ich das Problem, das ich nicht durch 365 teilen kann, weil's auch Schaltjahre gibt und deshalb geht das nicht so einfach.

Ich such' nun 'Hilfe dafür, dass ich das absolut exakt ermitteln kann - inklusive "Vor-1970-Kompatibilität"! ;) :)
 
"Absolut exakt" und eine Angabe in den ungenauen Einheiten Jahr und Monat? Ehh... widerspricht sich das nicht ein wenig? ;) Wie definierst du "ein Monat"? Sind das 30 Tage? Oder die Zeit vom n-ten Tag des einen Monats zum n-ten Tag des nächsten Monats? Wenn du in dem Fall deine Zeitdifferenz in Monate umwandelst, verlierst du Information - und dann war's das mit der absoluten Exaktheit...
 
Matthias Reitinger hat gesagt.:
"Absolut exakt" und eine Angabe in den ungenauen Einheiten Jahr und Monat? Ehh... widerspricht sich das nicht ein wenig? ;)

Seine "Lebenszeit" von Geburt an in Sekunden anzugeben find' ich sehr exakt! ;)
Denn dieses "absolut exakt" bezieht sich darauf, dass ich eben nicht nur mein Alter in Jahren haben will, sondern in Jahren, Monaten, Wochen, Tagen, Stunden, Minuten und Sekunden. - Das ist für 'ne Lebenszeit-Angabe schon SEHR exakt, IMHO zumindest... :)


Matthias Reitinger hat gesagt.:
Wie definierst du "ein Monat"? Sind das 30 Tage? Oder die Zeit vom n-ten Tag des einen Monats zum n-ten Tag des nächsten Monats? Wenn du in dem Fall deine Zeitdifferenz in Monate umwandelst, verlierst du Information - und dann war's das mit der absoluten Exaktheit...

Nein, ich verliere KEINE Information, weil ich mich (glaube ich zumindest) anscheinend etwas falsch ausgedrückt habe.
Ich will im Prinzip mit dem Snippet erreichen, dass angezeigt wird, viele Jahre ich schon lebe (zurzeit 19 ;)), dann die Monate, Wochen, Tage, Stunden und Minuten, die übrig sind.

Wir haben heute den 31. März, also bin ich 19 Jahre, 0 Monate, 4 Wochen, 0 Tage, 6 Stunden und (jetzt gerade) 17 Minuten und paar Sekunden alt.

Verstehst du jetzt, wie ich's meine? - Ich nehme den Differenzwert, rechne ihn in Jahre um, wandle den Restwert (bin ja 19,xxx Jahre alt ;)) in die nächst kleinere Einheit um, gebe diese aus und nehme davon wieder den Rest und wandle den wiederum in die nächst kleinere Einheit um - das mach ich runter bis zu den Sekunden, die runde ich dann auf, weil in Zehntel-Sekunden brauche ich's nun auch wieder nicht wissen! ;) :D

Nur kann ich momentan nur die Tage ausrechnen, nicht aber die Jahre und Wochen, weil's Schaltjahre gibt und sich damit auch die Anzahl an Wochen verschiebt - genau hierfür bräuchte ich nun bisschen helfe, wenn die mir jemand geben kann... ;) :)
 
FreedomCall hat gesagt.:
Seine "Lebenszeit" von Geburt an in Sekunden anzugeben find' ich sehr exakt! ;)
Da widersprichst du dir jetzt aber...

Denn dieses "absolut exakt" bezieht sich darauf, dass ich eben nicht nur mein Alter in Jahren haben will, sondern in Jahren, Monaten, Wochen, Tagen, Stunden, Minuten und Sekunden. - Das ist für 'ne Lebenszeit-Angabe schon SEHR exakt, IMHO zumindest... :)
Wie gesagt: Ein Jahr und ein Monat sind keine exakten Angaben.

Nein, ich verliere KEINE Information, weil ich mich (glaube ich zumindest) anscheinend etwas falsch ausgedrückt habe.
Doch, du verlierst Information. Wenn ich jetzt sage, XY ist exakt 30 Tage alt, dann weißt du (sekunden)genau, wie lange das ist. Sage ich allerdings, XY ist ein Monat alt, wie lange lebt XY dann schon? 31 Tage? Oder 30? Oder vielleicht doch 28? Oder etwa gar 29?

Ich will im Prinzip mit dem Snippet erreichen, dass angezeigt wird, viele Jahre ich schon lebe (zurzeit 19 ;)), dann die Monate, Wochen, Tage, Stunden und Minuten, die übrig sind.
Und du hast leider immer noch nicht genau erklärt, was du unter der Zeiteinheit "ein Monat" verstehst. Das ist aber eben der springende Punkt.
 
Matthias Reitinger hat gesagt.:
Da widersprichst du dir jetzt aber...

Wie gesagt: Ein Jahr und ein Monat sind keine exakten Angaben.

Doch, du verlierst Information. Wenn ich jetzt sage, XY ist exakt 30 Tage alt, dann weißt du (sekunden)genau, wie lange das ist. Sage ich allerdings, XY ist ein Monat alt, wie lange lebt XY dann schon? 31 Tage? Oder 30? Oder vielleicht doch 28? Oder etwa gar 29?

Und du hast leider immer noch nicht genau erklärt, was du unter der Zeiteinheit "ein Monat" verstehst. Das ist aber eben der springende Punkt.

So, dann wollen wir das alles mal nachholen! ;) :D

Okay, okay, ich verliere Informationen, wenn ich Monate angebe, allerdings nicht in jedem Fall:

Ein Monat ist sicherlich eine recht ungenaue Angabe - nichtsdestotrotz ist dieser Wert unter bestimmten Bedingungen sehr wohl genau, nämlich wenn ich festlege, dass ein Monat für den Zeitraum vom 03. des Vormonats bis zum 03. des aktuellen Monats anzusehen ist.
Sicherlich kann man jetzt sagen, dass das immer noch ungenau ist, weil es Monate mit 28, teilweise 29, 30 sowie 31 Tagen gibt, Doch ergibt sich im arithmetischen Mittel ein Wert, den man als recht exakt ansehen kann.


Ich persönlich möchte halt von "groß nach klein" in der Angabe meiner Lebenszeit gehen, sprich: am 03. März 2005, um exakt 13:00:00 sind genau 19 Jahre seit dem 03. März 1986, 13:00:00 vergangen.
Allerdings sind (bald) wiederum Wochen, Tage, Stunden, Minuten und Sekunden seit dem 03. März 2005, 13:00:00 vergangen und diesen Rest möchte ich nun erst in Wochen angeben, dann die restlichen Tage, da heute der Freitag, 01. April ist und somit noch 6 Tage fehlen (der 03. März 2005 war 'n Donnerstag ;)), bevor eine weitere volle Woche seit dem 03. März 2005 vergangen ist.
Weiterhin ist es jetzt 01:26, also sind ein paar Wochen und Tage rum, aber auch schon wieder eine Stunde und 26 Minuten!


Und genau so soll dann die Ausgabe sein - immer der Rest soll in die nächst kleinere Einheit umgewandelt werden, runter bis zur Sekunde, die wird "großzügig" gerundet... ;) :D
 
Exakt hin oder her, so bekommst Du was Du willst:
PHP:
$geburtsjahr = 1986;
$geburtsmonat = 3;
$geburtstag = 3;
$geburtsstunde = 13;
$geburtsminute = 0;
$geburtssekunde = 0;

$alter = mktime(
	date('G') - $geburtsstunde,
	date('i') - $geburtsminute,
	date('s') - $geburtssekunde,
	date('n') - $geburtsmonat,
	date('d') - $geburtstag,
	date('Y'),
	-1
);

echo 'Alter am '.date('d.m.Y').' um '.date('H:i:s').' Uhr: <br>';
echo date('Y') - date($geburtsjahr) - (date('Y') - date('Y', $alter)) . ' Jahre, ';
echo date('n', $alter) . ' Monate, ';
echo date('d', $alter) . ' Tage, ';
echo date('G', $alter) . ' Stunden, ';
echo date('i', $alter) . ' Minuten, ';
echo date('s', $alter) . ' Sekunden.';
Das mit dem Jahr muss man so komisch machen, weil man ja mit mktime() eine UNIX-Timestamp erzeugt und für UNIX gab's vor 1970 nix. Und die Monate sind jetzt keine gemittelten "Statistikmonate" mit 30.4375 Tagen, sondern einfach die Anzahl vollständiger Monate, egal wie lang diese sind.
Die Ausgabe wird zugegebenermaßen in manchen Fällen (so wie in Deinem) etwas seltsam, Du bist demnach eben nicht 19 Jahre sondern 18 Jahre und 12 Monate. Das kann man aber mit etwas mehr Feinarbeit im Code noch ausbügeln.
Probier lieber mal ein paar Konstellationen durch, bin mir nämlich nicht sicher, ob ich das bis zu Ende logisch durchdacht habe. Ist jedenfalls ne lustige kleine Übung - das Alter in Sekunden mit date('U') - mktime(4, 30, 25, 10, 15, 1967, -1) berechnen kann ja jeder. Aber einen doofen Computer dazu zu bringen wie ein Mensch zu denken...;)

Martin
 
ManicMarble hat gesagt.:
Exakt hin oder her, so bekommst Du was Du willst:
PHP:
$geburtsjahr = 1986;
 $geburtsmonat = 3;
 $geburtstag = 3;
 $geburtsstunde = 13;
 $geburtsminute = 0;
 $geburtssekunde = 0;
 
 $alter = mktime(
 	date('G') - $geburtsstunde,
 	date('i') - $geburtsminute,
 	date('s') - $geburtssekunde,
 	date('n') - $geburtsmonat,
 	date('d') - $geburtstag,
 	date('Y'),
 	-1
 );
 
 echo 'Alter am '.date('d.m.Y').' um '.date('H:i:s').' Uhr: <br>';
 echo date('Y') - date($geburtsjahr) - (date('Y') - date('Y', $alter)) . ' Jahre, ';
 echo date('n', $alter) . ' Monate, ';
 echo date('d', $alter) . ' Tage, ';
 echo date('G', $alter) . ' Stunden, ';
 echo date('i', $alter) . ' Minuten, ';
 echo date('s', $alter) . ' Sekunden.';
Das mit dem Jahr muss man so komisch machen, weil man ja mit mktime() eine UNIX-Timestamp erzeugt und für UNIX gab's vor 1970 nix. Und die Monate sind jetzt keine gemittelten "Statistikmonate" mit 30.4375 Tagen, sondern einfach die Anzahl vollständiger Monate, egal wie lang diese sind.
Die Ausgabe wird zugegebenermaßen in manchen Fällen (so wie in Deinem) etwas seltsam, Du bist demnach eben nicht 19 Jahre sondern 18 Jahre und 12 Monate. Das kann man aber mit etwas mehr Feinarbeit im Code noch ausbügeln.
Probier lieber mal ein paar Konstellationen durch, bin mir nämlich nicht sicher, ob ich das bis zu Ende logisch durchdacht habe. Ist jedenfalls ne lustige kleine Übung - das Alter in Sekunden mit date('U') - mktime(4, 30, 25, 10, 15, 1967, -1) berechnen kann ja jeder. Aber einen doofen Computer dazu zu bringen wie ein Mensch zu denken...;)

Martin
Moin, Namensvetter! ;) :D

Also erstmal danke für dein Snippet! :)
Nichtsdestotrotz gibt's da paar Dinge, die ich nicht verstehe und wo ich auf bessere (erweiterte ;)) Beschreibungen bzw. Erklärungen von dir hoffe:

1. Warum berechnest du die Jahre so, wie du's eben machst - so wie du das machst, komme ich beim Nachrechnen (mit einem Geburtsdatum VOR 1970, z. B. 1963) auf 0, denn du rechnest ja dann bei den Jahren 2005 - 1963 - (2005 - 1963)

2. Hab ich dein Snippet versucht und es kommt nicht nur bei meinem Geburtsdatum 'ne komische Zahl raus, sondern auch beim Geburtsdatum meiner Mum, die ist am 20. 07. 1963 um xx:xx geboren und da meint dein Code, sie sei 41 Jahre und 8 Monate - richtig wären 9 Monate.
Deshalb vermute ich generell einen Fehler in der Umrechnung der Monate, weil mit meinem Geburtsdatum kommen ja 18 Jahre und 12 Monate raus - das wiederum müsste aber PHP als 19 Jahre begreifen.

3. Als Minuten-Angabe wird mir gerade eben "04 Minuten" ausgegeben, was ja am date('n') format liegt - aber wie kann ich die 0 wegkürzen ohne beispielsweise aus "10 Minuten" dann "0 Minuten" zu machen?

[EDIT]
4. Wieso machst du bei mktime eigentlich beim Geburtsjahr nur date('Y') und nicht date('Y') - $geburtsjahr? - Ich weiß, es kommt dann 'n falscher Wert, aber wieso
[/EDIT]


Ich weiß, viele Fragen, aber hey, nur wer fragt wird schlau und deshalb danke ich schon mal allen für ihre Mühe... ;) :D
 
Zuletzt bearbeitet:
Also wie gesagt, ich habe das nicht wirklich zu Ende gedacht, war nur so ein Ansatz.

Die komischen Zeitangaben im Ergebnis kommen daher, dass mktime() eigentlich einen Zeitpunk (Timestamp) zurückliefert und eben keine Zeitspanne (Timeslice). Sprich: Das Ergebnis ist eigentlich ein Datum mit Uhrzeit - in Deinem Beispiel (Ergebnis "18 Jahre, 12 Monate, 29 Tage, 0 Stunden, 13 Minuten, 13 Sekunden") ist das der 29.12. des Jahres 18 (n.Chr.), 00:13:13 Uhr.

Das mit dem Jahr kann man so also nicht berechnen, da ja 18 n.Chr. deutlich vor dem 1.1.1970 liegt :).
Deshalb habe ich das Jahr außen vor gelassen und berechne das später extra.

Da bei der mktime()-Berechnung (also $alter) theoretisch auch das Vorjahr rauskommen kann (3.3.2005 minus 3 Monate = 3.12.2004) muss in diesen Fällen diese Differenz noch bei der Jahres-Berechnung berücksichtigt werden. Deshalb
date('Y') - $geburtsjahr - (date('Y') - date('Y', $alter))
enspricht im o.g. Beispiel
2005 - 1986 - (2005 - 2004) = 2005 - 1986 - 1 = 18

Wenn Du den Ansatz mal zu Ende denken willst, muss Dir klar sein, wie mktime() arbeitet. Bei dem Alter Deiner Mutter sähe das in Etwa so aus:
$alter = mktime(13 - 0, 44 - 0, 20 - 0, 4 - 7, 1 - 20, 2005, -1);
entspricht
$alter = mktime(13, 44, 20, -3, -19, 2005, -1);
mktime() ist angeblich so schlau, aus den negativen Zahlen wieder ein korrektes Datum zu machen. Funktioniert für Timestamps AFAIK eigentlich wunderbar, wenn man's aber als Timeslice missbraucht, bin ich mir nicht mehr so sicher. Ist dann wohl doch so, dass das nicht richtig klappt... :(

Tja, dann muss es halt doch irgendwie anders gehen. Vielleicht tüftel ich mal noch ein bischen dran rum, jetzt muss ich aber erst mal wieder das machen, wofür ich hier bezahlt werde...;)

Viel Spaß noch
Martin
 
Zurück