Berechnen der Zeitzone mit Perl

Für manche Programmiersprachen muss die Zeitzone eingegeben werden, mit Perl kann man sie berechnen

Die Zeitzone drückt die Differenz zwischen localtime() und gmtime() aus. Wenn mit der Zeitzone gerechnet werden soll, muss sie in einer definierten Zeiteinheit vorliegen. Betrachte untenstehenden Code, welcher die Zeitzone in Sekunden berechnet:

# returnvalue in seconds
sub zeitzone{
    my $self = shift;
    my $lo = [localtime(12*3600)];
    my $raw = ($lo->[3]- 1) * 86400 + $lo->[2] * 3600 + $lo->[1] * 60 + $lo->[0];
    return $raw - 43200;
}

Alle Zeitzonen dieser Welt erstrecken sich von -12 (westliche Datumsgrenze) bis +13 Stunden bezogen auf UTC bzw. GMT. Zum Vereinfachen der Zeitzonenberechnung wird in obenstehender Funktion mit localtime(12*3600) gegenüber 1970-01-01 00:00:00 ein definierter Vorlauf geschaffen was die Berechnung vereinfacht. D.h., über alle möglichen Zeitzonen hinweg ändert sich mit diesem Vorlauf maximal der Tag, womit Jahr und Monat aus der Berechnung rausfallen.

Hinweis: In der Zeitzone ist DST (Sommerzeit) implizit enthalten. Da sie jedoch länderspezifisch zu unterschiedlichen Zeiten eingeführt wurde, liefert die Funktion localtime() mit unterschiedlichen Zeitstempel auch unterschiedliche Ergebnisse. Aktuell auf diesem Server ist eine Zeitzone von GMT +1.00 Stunden (3600 Sekunden) eingestellt.

Obenstehende Funktion berechnet die Zeitzone zum Zeitpunkt 2.1.1970. Sofern DST zu diesem Zeitpunkt gilt, geht dies in die Berechnung der Zeitzone ein, was aber nur auf Länder der südlichen Halbkugel zutrifft. Mit dem CODE untenstehend hingegen erfolgt die Berechnung der Zeitzone mit der aktuellen Zeit:

use Time::Local;
print timegm(localtime) - time;

Berechnung über Julianische Tage

Untenstehend eine andere Methode zur Berechnung der Zeitzone. Über die Julianischen Tage, berechnet nach Scaliger, werden die sich aus gmtime und localtime ergebenden Sekunden berechnet sowie die sich daraus ergebende Differenz.

use strict;
use warnings;
use Scaliger;

# ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)
my @fields = qw(sec min hour mday mon year wday yday isdst);
my $gmt = do{
    my %t = ();
    @t{@fields} = gmtime;
    $t{mon} += 1;
    $t{year} += 1900;
    \%t;
}; 

my $loc = do{
    my %t = ();
    @t{@fields} = localtime;
    $t{mon} += 1;
    $t{year} += 1900;
    \%t;
}; 

# Julianische Tage nach Scaliger
my $sca_loc = Scaliger->new( date => "$loc->{mday}.$loc->{mon}.$loc->{year}");
my $sca_gmt = Scaliger->new( date => "$gmt->{mday}.$gmt->{mon}.$gmt->{year}");

# Sekunden
my $sec_gmt = $sca_gmt->jd * 86400 + $gmt->{hour} * 3600 + $gmt->{min} * 60 + $gmt->{sec};
my $sec_loc = $sca_loc->jd * 86400 + $loc->{hour} * 3600 + $loc->{min} * 60 + $loc->{sec};

print $sec_loc - $sec_gmt;

Abfrage der Zeitzone per Win32::Registry

use strict;
use warnings;
use Win32::Registry;

my $hand;
my $path = quotemeta('SYSTEM\CurrentControlSet\Control\TimeZoneInformation');
$::HKEY_LOCAL_MACHINE->Open($path, $hand) or die $^E;
$hand->QueryValueEx("ActiveTimeBias", my $type, my $value) or die $^E;

# Sommerzeit inbegriffen
print 1 + 0xFFFFFFFF - $value;

Datenschutzerklärung: Diese Seite dient rein privaten Zwecken. Auf den für diese Domäne installierten Seiten werden grundsätzlich keine personenbezogenen Daten erhoben. Das Loggen der Zugriffe mit Ihrer Remote Adresse erfolgt beim Provider soweit das technisch erforderlich ist. s​os­@rolf­rost.de.