PHP/Zeit- und Datumsfunktionen
Kalenderfunktionen
Alle Kalender basieren auf einem identischen Anfangsdatum, von dem ausgehend der benötigte Tag berechnet wird. Dies ist der sogenannte julianische Tag, der 1. Januar 4713 vor Christus. Wenn ein Datum als beispielsweise vom gregorianischen in den julianischen Kalender umgerechnet werden soll, wird erst die Differenz zum julianischen Tag in dem einen Kalender bestimmt und dann die Anzahl im anderen berechnet.
Funktion | Beschreibung | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
jdtogregorian | Wandelt ein Datum des Julianischen Kalenders in das gregorianische Format. | ||||||||||
gregoriantojd | Wandelt das gregorianische Format in eine Datum des Julianischen Kalenders. | ||||||||||
jdtojulian | Wandelt ein julianisches Tagesdatum in einen julianischen Tageswert um (für Berechnungen mit diesem). | ||||||||||
juliantojd | Wandelt einen julianischen Tageswert in ein julianisches Tagesdatum um. | ||||||||||
jdtojewish | Wandelt einen julianischen Tageswert in ein Datum des Jüdischen Kalenders um. | ||||||||||
jewishtojd | Wandelt ein Datum des Jüdischen Kalenders in einen julianischen Tageswert um. | ||||||||||
jdtofrench | Wandelt ein julianisches Datum in ein ein Datum des Kalenders der französischen Republik um. | ||||||||||
frenchtojd | Wandelt ein Datum des Kalenders der französischen Republik in ein julianisches Datum um. | ||||||||||
jdmonthname | Gibt einen Monatsnamen zurück, wobei die Datumsangabe dem Julianischen Kalender entsprechen muss. Die Ausgabe kann durch einen zweiten Parameter gesteuert werden, der den Ursprungskalender bestimmt. | ||||||||||
jddayofweek | Gibt den Wochentag zurück, entweder als Zahl oder als Wort (aus dem englisch-gregorianischen Kalender). | ||||||||||
easter_date | Gibt den Unix-Zeitcode für Ostersonntag des angegebenen Jahres zurück; die Funktion ist also nur innerhalb der Unix-Zeitdefinition zwischen 1970 und 2037 einsetzbar. | ||||||||||
easter_days | Gibt die Anzahl der Tage aus, die Ostern nach dem 21. März des angegebenen Jahres liegt. | ||||||||||
cal_days_in_month | Gibt die Anzahl der Tage eines bestimmten Monats in einem bestimmten Jahr des gewählten Kalenders aus. Mögliche Kalender sind:
| ||||||||||
cal_from_jd | Wandelt ein Datum im julianischen Format in eines der unterstützten Kalender und gibt weitere Informationen zurück. |
Anzeige des Osterdatums.
<?php
setlocale(LC_TIME, "de");
echo "Ostern ist am " . strftime("%d.%m.%Y", easter_date(2008));
?>
|
Ostern ist am 23.03.2008 |
Anzeige der Anzahl Tage des Monats Februar im Jahre 2008.
<?php
echo cal_days_in_month(CAL_GREGORIAN, 2, 2008);
?>
|
29 |
Datumsfunktionen
Funktion | Beschreibung |
---|---|
checkdate | Gibt "TRUE" zurück, wenn das angegebene Datum plausibel ist. Benötigt drei Argumente für Monat, Tag und Jahr (in dieser Reihenfolge). |
date | Formatiert ein Datum für die Ausgabe, sodass lokale Besonderheiten leicht berücksichtigt werden können. Die Funktion benötigt zwei Argumente: eine Formatieranweisung und eine Zeitinformation als Unix-Zeitstempel. Wenn der zweite Parameter entfällt, wird die aktuelle Zeit genommen. Innerhalb der Formatieranweisung ist eine Vielzahl von Symbolen erlaubt (siehe Formatierung von Datumsangaben). |
getdate | Gibt ein assoziatives Array mit Datums- und Zeitangaben zurück. |
gmdate | Formatiert ein Datum unter Berücksichtigung der GMT für die Ausgabe. |
Für die Arbeit mit Datumswerten ist das aktuelle Datum oft von grosser Bedeuetung. PHP bezieht sich allerdings immer auf das Systemdatum des Rechners. Wird PHP in den USA gehostet, so wird das Ergebnis nicht unbedingt den Erwartungen entsprechen, wenn etwa die Benutzer zeitabhängig begrüsst werden sollen.
Folgendes Beispiel zeigt die Anwendung der Funktion "date".
<?php
echo date("l dS of F Y") . "<br />";
echo date("l dS of F Y h:i:s A") . "<br />";
echo "The 1st of July 2000 was a ";
echo date("l", mktime(0, 0, 0, 7, 1, 2000)) . "<br />";;
?>
|
Friday 05th 2008f September 2008 |
Das folgende Beispiel zeigt, wie mit Datumsinformationen Datumsberechnungen angestellt werden können. Die Funktion "mktime" gibt dabei den Zeitstempel für ein Datum zurück (siehe Zeitfunktionen).
<?php
$morgen = mktime(0, 0, 0, date("m"), date("d") + 1, date("Y"));
$letztermonat = mktime(0, 0, 0, date("m") - 1, date("d"), date("Y"));
$naechstesjahr = mktime(0, 0, 0, date("m"), date("d", date("Y") + 1));
setlocale(LC_TIME, "ge");
printf ("Tomorrow is %s, the name of the last month is %s.",
strftime("%A", $morgen),
strftime("%B", $letztermonat));
?>
|
Tomorrow is Saturday, the name of the last month is August. |
Information über die Konfiguration
Die Funktion "nl_langinfo"" ermittelt Informationen über die Lokalisierungskonfiguration, um das Verhalten von Funktionen wie "strftime" bestimmen zu können. Folgendes Beispiel gibt die Fomratierungsanweisung zurück, die zuletzt von der Funktion "strftime" benutzt wurde.
$info = nl_langinfo(D_FMT);
|
Weitere Parameter finden sich in der folgenden Tabelle.
Parameter | Beschreibung |
---|---|
CODESET | Zeichensatz. |
D_F_FMT | Zeit und Datum für "strftime". |
D_FMT | Datum für "strftime". |
T_FMT | Zeit für "strftime". |
DAY_X | Für "X" kann ein Wert zwischen 1 und 7 eingesetzt werden, um den Namen des Wochentags zu ermitteln. |
ABDAY_X | Für "X" kann ein Wert zwischen 1 und 7 eingesetzt werden, um den Kurznamen des Wochentags zu ermitteln (z. B. "Fri"). |
MON_X | Für "X" kann ein Wert zwischen 1 und 12 eingesetzt werden, um den Namen des Monats zu ermitteln. |
ABMON_X | Für "X" kann ein Wert zwischen 1 und 12 eingesetzt werden, um den Kurznamen des Monats zu ermitteln (z. B. "Dec"). |
RADIXCHAR | Zeichen für den Dezimalpunkt. |
THOUSEP | Tausendertrennzeichen. |
YESEXPR | Regulärer Ausdruck für "Yes". |
NOEXPR | Regulärer Ausdruck für "No". |
CRNCYSTR | Währungssymbol. |
Zeitfunktionen
Funktion | Beschreibung | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
mktime | Ermittelt den Zeitstempel für eine bestimmte Zeitangabe. | ||||||||||
gmmktime | Ermittelt den Zeitstempel für eine bestimmte Zeitangabe unter Berücksichtigung der Greenwich Mean Time (GMT). | ||||||||||
time | Gibt den Unix-Zeitstempel sekundengenau zurück. Diese Funktion verfügt über keine Formatiereigenschaften, wie das bei "date" der Fall ist. | ||||||||||
microtime | Gibt den Unix-Zeitstempel mikrosekundengenau zurück. Diese Funktion verfügt über keine Formatiereigenschaften, wie das bei "date" der Fall ist. | ||||||||||
strfime | Formatiert eine Zeitangabe. | ||||||||||
gettimeofday | Gibt ein Array mit Angaben zur aktuellen Zeit zurück. Die Elemente des Arrays werden folgendermassen indiziert.
|
Viele Datums- und Zeitfunktionen rechnen mit der internen Ausgabe des Unix-Zeitstempels. Diese Angabe stellt die Anzahl der Sekunden seit dem 1. Januar 1970 00:00 Uhr dar. Um eine solche Angabe für ein bestimmtes Datum zu erhalten, wird die Funktion "mktime" eingesetzt. Der Parameter "sz" ist optional. Wird er auf 1 gesetzt, nimmt die Funktion an, dass sich das Datum in der Sommerzeit befindet. Der Wert 0 ist ausserhalb der Sommerzeit, der Standardwert ist -1 und steht für "unbekannt".
$stamp = mktime(stunde, minute, sekunde, monat, tag, jahr, sz);
|
Der Zeitstempel für den Frühlingsanfang 2006 wird also folgendermassen ermittelt.
$stamp = mktime(0, 0, 0, 3, 21, 2006);
|
Folgendes Beispiel zeigt die Ausgaben der Funktion "gettimeofday".
<?php
$time = gettimeofday();
echo $time["usec"] . "µs<br />\n";
echo date("H:m:s", $time["sec"]) . " (Zeit)<br />\n";
echo $time["minuteswest"] . " min (Diff zu GMT)<br />\n";
echo $time["dsttime"] . "<br />";
?>
|
755082µs |
Formatierung von Datumsangaben
Die Funktion "strftime" arbeitet ähnlich wie "date" und formatiert eine Datums- und Zeitangabe anhand einer Formatieranweisung. Die Parameter der beiden Funktionen stimmen allerdings nur teilweise überien und haben in einzelnen Fällen eine völlig andere Bedeutung!
date | strftime | Beschreibung |
---|---|---|
a | %p | "am" oder "pm". |
A | %r | "AM" oder "PM". |
B | Swatch-Internetzeit. Diese Zeit teilt den Tag ohne Zeitzonen in 1'000 Einheiten. | |
d | %d | Monatstag als zweistellige Zahl zwischen "01" und "31" mit führender Null bei einstelligen Werten. |
%e | Monatstag als Zahl zwischen " 1" und "31" mit führendem Leerzeichen bei einstelligen Werten. | |
D | %a | Wochentag mit drei Buchstaben (z. B. "Fri"). "date" verwendet nur englische Bezeichnungen. |
F | %B | Monatsname (z. B. "January"). "date" verwendet nur englische Bezeichnungen. |
h | Stunde im 12-Stunden-Format zwischen "01" bis "12" mit führender Null bei einstelligen Werten. | |
H | Stunde im 24-Stunden-Format zwischen "00" bis "23" mit führender Null bei einstelligen Werten. | |
g | %I | Stunde im 12-Stunden-Format zwischen "1" bis "12" ohne führender Null bei einstelligen Werten. |
G | %H | Stunde im 24-Stunden-Format zwischen "0" bis "23" ohne führende Null bei einstelligen Werten. |
i | Minuten "00" bis "59" mit führender Null bei einstelligen Werten. | |
%M | Minuten "0" bis "59" als Dezimalwert. | |
I | "1" in der Sommerzeit, sonst "0". | |
j | Monatstag "1" bis "31" ohne führende Null bei einstelligen Werten. | |
l | %A | Ausgeschriebener Wochentag (z. B. "Friday"). "date" verwendet nur englische Bezeichnungen. |
L | Boolescher Werts für das Schaltjahr: "0" oder "1". | |
m | %m | Monat "01" bis "12" mit führender Null bei einstelligen Werten. |
n | Monat "1" bis "12" ohne führende Null bei einstelligen Werten. | |
M | %b | Monat als Abkürzung mit drei Buchstaben (z. B. "Jan"). "date" verwendet nur englische Bezeichnungen. |
O | Zeitdifferenz zum UTC in Stunden als Zeichenkette (z. B. "+0200"). | |
r | Datum und Zeit im RFC 822-Format, das folgende Form hat: "Thu, 5 Mar 2008 19:03:00 +0100". Die RFC 822 definiert Datumsformate wie sie in E-Mails verwendet werden. | |
s | %S | Sekunden "00" bis "59" mit führender Null bei einstelligen Werten. |
S | Suffix der englischen Ordnungszahlen: "st", "nd", "rd", "th" usw. | |
t | Anzahl Tage des Monats "28" bis "31". | |
T | Zeitzoneneinstellung des Rechners (z. B. "EST" oder "MDT"). | |
U | Sekunden der Unix-Epoche (seit 1. Januar 1970). Entspricht der Ausgabe der Funktion "time". | |
w | %w | Wochentag "0" (Sonntag) bis "6" (Samstag). |
W | Wochennummer des Jahres im ISO-8601-Format (ab erste Woche mit einem Montag drin). | |
Y | %Y | Jahr im vierstelligen Format (z. B. "2008"). |
y | %y | Jahr im zweistelligen Format (z. B. "08"). |
z | %j | Tag im Jahr "0" bis "365". |
Z | %Z | Offset der Zeitzonen gegenüber dem UTC in Sekunden von -43200 bis 43200 (86400 Sekunden entsprechen einem Tag). |
%G | Jahr im vierstelligen Format (wie "%Y", also z. B. "2008"), aber nur bei vollen Wochen. Angefangene Wochen zählen im vorhergehenden bzw. folgenden Jahr. | |
%g | Jahr im zweistelligen Format (wie "%y", also z. B. "08"), aber nur bei vollen Wochen. Angefangene Wochen zählen im vorhergehenden bzw. folgenden Jahr. | |
%x | Zeit nach lokalen Systemeinstellungen. | |
%X | Datum nach lokalen Systemeinstellungen. | |
%c | Zeit und Datum nach lokalen Systemeinstellungen. | |
%D | Entspricht der Folge "%m/%d/%y" (z. B. "03/31/08"). | |
%U | Wochennummer, wobei die Woche mit dem Sonntag beginnt. | |
%V | Kalenderwoche nach ISO 8601. | |
%W | Wochennummer, wobei die Woche mit dem Montag beginnt. | |
%R | Vollständige Zeit im 24-Stunden-Format. | |
%C | Jahrhundert (z. B. "2003" gibt "20" zurück). | |
%t | Tabulator. | |
%n | Zeilenvorschub. | |
%% | Prozentzeichen. |
Mit Hilfe der Funktion "setlocale" lassen sich die Ausgaben an die sprachlichen Besonderheiten eines bestimmten Gebiets anpassen.
string setlocale(<category>, <localeID>)
|
Der Parameter "category" wird durch folgende Werte bestimmt:
Wert | Bedeutung |
---|---|
LC_ALL | Alle weiteren Angaben. |
LC_COLLATE | Wirkt auf Zeichenkettenvergleiche. |
LC_CTYPE | Wirkt auf zeichensetzung (z. B. in "strtoupper()"). |
LC_MONETARY | Wirkt auf Währungsfunktionen (z. B. "localeconv()"). |
LC_NUMERIC | Bestimmt die Dezimaltrennzeichen. |
LC_TIME | Wirkt auf Datums- und Zeitformatierungen mit "strftime()". |
Als "localeID" wird der ISO-Landescode angegeben, auf dessen Parameter die Ausgaben gesetzt werden sollen. Wird eine leere Zeichenkette genutzt, so versucht PHP entsprechende (gleichlautende) Variablen in der Betriebssystemumgebung zu finden. Wird eine "0" angegeben, so werden die aktuellen Einstellungen nicht geändert, aber zurückgegeben. Die Funktion gibt "FALSE" zurück, wenn der lokale Code nicht implementiert wurde.
Die ISO-Ländercodes berücksichtigen sowohl die Sprachen als auch das Land. Für Deutschland heisst der Code "de_DE", für die Schweiz gibt es die Varianten "de_CH" und "fr_CH". Die konkrete Umsetzung hängt jedoch vom Betriebssystem ab. Unix liefert diese Tabellen in "/usr/share/language" mit. Je nach System gelten die dort befindlichen Daten. Allgemein gilt folgende Regel für Unix-Systeme:
- Das Grundformat ist "sprache_LAND", also z. B. "de_CH".
- Zur Ausgabe bestimmter Sonderzeichen einer Sprache kann eine Codeseite angegeben werden, z. B. "kr_KR.949".
Der zweite Parameter "localeID" kann auch entfallen - dann wird die aktuelle Rechnerzeit gesetzt. Das scheint aber - wie aus der Ausgabe ersichtlich - ohnehin einen Dreck zu bewirken...
<?php
print(strftime("%A heisst auf Deutsch "));
setlocale(LC_TIME, "ge");
print(strftime("%A.<br />\n"));
?>
|
Friday heisst auf Deutsch Friday. |
Die lokalisierten Einstellungen wirken sich auch auf die interne Verarbeitung von Zahlen aus. Normalerweise gilt für alle numerischen Werte die Schreibweise mit Dezimalpunkt. Daran ändern auch die lokalen Einstellungen mit "setlocale" nichts. Werden dagegen Zahlen als Zeichenketten angegeben und mit diesen einfache mathematische Operationen ausgeführt, so rechnet PHP auch mit Dezimalkommata. das folgende Beispiel zeigt, wie das aussieht. Die Funktion "setlocale" basiert auf der internen Umwandlung zwischen Datentypen, die PHP automatisch vornimmt. Da der Operator "*" auf Zeichenketten keine Anwendungfinden kann, wird der passende Datentyp (hier "double") ermittelt und dann die Multiplikation ausgeführt.
<?php
setlocale(LC_ALL, "ge");
$net = "1234,56";
$gross = "1,16" * $net;
printf("Netto: %04.2f, Brutto: %04.2f", $net, $gross);
?>
|
Netto: 1234.00, Brutto: 1234.00 |
Die folgende Zeile ist dagegen nicht zulässig.
$net = 1234,56;
|
Vor dem intensiven Einsatz der Funktion "setlocale" sollte man sich mit der Funktion "number_format" beschäftigen. Die Formatierung zur Ausgabe birgt deutlich weniger Risiken und ist weitestgehend versions- und plattformunabhängig.
Es ist ausserdem eine gute Idee, alle internen Berechnungen und Verarbeitungen mit den Standarddatenformaten (also englischen Zahlen und Daten) im Unix-Zeitstempel-Format vorzunehmen und nur für die Ausgabe umzuwandeln. Dies vermindert die Zahl der Eingriffe bei der Übertragung des Skripts von einem System auf ein anderes ganz erheblich.
Datumsbehandlung
Die folgende Funktion fragt ein HTML-Formularfeld ab und wandelt ein darin enthaltenes Datum so um, dass es ohne Probleme in das Datumsfeld einer MySQL-Tabelle eingefügt werden kann. Das interne Datumsformat in MySQL sieht ohne Zeitangaben wie folgt aus.
YYYY-MM-DD
Folgende Eingabeformate sind zulässig:
- "d.m.y"
- "y.m.d"
- "d.m"
- "d"
Fehlt ein Datumsbestandteil, so wird die entsprechende Information dem aktuellen Systemdatum entnommen. Gibt die Funktion eine leere Zeichenkette zurück, so konnte das Eingabedatum nicht ausgewertet werden. Die Funktion kann wie folgt benutzt werden.
$date_ok = input2date($date_from_form_field);
|
<?php
function input2date($idate)
{
## Die Funktion "strtok" sucht bei jedem erneuten Aufruf das nächste
## Element in der Zeichenkette. Der folgende Teil zerlegt die
## Zeichenkette tatsächlich in vier Teile.
$token="-./ ";
$p1 = strtok($idate, $token);
$p2 = strtok($token);
$p3 = strtok($token);
$p4 = strtok($token);
$date = $y = $m = $d = "";
## Wenn hier zweistellige Jahreszahlen akzeptiert werden, muss eine
## Priorität festgelegt werden, da sonst Daten wie "11.3.03" nicht
## richtig erkannt werden können (könnte 11. März 2003 oder auch 3.
## November 2013 sein).
## Prüfen der Kombination "d.m.y" (Standard)
if (($p1 > 0 && $p1 < 32) && ($p2 > 0 && $p2 < 13) && ($p3 > 0))
{
$y = $p3;
$m = $p2;
$d = $p1;
}
## Alternative Prüfung auf "y.m.d"
elseif ($p1 > 0 && ($p2 > 0 && $p2 < 13) && ($p3 > 0 && $p3 < 32))
{
$y = $p1;
$m = $p2;
$d = $p3;
}
## Prüfen der Kombination "d.m"
if ($y == "" && ($p3 == "") && ($p2 > 0 && $p2 < 13) && ($p1 > 0 && $p1 < 32))
{
$y = date("Y");
$m = $p2;
$d = $p1;
}
## Prüfen der Kombination "d"
if ($y == "" && ($p3 == "") && ($p2 == "") && ($p1 > 0 && $p1 < 32))
{
$y = date("Y");
$m = date("m");
$d = $p1;
}
## Hinzufügen von 1900 oder 2000 zum Jahr
if ($y != "" && $y <= 99)
{
if ($y >= 70) $y = $y + 1900;
if ($y < 70) $y = $y + 2000;
}
if ($y != "")
{
if (checkdate($m, $d, $y)) $date = "$y-$m-$d";
}
return $date;
}
?>
Geben Sie einen Datumswert ein und beobachten Sie die Reaktion:
<p>
<form method="post" action="<?=$_SERVER['PHP_SELF']?>">
Testwert:
<input type="text" size="8" name="checkdate" value="">
<input type="submit" value="Testen">
</form>
<hr noshade size=1>
<?php
if (isset($_POST['checkdate']))
{
echo "Das Datum <b>{$_POST['checkdate']}</b> im MySQL-Format ist: ";
echo "<b>";
echo input2date($_POST['checkdate']);
echo "</b>";
}
?>
|