| Auf dieser Seite finden sie einige Funktionen, die Perl zum Thema 'Datum und Zeit' bietet. Alle vorgestellten Beispiele sind in jeder Perl-Grundausstattung enthalten, d.h. auch bei den meisten Web-Providern. | Algorithmen zur Umrechnung finden sie auf der Seite ' IT-Datenformate für Datum & Zeit' |
Perl
|
Scripts für CGI und Systemverwaltung |
| time() | UNIX-Timestamp der aktuellen Systemzeit |
| mktime() | Erzeugung eines UNIX-Timestamps aus den Bestandteilen |
| gmtime() & localtime() | Aufspaltung eines UNIX-Timestamps in die Bestandteile |
| strftime() | Bequeme Formatierung von Datum und Zeit |
| Time::HiRes | Genaue Zeitmessung |
| Systemzeit | PC-System-Uhr setzen. Spezielle Windows-Probleme |
| Zeitzone | Differenz zur Weltzeit UTC, Sommerzeit |
| Datei-Zeiten | Erzeugung, letzte Änderung. letzter Zugriff |
| Timeout | Funktionen alarm(), sleep(), select() ... |
| Modul Date | Die zahlreichen Funktionen des Perl-Moduls Date |
| Perl-Module | Weitere Funktionen zu Datum & Zeit |
| Verwandte Themen | Datum & Zeit (Standards), Christliche Feiertage (Ostern...), Entwicklung mit C/C++, Javascript, PHP, SQL, VBA, Betriebssysteme Linux, Windows (Konsole + Cygwin) |
| Links |
Ausgewählte
|
Funktion time() liefert einen UNIX-Timestamp der aktuellen Systemzeit |
|||||||
|
Ein UNIX-Timestamp markiert die Anzahl Sekunden seit 1970-01-01 in Weltzeit UTC.
Timestamps eignen sich gut zum Rechnen mit Datum und Zeit. Das Ergebnis wird zur Ausgabe in Strings umgewandelt, z.B. mit ↓ Funktion strftime() Hinweise zur ↓ Programmierung dieser Seite finden sie ganz unten. |
$uts = time();
Live Daten (Zeit des Webservers):
|
||||||
Funktion mktime() erzeugt einen UNIX-Timestamp aus den Bestandteilen |
|||||||||||||||||||
|
Mit der POSIX-Funktion mktime() wird ein UNIX-Timestamp
aus den einzelnen Bestandteilen in zusammengesetzt.
use POSIX;
$uts = mktime($ss,$mi,$hh,$dd,$mo,$yy);
♣ Beachten sie die ungewöhnliche Reihenfolge der Argumente ! ♣ Ein Unix Timestamp wird in Weltzeit UTC angegeben. Zur Berechnung der UTC aus Lokalzeit korrigiert man lediglich die Stunden (Zonen-Differenz + Sommerzeit), derzeit in Mitteleuropa: UTC = CET - 2 Stunden
|
Beispiel:
Timestamp von heute 00:00:00 und Differenz in Sekunden seit Mitternacht
use POSIX;
Live Daten (Zeit des Webservers):
$uts = time(); $uts0 = mktime(0,0,0,$d,$m,$y); $dif = $uts - $uts0;
$uts0 = 1234567890
$dif = 0 |
||||||||||||||||||
Argumentemktime() verlangt 6 ganze Zahlen als Argumente. Weniger Argumente ergeben Fehler. Gleitkomma-Zahlen werden abgeschnitten. |
Die Argumente kann man auch als
→ Array
übergeben, z.B. für Neujahr 2000:
@a2k = (0,0,0,1,0,100);
$y2k = mktime(@a2k); |
||||||||||||||||||
Intelligente InterpretationNormalerweise sollten die Zahlenwerte der Argumente im üblichen Rahmen liegen, z.B. Sekunden 0..59 oder Monatstage 1..31Wenn die Werte der Argumente außerhalb liegen, dann werden sie intelligent interpretiert. Damit kann man sich z.B. komplizierte Kalender-Rechnungen ersparen. |
Beispiele:
•
Sekunden=90 ergeben richtig +1 Minute, 30 Sekunden• Stunde=-1 ergibt 23 Stunden des Vortags • Tag>31 ergibt den richtigen Tag im nächsten Monat • Tag=0 ergibt den letzten Tag des Vormonats • Monat<0 oder Monat>11 ergibt das entsprechende Monat des vorigen oder nächsten Jahres mit dem gleichen Monatstag. |
||||||||||||||||||
gmtime() und localtime() - Funktionen zur Aufspaltung von Timestamps |
||||||||||||||||||||||||||||
Funktion gmtime() verwendet als Argument einen UNIX-Timestamp,
der in den meisten Fällen durch ↑ Funktion time()
geliefert wird. Als Ergebnis wird ein Array von 9 Elementen geliefert, die Weltzeit UTC
(früher GMT)
|
Beispiel:
Erzeugung eines Datum+Zeit Strings ähnlich
→ ISO-8601 (ohne führende Nullen für 1stellige Zahlen)
@dta = gmtime(time);
# my $dtalen = @dta;
$dta[5]+=1900;# print "Laenge(Array) = $dtalen\n"; $dta[4]++; $utc ="$dta[5]-$dta[4]-$dta[3] "; $utc.="$dta[2]:$dta[1]:$dta[0]"; Live-Daten (Zeit des Webservers):
Weltzeit $utc = yyyy-mo-dd
hh:mi:ss
|
|||||||||||||||||||||||||||
|
Funktion localtime() arbeitet genauso
wie gmtime(), liefert jedoch die
lokale Zeit (der Server-Zeitzone). Die Elemente von gmtime() und localtime() lassen sich mit → Funktion sprintf() zu jedem beliebigen Datum-Format kombinieren. Das erspart die Verwendung von ↓ Modul POSIX mit Funktion strftime() : |
my $iso=($dta[5]+1900)."-";
$iso.=sprintf('%02d-',$dta[4]+1); $iso.=sprintf('%02d ',$dta[3]); $iso.=sprintf('%02d:',$dta[2]); $iso.=sprintf('%02d:',$dta[1]); $iso.=sprintf('%02d',$dta[0]); print "iso=$iso\n"; Live-Daten (Zeit des Webservers):
Lokalzeit $iso = yyyy-mo-dd
hh:mi:ss
|
|||||||||||||||||||||||||||
| Bei Anwendung ohne Argumente wird die aktuelle Zeit als String ausgegeben. Das dabei verwendete US-Format ist für die Praxis unbrauchbar. Man kann das Beispiel jedoch dazu verwenden, um die korrekte Einstellung der lokalen ↓ Zeitzone zu überprüfen.. |
Die Lokalzeit sollte in Mitteleuropa 1 Stunde (Normalzeit) oder 2 Stunden
(Sommerzeit) später als die Weltzeit UTC (GMT) anzeigen:
print 'gmtime='.gmtime()."\n";
print 'localtime='.localtime()."\n"; |
|||||||||||||||||||||||||||
|
Die Korrektur ist aufwändig: Man kann die Daten der Zeitzone aus der → Registry Datenbank lesen und die Lokalzeit mit eigenen Funktionen zu berechnen. Alternativ kann man die Zeitpunkte der → Sommerzeit-Umstellung selbst berechnen und korrigieren. |
♦ Details zum Thema Zeitzone auf dieser Seite. |
|||||||||||||||||||||||||||
POSIX-Funktion strftime() zur Formatierung von Datum und Zeit |
|
|
Funktion strftime() ist in PHP und Perl die
Standardfunktion zur Erzeugung von Strings (Text) aus einem Datum und
Zeit-Array, so wie von gmtime()
oder localtime() geliefert. Als Beispiel die Erzeugung eines Strings nach dem → ISO-8601-Standard für Datum und Zeit. |
Live-Daten des Webservers:
$iso = 2012-05-20 15:32:44
|
|
Die Funktion verwendet als Argumente einen Format-String und ein Array,
sie liefert einen String. Der Format-String besteht aus beliebigen Zeichen (die so wiedergegeben werden wie eingesetzt) und Platzhaltern. Die Platzhalter werden durch die passenden Datum- und Zeit-Daten ersetzt. |
Die einfachen und wichtigen Platzhalter werden immer unterstützt (sichere Variante).
Die komplexen, sprach- und kulturabhängigen Platzhalter werden je nach System und
Version unterschiedlich oder gar nicht unterstützt. Nachfolgende Live-Daten stammen aus der gleichnamigen PHP-Funktion. ♦ Details in der Original Perl-Doku, Kapitel |
|
Liste ausgewählter Platzhalter: (ohne Gewähr,
mit Live-Wert) ■ Datum: ► Jahrhundert %C - Jahrhundert, 2 Stellen (00..99) - 20 ► Jahr %Y - Jahr, 4 Stellen - 2012 %y - Jahr, 2 Stellen - 12 ► Monat %m - Monat (01..12) - 05 %h - Monat, 3 Zeichen - May %B - Monatsname - May ► Tag des Monats %d - Tag des Monats (01..31) - 20 %e - Tag des Monats ( 1..31) - 20 ► Tag des Jahres (DOY) %j - Tag des Jahres (001..366) - 141 ► Tag der Woche (DOW) %u - Tag der Woche (1=Mo..7=So) - 7 %w - Tag der Woche (0=So..6=Sa) - 0 %a - Wochentag, 3 Zeichen - Sun %A - Wochentag - Sunday ► Kalenderwoche (Woche des Jahres, KW, WOY) %V - Woche des Jahres (00..53). Mindestens 4 Tage ab Mo - 20 %W - Woche des Jahres (00..53). Ab Montag - 20 %U - Woche des Jahres (00..53). Ab Sonntag - 21 |
■ Zeit: ► Stunde %H - Stunde (00..23) - 15 %I - US-Stunde (01..12) - 03 %p - US-Halbtag (AM,PM) - PM ► Minute %M - Minute (00..59) - 32 ► Sekunde %S - Sekunde (00..59) - 44 ► Zeitzone %Z - Zeitzone - CEST ■ Zusammengesetzte Strings %D - US-Datum - 05/20/12 %x - US-Datum - 05/20/12 %T - Zeit (H:M:S) - 15:32:44 %X - Zeit (H:M:S) - 15:32:44 %R - Zeit (H:M) - 15:32 %r - US-Zeit - 03:32:44 PM %c - US-Datum und Zeit: Sun May 20 15:32:44 2012
■ Sonderzeichen %% - Prozent- Zeichen % %n - neue Zeile %t - Tabulator |
|
|
♦ Details zum Thema Zeitzone auf dieser Seite. |
Genaue Zeitmessung mit Time::HiRes |
|
|
Manchmal ist es notwendig, Zeiten genauer als auf 1 sec zu messen.
In solchen Fällen geht es meistens um die genaue Differenz
von Zeitpunkten. ► Perl bietet dazu das Modul Time::HiRes, das Zeitpunkte in µs (Mikrosekunden) verarbeitet ... ► Funktion gettimeofday() liefert ein Array von 2 Elementen (jeweils ganze Zahlen): [0] UNIX-Timestamp in s = Sekunden seit Neujahr 1970-01-01 [1] µs (Mikrosekunden) seit der letzten vollen Sekunde. |
use Time::HiRes qw(gettimeofday);
my(@a); @a = gettimeofday(); $s = $a[0];
$us = $a[1];
print "Timestamp = $s + $us us\n";
|
|
►
Zur Messung wird sie die Differenz zwischen Anfangs- und Endzeit bestimmt.
Kleine Intervalle werden oft wiederholt, um sie messbar zu machen. ► Im Beispiel rechts dient eine for--Schleife mit eingebauten Test-Befehlen als 'Verzögerung'. ► Typische Zeiten für einfache Schleifen liegen je nach PC bei 10-1000 µs, man muss daher die Schleife ziemlich oft durchlaufen, um >1 Sekunde zu erreichen. ► Nach Ablauf des Tests wird die Differenz gebildet und durch die Anzahl der Schleifen-Durchläufe dividiert. |
@a = gettimeofday();
$s_anf = $a[0]; $us_anf = $a[1];
for($i=0;$i<$imax;$i++) {
# Test-Befehle
}
@a = gettimeofday();
$s_end = $a[0]; $us_end = $a[1];
$us_dif = ($s_end - $s_anf)*1000000;
$us_dif+=($us_end - $us_anf); $us_mw = $us_dif/$imax;
print "Mittelwert = $us_mw us\n";
|
| ► Wenn sie eine Leer-Schleife ohne Test-Befehle messen und getrennt davon eine Schleife mit Befehlen, so erhalten sie brauchbare Werte für jene Zeit, welche auf das 'Zeit-Konto' der Test-Befehle geht. | ► Ideal sind Messzeiten von 1 bis 2 s. Wiederholen sie die Messung, denn manchmal wird das Programm durch Interrupts 1-2 ms 'aufgehalten' - Das Betriebssystem hat sich in dieser Zeit um andere Aufgaben gekümmert. |
| ► Versuchen sie nicht, Sekunden und ihre Bruchteile in einer einzigen 32-Bit-Variablen zu speichern. Das übersteigt die speicherbare → Genauigkeit und ergibt unsinnige Resultate. | ♦ Details zu diesem Thema und zu den anderen Funktionen dieses Moduls bietet die Perl-Dokumentation unter Stichwort Modules | Time | HiRes |
Systemzeit |
|
|
Perl wird häufig zur Systemverwaltung eingesetzt. Deshalb wird hier vorgestellt, wie die Systemzeit geändert wird. Die Zeit-Information kann aus verschiedenen Quellen stammen, z.B. aus einer → NTP-Anfrage, aus einer → Webseite oder noch einfacher aus dem → HTTP-Header einer Webseite. |
Linux:
$mytime = "15:32:44";
$cmd = "date --set=$mytime"; system($cmd);
Zugriffsrechte:
Auf Linux haben nur privilegierte User das Recht, die Systemzeit zu ändern.
Da Webserver dieses Recht (besser) nicht haben, werden solche Scripts normalerweise
nicht als CGI-Webseite, sondern als 'standalone'-Scripts ausgeführt.
|
|
Mit →
Funktion system() werden Perl-Befehle an die
→
Linux-Shell oder an die
→
Windows-Konsole (cmd.exe) weitergegeben. ♦ Details zum Thema Datum & Zeit auf Windows |
Windows:
15:32:44 = "15:32:44";
$cmd = "time $mytime"; system($cmd);
|
|
Lesen der Systemzeit: Die ↑ Funktion time liefert einen Timestamp der aktuellen Systemzeit. Mit den ↑ Funktionen gmtime oder localtime kann man daraus Datum- und Zeit-Bestandteile entnehmen. ↑ Funktion strftime erzeugt einen beliebig formatierten Ausgabe-Text. |
Alle erwähnten Funktionen werden in eigenen Kapiteln dieser Seite demonstriert. Die dabei angezeigten Live-Daten sind jeweils Datum & Zeit des → Webservers, da sowohl Perl-CGI-Scripts als auch PHP-Scripts am Webserver ausgeführt werden. |
Zeitzone |
|
|
Jedes Betriebssystem ist auf eine bestimmte Zeitzone eingestellt, d.h. auf eine
Differenz zur Weltzeit UTC (früher GMT). Moderne Betriebssysteme verfügen
zusätzlich über eine Datenbank mit Angaben über andere Zeitzonen und die
dort angewendeten Regeln (z.B. Sommerzeit). ● Die Differenz zwischen Lokalzeit und Weltzeit (TimeZoneOffset TZO) ist variabel nach Ort und Datum. Sie wird meist in Stunden oder Minuten angegeben.
●
Aktuelle TZO (Mitteleuropa) = 2 Stunden
|
Das Thema Zeitzone erlaubt u.a. folgende Fragen (in Reihenfolge abnehmender Wichtigkeit): • Welche TZO gilt jetzt am eigenen PC und welche Lokalzeit ergibt das ? • Welche TZO gilt am eigenen PC an einem anderen Datum ? • Welche TZO gilt in einer anderen Zeitzone an einem beliebigen Datum ? ♦ Details zu Datum & Zeit, speziell auf Linux & Windows |
Aktuelle ZeitdifferenzDas Beispiel rechts zeigt 2 verschiedene Möglichkeiten zur Ermittlung des aktuellen TimeZoneOffset (TZO).Bei korrekt eingestellter Zeitzone liefert die unter 'Standard' angeführte Methode korrekte Werte. Das Beispiel rechts zeigt, wie man das Problem umgehen kann. Auf Windows wird der aktuelle Wert aus der Registry-Datenbank gelesen. Die → Registry-Funktion liefert einen Hexadezimal-String, der mit Funktion reg_dword() (unten) decodiert wird. Danach wird der Zahlenwert in positive Stunden umgerechnet. Mit Hilfe dieses Zahlenwerts kann man die Lokalzeit auch auf Windows korrekt angeben, z.B.
$t = time()+$tzoh*3600;
$iso = strftime("%H:%M:%S",gmtime($t)); print "Lokalzeit = $iso\n"; Auf → Linux braucht man den Offset normalerweise nicht, da alle Programme diese Daten aus der Zeitzonen-Datei des Betriebssystems beziehen. Das Beispiel zeigt eine Möglichkeit der Berechnung aus der Differenz zwischen Lokalzeit und Weltzeit UTC. |
TimeZone Offset in Stunden relativ zu UTC::
sub get_tzoh {
my $tzoh=0;
}if($^O=~m/win/i) { # Windows
use Win32::TieRegistry;$Registry->Delimiter('/'); my $rk='HKEY_LOCAL_MACHINE/SYSTEM'; $rk.='/CurrentControlSet'; $rk.='/Control/TimeZoneInformation'; $rk.='//ActiveTimeBias'; my $rd = $Registry->{$rk}; $tzoh = reg_dword($rd); $tzoh = -$tzoh/60; else { # Standard
my @da = localtime(time);my @db = gmtime(time); $tzoh = $da[2]-$db[2]; return $tzoh; sub reg_dword {
my ($r)=@_;
}
my $rn = hex($r); if($rn & 0x80000000) {$rn=$rn-0xFFFFFFFF-1;} return $rn; |
Windows System-VariableDie gezeigte Variante - Lesen benötigter Daten aus der Registry - muss man für jede Anwendung erneut durchführen.Eine dauerhafte Lösung für dieses und ähnliche Probleme ist das Anlegen von Umgebungs-Variablen. ● Vorteile: • Die Umgebungs-Daten stehen für alle Programe zur Verfügung, insbesondere auch für jene, die nicht auf die Registry zugreifen können. • Die Daten stehen für alle User zur Verfügung (Kontrollieren sie das sicherheitshalber !) ● Nachteile: • Änderungen der System-Variablen werden erst nach System-Neustart wirksam. • Das Programm muss jedesmal ausgeführt werden, wenn sich die Daten geändert haben. Im Falle von TZOH führt man das Programm am besten automatisch bei System-Start aus. |
Anlegen der Windows System-Variablen TZ und TZOH
Vorsicht: Die unbedachte Änderung von Registry-Daten kann Betriebssystem,
Programme oder Daten beschädigen oder zerstören !
use Win32::TieRegistry;
Die Funktion get_tzoh() wird im ↑
Absatz oberhalb vorgestellt.my $renv = 'HKEY_LOCAL_MACHINE/SYSTEM/'; $renv.='CurrentControlSet/Control'; $renv.='/Session Manager/Environment'; $tzoh = get_tzoh(); # Offset der Lokalzeit in Std
$Registry->{$renv.'/TZOH'} = $tzoh;
# Zeitzone
$Registry->{$renv.'/TZ'}='Europe/Vienna';
Die Änderung der Registry-Daten wird erst nach System-Neustart wirksam ! Kontrolle z.B. an der → Konsole cmd.exe C:\> set t
|
Datei - Informationen |
|
|
■
Für jedes Verzeichnis (Ordner) und jede Datei werden vom Dateisystem einige
Datum & Zeit - Daten geführt, üblicherweise Erstellungszeit
(creation), letzte Änderung (modification)
und letzte Verwendung (access). ■ Diese Daten sind mit der Perl-Funktion stat() zugänglich, die ohne Zusatz-Modul immer zur Verfügung steht. ■ Als Argument zur Identifikation der Datei dient entweder ein → File-Handle (z.B. von einer bereits geöffneten Datei) oder ein String mit dem Datei-Pfad. Beachten sie bei Windows-Pfaden die notwendige Maskierung der \-Zeichen ! ■ Funktion stat() liefert ein Array von 13 Elementen (Beschreibung unter Linux mit perldoc -f stat). Die Elemente 8, 9, 10 enthalten UNIX-Timestamps, die im Beispiel mit localtime() decodiert und mit strftime() formatiert werden. Element 10 liefert die 'inode change time', nicht identisch mit der Erstellungszeit, aber meistens dafür verwendet.. |
# Linux-Pfad:
$fp = '/home/test/test.xyz':# Windows-Pfad:
$fp = "C:\\test\\test.xyz";
# Format-string für strftime
$fmt = '%Y-%m-%d %H:%M:%S';
# Access time:
$p = (stat($fp))[8];
$p = strftime($fmt,localtime($p));print "Last access time = $p \n"; |
|
Weitere Daten bieten einige Datei-Test-Operatoren, von denen es eine ganze Reihe gibt. Eine übersichtliche Liste der Operatoren bietet u.a. |
# Zugriffszeit in Tagen
$tzu = -A $inpath;
# Unverändert seit Tagen
$tun = -M $inpath;
|
Perl-Module |
|
|
Perl bietet zahlreiche spezialisierte Module mit zusätzlichen Funktionen. ► Auf Linux verwendet man die Service-Programme der jeweiligen Distribution zur Installation (auf SuSE YAST | Software). ► Auf Windows öffnen sie ein Konsolen-Fenster cmd.exe und starten den Perl Package Manager: C:\> ppm
♦ Details zum Package Manager bei der
→ Perl-Installation auf Windows.► Unterscheiden sie zwischen Perl-Modulen, die auch bei ihrem Web-Provider geladen sind und solchen für den Gebrauch am eigenen PC. Erstere kann man für (öffentliche) Webseiten verwenden, letztere nur am eigenen PC und im eigenen Netzwerk. |
●
Das wichtigste Perl-Modul zum Thema Datum & Zeit ist das
→ Modul Date.
Eine Auswahl seiner Funktionen wird auf einer eigenen
Webseite vorgestellt. Die beiden Stichworte date, time liefern jeweils >100 Module, jedes davon mit mehreren Funktionen und/oder Daten. Weitere sinnvolle Stichworte:
8601, benchmark, calend, clock, cron, date/time, day, duration, easter,
elapsed, file time, holiday, hour, interval, iso, julian, leap, minute,
schedule, second, stamp, timezone, utc, wait, week, ...
|
|
|
SelfHTML:
Daytime, Sockets und Perl
|
Perl.com: The many dates & times of Perl |
|
Letzte Änderung dieser Seite: 2011-12-01 08:54:25
|