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