Datum: wieviele Monate Unterschied?
Tanja
- php
hi,
könnt Ihr mir bitte helfen.
Habe 2 timestamps, $t_alt und $t_neu.
wie kann ich nun feststellen, wieviel monate zwischen den beiden timestamps unterschied sind? jahresübergreifend wäre auch noch geschickt...
Danke
was in deinem "siehe hier" nicht drin steht ist die wunderschöne mysql funktion timediff, sofern es um timestamps aus mysql geht
beispielsweise select TIME_TO_SEC(timediff(ende,start)) from zeiten
ich liebe mysql ;)
und wenn es darum geht zu wissen, ob es genau einen monat ist, kannst du ja auch 2 sachen abfragen
beispiel:
select TIME_TO_SEC(timediff(ende,start)) as genauer_unterschied, TIME_TO_SEC(timediff(DATE_ADD(start, INTERVAL 1 MONTH),start)) as genau_ein_monat from zeiten
sofern du beide ergebnisse vergleichst, weißt du, ob es 1 monat ist, weniger oder mehr .....
PS: nur beispiele ;)
hi,
könnt Ihr mir bitte helfen.
Habe 2 timestamps, $t_alt und $t_neu.
wie kann ich nun feststellen, wieviel monate zwischen den beiden timestamps unterschied sind? jahresübergreifend wäre auch noch geschickt...
Danke
Kommt Drauf an, wie Du es definierst!
30.3. - 30.4. 1 Monat
31.3. - 30.4. 1 Monat ?
28.2. - 28.3. 1 Monat
28.2. - 29.3. 1 Monat ?
28.2. - 29.3. 1 Monat ?
28.2. - 30.3. 1 Monat !?
die frage ist in dem fall recht einfach zu beantworten.
es sind nur daten vom jeweils 1. eines monats.
aber nun zu prüfen, ob es ein vielfaches von 31 o.ä. ist, wäre doch etwas unsauber... gibts nichts geeigneteres?
danke für weitere infos
hi Tanja,
Habe 2 timestamps, $t_alt und $t_neu.
wie kann ich nun feststellen, wieviel monate zwischen den beiden timestamps unterschied sind? jahresübergreifend wäre auch noch geschickt...
Wenn die Zahl korrekt berechnet werden soll, kommen Schätzformeln, wie das Teilen der Tagesdifferenz durch 30 wohl nicht in Frage. Daher hätte ich (für eine reine PHP-Lösung des Problems) folgende Funktion anzubieten:
function foxy_month_diff(
$ts_alt,
$ts_neu
) {
if($ts_alt > $ts_neu ) return(FALSE);
$alt = getdate($ts_alt);
$neu = getdate($ts_neu);
list($years, $months, $days) = foxy_date_diff(
$alt['year'], $alt['mon'], $alt['mday'],
$neu['year'], $neu['mon'], $neu['mday']
);
return($years * 12 + $months);
}
Sie basiert auf einigen anderen Kalenderfunktionern, die ich mir vor längerer Zeit gebastelt hatte, um Abstände zwischen zwei Daten in Jahren, Monaten und Tagen zu berechnen. Der Quellcode mag etwas umständlich erscheinen, aber er diente vor allem zur Demonstration von Kalenderberechnungen (und deren Komplexität). Alle Funktionen liefern FALSE zurück, wenn ungültige Werte übergeben werden.
function foxy_date_diff(
$year1 = FALSE, // Datum alt
$month1 = FALSE, // dieses Datum muss kleiner oder
$day1 = FALSE, // gleich dem "neuen" Datum sein
$year2 = FALSE, // Datum neu
$month2 = FALSE,
$day2 = FALSE
) {
// sanity checks
if(!is_integer($month1) || $month1 < 1 || $month1 > 12) return(FALSE);
if(!is_integer($month2) || $month2 < 1 || $month2 > 12) return(FALSE);
// das brauchen wir später noch
$days_in_month1 = foxy_days_in_month($year1, $month1);
if(!is_integer($day1) || $day1 < 1 || $day1 > $days_in_month1) return(FALSE);
if(!is_integer($day2) || $day2 < 1 || $day2 > foxy_days_in_month($year2, $month2) ) return(FALSE);
$diff_years = FALSE;
$diff_months = FALSE;
$diff_days = FALSE;
// Tageswerte ermitteln
$days_in_month1 = foxy_days_in_month($year1, $month1);
if($year1 < $year2) $diff_years = $year2 - $year1 - 1;
// gleiches Jahr
elseif($year1 == $year2) {
$diff_years = 0;
if($month1 < $month2) $diff_months = $month2 - $month1 - 1;
// gleicher Monat
elseif($month1 == $month2) {
$diff_months = 0;
if($day1 < $day2)$diff_days = $day2 - $day1;
elseif($day1 == $day2)$diff_days = 0;
else return(FALSE);
}
else return(FALSE);
}
else return(FALSE);
if(FALSE === $diff_days) $diff_days = $day2 + $days_in_month1 - $day1;
if(FALSE === $diff_months) $diff_months = $month2 + 12 - $month1 - 1;
if($diff_days > $days_in_month1) {
$diff_days = $diff_days - $days_in_month1;
$diff_months++;
}
if($diff_months > 12) {
$diff_months = $diff_months - 12;
$diff_years++;
}
return( array($diff_years, $diff_months, $diff_days));
}
function foxy_days_in_month(
$year = FALSE,
$month = FALSE
) {
// ein 30-Tage-Monat?
if(
$month == 4 or
$month == 6 or
$month == 9 or
$month == 11
) {
return 30;
}
// Februar-Tage berechnen
elseif($month == 2) {
if( foxy_is_leap_year($year) ) return(29);
else return(28);
}
// im Oktober 1582 wurden die Tage 5 bis 14 gestrichen
elseif( ($year == 1582) and ($month == 10) ) {
return 21;
}
// einer der anderen Monate
return 31;
}
function foxy_is_leap_year(
$year = FALSE
) {
if(FALSE === $year) return(FALSE);
if( $year % 4 != 0 ) return(FALSE); // alle nicht durch 4 teilbaren Jahre (die meisten);
// 1600 war das erste Jahrhundert, dass nach der neuen Regel ein Schaltjahr war
if($year >= 1600 && ($year % 400 == 0) ) return(TRUE); // alle Jahrhunderte, die durch 4 teilbar sind
if( $year % 100 == 0 ) return(FALSE); // alle anderen Jahrhunderte
return(TRUE); // alle anderen durch 4 teilbaren Jahre
}
Angewendet (oder angewandt) sieht das viel einfacher aus.
Folgendes Stück PHP-Code gibt die Zahl der vergangenen Monate
seit der Eröffnung des SELFHTML-Forums aus:
// Test des Ganzen:
$ts_alt = mktime(0, 0, 0, 7, 26, 1998);
$ts_neu = time(); // jetzt
$diff = foxy_month_diff($ts_alt, $ts_neu);
if(FALSE === $diff) exit('Fehlerhafte Datumsangabe!');
printf('Anzahl der Monate: %s', $diff );
exit();
MffG
EisFuX
wow! danke, werds mal durchstöbern und testen.
hallo,
kurz getestet und nen bug gefunden... :(
$ts_alt = mktime(0, 0, 0, 8, 1, 2006);
$ts_neu = mktime(0, 0, 0, 7, 1, 2006);
=> returns false :(
warum?
danke
Hallo Tanja,
hallo,
kurz getestet und nen bug gefunden... :(
Kein Bug -- ein Feature! ;-)
$ts_alt = mktime(0, 0, 0, 8, 1, 2006);
$ts_neu = mktime(0, 0, 0, 7, 1, 2006);
=> returns false :(
warum?
Das "neue" Datum sollte "größer" sein als das "alte" (oder gleich).
Sonst macht das ja keinen Sinn. Das steht auch als Kommentar hinter
den Parametern von foxy_date_diff().
Ich sehe das ganze auch eher als Codebeispiel und Grundlage für eine einfachere
Funktion zur Berechnung des Monatsabstandes. Denn das ganze Zeug mit den Tagen
die ein Monat hat, ist nur dann nötig, wenn man auch die Tageszahl mit berechnen
will.
MffG
EisFuX
echo $begrüßung;
Das "neue" Datum sollte "größer" sein als das "alte" (oder gleich).
Sonst macht das ja keinen Sinn.
Ach was. Man kann von einem bestimmten Zeitpunkt aus ebenso gut in die Vergangenheit als auch in die Zukunft schauen und dabei irgendwelche Berechnungen angestellt haben wollen. Wenn du diese Größer/Kleiner-Prüfung machst kannst auch auch gleich die Werte in eine dir genehme Reihenfolge bringen.
echo "$verabschiedung $name";
printf('Hallo %s!', $name_vorposter);
Das "neue" Datum sollte "größer" sein als das "alte" (oder gleich).
Sonst macht das ja keinen Sinn.Ach was. Man kann von einem bestimmten Zeitpunkt aus ebenso gut in die Vergangenheit als auch in die Zukunft schauen und dabei irgendwelche Berechnungen angestellt haben wollen. Wenn du diese Größer/Kleiner-Prüfung machst kannst auch auch gleich die Werte in eine dir genehme Reihenfolge bringen.
Den Gedanken hatte ich auch schon. Aber die Funktion date_diff() hatte ich ursprünglich gebastelt, weil in irgendeinem Web-Board jemand wissen wollte, wie man das Alter in Jahren, Monaten und Tagen ausrechnen kann. Also den Zeitabstand von der Geburt eines Menschen bis zum heutigen Tag. Deswegen die Einschränkung. Mir ist nämlich bisher noch niemand untergekommen, der ein negatives Alter aufzuweisen hatte ... ;-)
Nebenbei wäre die Prüfung und der Tausch der beiden Daten aufwändiger als meine bei passender Gelegenheit eingestreuten return(FALSE)-Anweisungen ...
Und letztendlich war es nur als Anregung gedacht, zum SELBST-Bauen einer Funktion, die das nur mit Monaten macht ...
printf('MffG %s', $mein_name);
Hallo EisFuX,
Das "neue" Datum sollte "größer" sein als das "alte" (oder gleich).
Sonst macht das ja keinen Sinn.
Ach was. Man kann von einem bestimmten Zeitpunkt aus ebenso gut in die Vergangenheit als auch in die Zukunft schauen und dabei irgendwelche Berechnungen angestellt haben wollen. Wenn du diese Größer/Kleiner-Prüfung machst kannst auch auch gleich die Werte in eine dir genehme Reihenfolge bringen.
Den Gedanken hatte ich auch schon. Aber ...
Nebenbei wäre die Prüfung und der Tausch der beiden Daten aufwändiger als meine bei passender Gelegenheit eingestreuten return(FALSE)-Anweisungen ...
Naja, man kann ja bei den Timestamps ansetzen, da ist der Vergleich noch einfach:
function foxy_month_diff(
$ts_alt,
$ts_neu
) {
// "Vertauschen", falls alt größer als neu ...
if($ts_alt > $ts_neu ) {
$alt = getdate($ts_neu);
$neu = getdate($ts_alt);
}
else {
$alt = getdate($ts_alt);
$neu = getdate($ts_neu);
}
list($years, $months, $days) = foxy_date_diff(
$alt['year'], $alt['mon'], $alt['mday'],
$neu['year'], $neu['mon'], $neu['mday']
);
return($years * 12 + $months);
}
MffG
EisFuX
hi,
noch was aus meiner anfängerzeit; folglich nicht sehr schön... aber es funktioniert:
<?
function difference_in_months($ts1,$ts2)
{
if((!empty($ts1))AND(!empty($ts2)))
{
$y1=date('Y',$ts1);
$y2=date('Y',$ts2);
$m1=date('n',$ts1);
$m2=date('n',$ts2);
$d1=$y1*12+$m1;
$d2=$y2*12+$m2;
$d=$d2-$d1;
return $d;
}
else
{
return false;
}
}
?>