Wie finde ich das Datum von gestern?
Inhalt:
Problem
Du brauchst das Datum von gestern, morgen oder von vor einem Jahr. Du könntest einfach 86400 Sekunden abziehen, aber leider hat nicht jeder Tag 86400 Sekunden (Zeitumstellung), so dass man an bestimmten Tagen fehlerhafte Werte bekommt. Es gibt verschiedene Möglichkeiten, ein korrektes Ergebnis zu bekommen. Hier ein paar Beispiele für das Datum von gestern.
POSIX
Beispiel von ptk in perl.de:
use POSIX qw(mktime);
my @l = (0,30,0,28,3-1,2005-1900);
$l[3]--;
print scalar localtime mktime @l;
DateTime?
use DateTime;
my $dt = DateTime->new(
year => 2005,
month => 3,
day => 28,
hour => 0,
minute => 12,
second => 47,
);
print $dt;
my $d = DateTime::Duration->new(
days => 1,
);
print $dt - $d;
Date::Calc
Mit Date::Calc verwendet man typischerweise ein ($y,$m,$d)-Tupel für das Datum. Die Berechnung des gestrigen Datums erfolgt dann so:
use Date::Calc qw(Add_Delta_Days);
($year,$month,$day) = Add_Delta_Days($year,$month,$day, -1);
Date::Manip
Mit Date::Manip erhält man Zeitpunkte im Format "YYYYMMDDhh:mm:ss". Die Berechnung des Zeitpunktes, jetzige Uhrzeit aber gestern funktioniert mit diesem Modul z.B. so:
use Date::Manip; Date_Init qw(Language=English DateFormat=non-US TZ=UT); # use und Initialisierung
...
$yesterday = ParseDate('yesterday');
$yesterday = ParseDate('-1 day'); # ist das gleiche Ergebnis
# formatieren z.B. in: "DD.MM.YYYY hh:mm:ss"
$yesterday =~ s/^(....)(..)(..)(.+)/$3.$2.$1 $4/);
Neu berechnen
Man schaut sich die Stunde des berechneten Ergebnisses an und berechnet ggfs. neu. Man sollte beachten, das bei dieser Lösung die Uhrzeiten des Ergebnisses unterschiedlich von der ursprünglichen Uhrzeit sein können.
print scalar localtime $heute;
my $gestern = $heute - $sek;
my $hour_h = (localtime $heute)[2];
my $hour_g = (localtime $gestern)[2];
my $day_h = (localtime $heute)[3];
my $day_g = (localtime $gestern)[3];
if ($day_h - $day_g != 1) {
if ($hour_h < $hour_g) {
$gestern += 60*60;
}
elsif ($hour_g < $hour_h) {
$gestern -= 60*60;
}
}
print scalar localtime $gestern;
Einfache Variante ohne Uhrzeit
Man berechnet vom gegebenen Datum ungefähr die Mittagszeit nach Vorschlag von Crian
my $datum = ...;
my $stunde = (localtime $datum)[2];
my $diff = 12 - $stunde;
$datum += 60*60*$diff;
$datum -= 60*60*24;
Ergänzungen, Kommentare
Schaltsekunden
Es gibt Tage, die um ein bis zwei Schaltsekunden länger als 60*60*24 Sekunden sind --- ich (
PlTk?, ptk) nehme an,
dass das Betriebssystem sich dieser
Anomalien annehmen kann und die POSIX-Funktionen (mktime, localtime, strftime) darauf eingestellt sind.
Warum wird hier von Uhrzeiten ausgegann?
Wenn man wirklich nur am Datum interessiert ist, könnte man doch auch von "heute", 12 Uhr Mittags einfach 60*60*24 Sekunden abziehen und das dazu passende Datum ermitteln.
re: Warum wird hier von Uhrzeiten ausgegann?
Da hast du recht. Ist man nicht an der Uhrzeit interessiert, ist es einfacher.
--
TinaMueller
Anderer Ansatz
Ich hab in einem Modul von mir einen ganz anderen Ansatz gefahren. Das Modul kennt die Monatslängen und Schaltjahre und kann mit deren Hilfe "einfach" berechnen, wie man zum Datum heute - x oder heute + y kommt.
Kommentare werden am besten in folgender Form vorgenommen, damit
sie im Inhaltsverzeichnis angezeigt werden (natürlich ohne das <verbatim>):
---+++ Main.??? - 14 Jul 2003 - Betreff