[S] PHP-Programmierer

memoriam

Angesehenes Mitglied
HI,

in PHP:

ich habe zwei Termine:

1. Geburtstag (Tag, Monat, Jahr)

2. Stichtag (Tag, Monat, Jahr) - der 1. des nächsten Monats und der anderen folgenden Monate

Jetzt brauche ich:

Wie alt ist man am Stichtag - auf den Tag genau!

Besonderheit: Wenn Geburtstag innerhalb des nächsten halben Jahres (ab Stichtag) - dann Alter gleich ein Jahr älter.

Für einen erfahrenen Programmierer sicherlich nicht allzu schwierig. Das Problem dürfte sein: das EXAKTE Alter zu errechnen.


Beispiel: Geburtstag ist 10.12.1962
Stichtag: 01.12.2007

Alter ist (da im nächsten halben Jahr Geburtstag) 45

Soweit klar? Über Angebote freue ich mich.

memoriam

 
Am einfachsten ist sicher, die beiden Daten in einen Timestamp umzuwandeln um dann das Alter in Sekunden zu berechnen, das man dann durch die Sekunden pro Jahr teilt:
CODE <?php
/**
* This function returns the age in days from the birthday to a specified day.
*
* @param string $birhday: Point-seperated date (e.g. 31.12.2006)
* @param string $reference_day: Point-seperated date, empty for today
*/
function age_in_seconds($birthday, $reference_day = null) {
$birthday = explode('.', $birthday);
$birthday = mktime(0, 0, 0, $birthday[1], $birthday[0], $birthday[2]);
if($reference_day == null) {
$reference_day = time();
} else {
$reference_day = mktime(0, 0, 0, $reference_day[1], $reference_day[0], $reference_day[1]);
}
return ($reference_day - $birthday);
}

echo 'Alter: ' . round(age_in_seconds('13.04.1962') / 3600 / 24 / 365.25) . "\n";
?>


Wobei natürlich die Frage ist, wie genau das Alter sein muss. Hier wird für ein Jahr 365.25 Tage angenommen, obwohl das eigentlich nicht ganz korrekt ist. Deshalb das obige Script eher als Denkanstoß...
 
Mit Unix-Timestamps schießt du dir bei Geburtstagen ordentlich ins Knie. Wenn einer vor 1970 geboren wurde, wird deine Rechnung versagen.

QUOTE Der Zeitstempel ist ein long-integer-Wert, der die Anzahl der Sekunden zwischen der UNIX Epoche (January 1 1970 00:00:00 GMT) und der angegebenen Zeit enthält.


 
Hi,

hier mal eine Funktion:
CODE
function alter($gebdat) // funktion zum berechnen von alter datum englisch-year-month-day
{
list($geby,$gebm,$gebd)=explode("-",$gebdat);

$time=time();
$akty=date("Y", $time);
$aktm=date("m", $time);
$aktd=date("d", $time);
$alter=$akty-$geby;
$v=$aktm-$gebm;
if ($v < 0)
$alter=$alter-1;
if ($v == 0)
{
$d=$aktd-$gebd;
if ($d < 0)
$alter=$alter-1;
}
return $alter;
}


Gruß Sven
 
QUOTE (Maik @ Mo 19.11.2007, 16:41) Mit Unix-Timestamps schießt du dir bei Geburtstagen ordentlich ins Knie. Wenn einer vor 1970 geboren wurde, wird deine Rechnung versagen.


QUOTE Der Zeitstempel ist ein long-integer-Wert, der die Anzahl der Sekunden zwischen der UNIX Epoche (January 1 1970 00:00:00 GMT) und der angegebenen Zeit enthält.


Der Timestamp kann auch negative Werte annehmen, sofern das betreffende Script nicht unter Windows läuft


QUOTE Anmerkung: Der gültige Bereich eines Timestamp liegt typischerweise zwischen Fri, 13 Dec 1901 20:45:54 GMT und Tue, 19 Jan 2038 03:14:07 GMT. (Das entspricht den minimalen und maximalen Werten für einen vorzeichenbehafteten 32-Bit Integer). Unter Windows-Betriebssytemen ist dieser Bereich auf 01-01-1970 bis 19-01-2038 beschränkt.


Quelle: http://de.php.net/manual/de/function.date.php
 
dieser Hinweis gilt erst ab Version 5.1 und auch nur ausschließlich für diese Funktion
 
QUOTE Der Timestamp kann auch negative Werte annehmen, sofern das betreffende Script nicht unter Windows läuft


Das bleibt in jedem Fall nicht ohne Tuecken ... ich habe dazu auch schon einmal etwas geschrieben.

MySQL (ab 4.1.1) beispielsweise erlaubt so ein Konstrukt mit einem beliebigen Datum:

SELECT DATEDIFF(NOW(), '1962-12-10');

Das Ergebnis wird in Tagen geliefert. Nun gibt es sicher elegantere Moeglichkeiten Tage in Jahre umzurechen. Aber hier findet man zumindest die interessanteste Moeglichkeit, die dann

SELECT DATEDIFF(NOW(), '1962-12-10') * 0.00274;

aufzeigt (was auch nichts anderes ist, als mit 365.25 zu rechnen). Um die urspruengliche Aufgabe zu loesen, muss man doch an sich nur vom 1. des naechsten Monats + 6 Monate in die Zukunft rechnen, oder?

SELECT FLOOR((DATEDIFF(LAST_DAY(DATE_ADD(now(), INTERVAL 6 MONTH)), '1962-12-10') + 1) * 0.00274) AS AGE;

Cheers,
Den.
 
QUOTE (Maik @ Mo 19.11.2007, 17:41)Mit Unix-Timestamps schießt du dir bei Geburtstagen ordentlich ins Knie. Wenn einer vor 1970 geboren wurde, wird deine Rechnung versagen.


QUOTE Der Zeitstempel ist ein long-integer-Wert, der die Anzahl der Sekunden zwischen der UNIX Epoche (January 1 1970 00:00:00 GMT) und der angegebenen Zeit enthält.


Wie Jörg Kruse auch schon geantwortet hat, es hilft immer, die richtige Dokumentation zu lesen bevor man seine Weisheiten verbreitet. Ich habe den Snippet als Denkanstoß gepostet. Da ich eine aktuelle PHP-Version unter Linux einsetze für mich kein Problem. Was mich mehr interessierte war, wie andere das Problem angehen würden (und damit meine ich nicht, richtige Dinge falsch aus Dokumentationen zu zitieren, sondern wie sven_b und bowling-liga einen anderen Vorschlag zu posten).

Ich habe mir den Ansatz von sven_b angeschaut und bin zu dem Schluss gekommen, dass es davon abhängt, was man nun genau errechnen will:
a) Die genaue Zeit in Sekunden/Tagen, die dieser Mensch bereits lebt.
b) Wieviele Jahreswechsel dieser Mensch bereits erlebte (+ evtl. 1 zusätzlicher falls er schon nahe dran ist).
Der Unterschied besteht darin, dass a) zwar theoretisch genauer ist, aber da in unserer Zeitrechnung ein Jahr nicht immer der gleichen Zahl an Sekunden entspricht, kann es zu Fehlern kommen. b) hingegen ist zwar theoretisch nicht ganz korrekt, dafür aber vermutlich das, was eher gewünscht wird.
 
Hi David,

QUOTE a) Die genaue Zeit in Sekunden/Tagen, die dieser Mensch bereits lebt.


Nun mal ehrlich, wen interessieren hier die Sekunden. ;-)
Vor allem wirst du hierfür noch den genauen Zeitpunkt der Geburt wissen müssen.

Also ich bin da nicht so kleinlich und mir ist egal um welche Stunde ich am Geburtstag wirklich ein Jahr älter werde. Ab meinem Alter wird man dann sowieso in der Altersfrage nicht mehr kleinlich. ;-)

Ach ja, bei meinem Lösungsvorschlag wird garnicht mit dem Timestamp gerechnet (hoffe hab dich richig interpretiert).

Gruß Sven
 
QUOTE Ach ja, bei meinem Lösungsvorschlag wird garnicht mit dem Timestamp gerechnet (hoffe hab dich richig interpretiert).


Naja, garnicht kann man auch nicht sagen ;-) ... immerhin rufst Du einmal time auf.

Aber mal im Ernst, die Aufgabe widerspricht sich selbst in dem Punkt mit dem genauen Alter. Meiner Meinung nach liegt der Schluessel in der Ausnahme, die angegeben wurde. Insofern kann man den Code etwas umstrukturieren:


CODE
function alter($gebdat){
list($geby,$gebm,$gebd)=explode("-",$gebdat);
$ts=mktime(0,0,0,date("m")+7,1,date("Y"));
$alter=date("Y", $ts)-$geby;
if(($v=date("m", $ts)-$gebm) < 0){
$alter-=1;
}
if ($v == 0){
if(date("d", $ts)-$gebd < 0){
$alter-=1;
}
}
return $alter;
}

echo alter('1962-12-10'); #45



So long,
Den.
 
QUOTE Naja, garnicht kann man auch nicht sagen ;-) ... immerhin rufst Du einmal time auf.


Witzbold ;-))

Das deine Routine aber verkehrt rechnet ist dir bewußt?

Gib mal das Geburtsdatum ein: 1967-11-30, wieso kommt dann als Alter 40 raus? ;-)

Gruß Sven
 
Nee, die rechnet nicht verkehrt ... der Punkt ist doch der, wenn ich noch einmal zitieren darf:

QUOTE Besonderheit: Wenn Geburtstag innerhalb des nächsten halben Jahres (ab Stichtag) - dann Alter gleich ein Jahr älter.


Der Witzboild ist in meinen Augen eigentlich derjenige, der den Thread gestartet hat und sich im Augenblick nicht aeussert ...

Cheers,
Den.
 
Hallo Leute,

vielen Dank für Eure Hilfe, allerdings funktioniert auch der letzte Vorschlag nicht so ganz exakt. Ich brauche das taggenaue Alter - mit dem eventuellen halben Jahr - und das ist offensichtlich nicht so einfach hinzukriegen. (Hängt übrigens mit Versicherungsmathematik zusammen...)

Wenn also jemand einen Vorschlag hat, ich bin gerne bereit, die Arbeit zu bezahlen. Aus gegebenem Anlass: Aber bitte nur jemand, der es auch kann. Ich habe keine Lust, wieder für eine halbgare Lösung zu bezahlen...
sad.gif


Ich freue mich also auf Kontaktaufnahmen
smile.gif
 
Zurück
Oben