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

UtilFaqSubForm edit

Titel Wie finde ich das Datum von gestern?
Autor TinaMueller
Bereich FaqAllgemeines
Topic revision: r6 - 2006-01-04 - 23:23:58 - SteffenWinkler
 
Bitte die NutzungsBedingungen beachten.
Bei Vorschlägen, Anfragen oder Problemen mit dem PerlCommunityWiki bitten wir um WebBottomBarExample">Rückmeldung.