Discussion:
Zeitzone: Sommer-/Winterzeit - Modul?
(zu alt für eine Antwort)
Thomas Wittek
2004-10-06 10:44:13 UTC
Permalink
Ich schreibe gerade einen RSS 2.0-Export für meine Blogging-Engine.
Dort werden Datumsangaben ja derart formatiert:
<dc:date>2004-10-06T12:17+02:00</dc:date>
Also gemäß http://www.w3.org/TR/NOTE-datetime
Mein Problem liegt jetzt in der Angabe der Zeitzone "+02:00".
Hier müsste ich bei Mitteleuropäischer Sommerzeit +02:00 und bei
Winterzeit +01:00 angeben.
Die Regeln dafür findet man z.B. hier:
http://www.zeitumstellung.de/regeln-zeitumstellung.htm
Die sind jedoch ein wenig umständlich, also habe ich mich gefragt, ob es
da nicht ein fertiges Perl-Modul gibt, das mir zu "Datum + Zeitzone" die
Verschiebung in Stunden angibt.
date -R
gibt die aktuelle Verschiebung auf dem System an. Aber ich brauche ja
nicht die aktuelle, sondern diejenige zu einem gegebenen Zeitpunkt != jetzt.

Jemand ne Idee?

Danke!
-Thomas
Thomas Wittek
2004-10-06 11:00:10 UTC
Permalink
Post by Thomas Wittek
...
Die sind jedoch ein wenig umständlich, also habe ich mich gefragt, ob es
da nicht ein fertiges Perl-Modul gibt, das mir zu "Datum + Zeitzone" die
Verschiebung in Stunden angibt.
...
Dank, hab schon selbst ne Lösung gestrickt:

#perl -w
use strict;
use Time::Local;

#Eingabezeit: z.B.
my ($sec,$min,$hour,$mday,$mon,$year) = localtime(time);

#Differenz berechnen
my $time = timelocal($sec,$min,$hour,$mday,$mon,$year);
my $diff = ((localtime($time))[2] - (gmtime($time))[2]);

#Ausgabe
printf("+%2.2d:00", $diff);
Martin Herrmann
2004-10-07 09:39:40 UTC
Permalink
Post by Thomas Wittek
Post by Thomas Wittek
...
Die sind jedoch ein wenig umständlich, also habe ich mich gefragt, ob es
da nicht ein fertiges Perl-Modul gibt, das mir zu "Datum + Zeitzone" die
Verschiebung in Stunden angibt.
...
#perl -w
use strict;
use Time::Local;
#Eingabezeit: z.B.
my ($sec,$min,$hour,$mday,$mon,$year) = localtime(time);
#Differenz berechnen
my $time = timelocal($sec,$min,$hour,$mday,$mon,$year);
my $diff = ((localtime($time))[2] - (gmtime($time))[2]);
#Ausgabe
printf("+%2.2d:00", $diff);
Vorsicht, wenn $diff negativ wird, ergibt das z.B. "+-02:00".
Bastel-Loesung 1:
my $plus = "+"; $plus = "" if ($diff < 0);
my $GMToffset = sprintf("%s%2.2d:00", $plus, $diff);

Bastel-Loesung 2:
my $GMToffset = sprintf("%s%2.2d:00", $plus, $diff);
$GMToffset = "+$GMToffset" if ($diff >= 0);

Gruss
Martin
Christian Lackas
2004-10-07 09:53:36 UTC
Permalink
* Martin Herrmann [2004-10-07]:

Hallo Martin,
Post by Martin Herrmann
Post by Thomas Wittek
printf("+%2.2d:00", $diff);
Vorsicht, wenn $diff negativ wird, ergibt das z.B. "+-02:00".
my $plus = "+"; $plus = "" if ($diff < 0);
my $GMToffset = sprintf("%s%2.2d:00", $plus, $diff);
oder auch gleich:

$ perl -we 'printf "%+03d:00 %+03d:00\n", +2, -1'
+02:00 -01:00

BTW: Was soll das '%2.2d' heissen? Ganze Zahlen haben idR keinen
Nachkomma-Anteil.

Weitere Details findet sich in

perldoc -f sprintf
printf(3)

Gruss
Christian
--
Götterspeise zum Abendmahl.
http://www.lackas.net/ Perl Delphi Linux MP3 Searchengines Domainchecker
Thomas Wittek
2004-10-07 12:03:32 UTC
Permalink
Mein genaues Ergibnis sieht mittlerweile (als Methode eines Objektes) so
aus:


#= &w3c_date_time
#
# Description:
# Returns the difference between a specified local time and UTC
#
# Arguments:
# $year - Either the years since 1900 (e.g. 1996 = 96, 2004 = 104) or
# the absolute year (e.g. 1996)
# $month - Jan = 1, Feb = 2, ...
# $mday - 1,2,3,...
# $hour
# $minute
# $second
#
# Returns:
# The diffence in the format as specified in
# http://www.w3.org/TR/NOTE-datetime
# YYYY-MM-DDThh:mm:ssTZD
#
sub w3c_date_time {
my ($self, $year, $mon, $mday, $hour, $min, $sec) = @_;

#adjust date to fit into timelocal/localtime
$year -= ($year > 1900 ? 1900 : 0);
$mon -= 1;
$sec |= 0;

use Time::Local;
my $time = timelocal($sec, $min, $hour, $mday, $mon, $year);
my $diff = ((localtime($time))[2] - (gmtime($time))[2]);

#readjust date to get it human readable
$year += 1900;
$mon += 1;

#format date
$time = sprintf("%.4d-%.2d-%.2dT%.2d:%.2d:%.2d".
($diff < 0 ? '-' : '+')."%.2d:00",
$year, $mon, $mday, $hour, $min, $sec, $diff);

return $time;
}
#
#= /&w3c_date_time

Grüße,
-Thomas
Thomas Wittek
2004-10-07 12:06:46 UTC
Permalink
Post by Thomas Wittek
# Returns the difference between a specified local time and UTC
richtig waere hier:
# Description:
# Returns the specified local time in the w3c date/time format

:)
Fabian Pilkowski
2004-10-07 15:43:52 UTC
Permalink
Post by Thomas Wittek
Mein genaues Ergibnis sieht mittlerweile (als Methode eines Objektes) so
sub w3c_date_time {
#adjust date to fit into timelocal/localtime
$year -= ($year > 1900 ? 1900 : 0);
$mon -= 1;
$sec |= 0;
use Time::Local;
my $time = timelocal($sec, $min, $hour, $mday, $mon, $year);
my $diff = ((localtime($time))[2] - (gmtime($time))[2]);
#readjust date to get it human readable
$year += 1900;
$mon += 1;
#format date
$time = sprintf("%.4d-%.2d-%.2dT%.2d:%.2d:%.2d".
($diff < 0 ? '-' : '+')."%.2d:00",
$year, $mon, $mday, $hour, $min, $sec, $diff);
return $time;
}
Du gehst hier gar nicht auf Christians Anmerkung ein. Ich wiederhole:

* Es gibt keine ganzen Zahlen mit Nachkommastellen (auch wenn Perl
Dein fragwuerdiges Konstrukt richtig umsetzt - wer weiss warum?)
* Es gibt eine schoene Moeglichkeit, dem sprintf() das jeweils
korrekte Vorzeichen beizubringen

Also:

$time = sprintf '%04d-%02d-%02dT%02d:%02d:%02d%+02d:00',
$year, $mon, $mday, $hour, $min, $sec, $diff;

gruss,
fabian
Thomas Wittek
2004-10-07 17:30:04 UTC
Permalink
Post by Fabian Pilkowski
* Es gibt keine ganzen Zahlen mit Nachkommastellen (auch wenn Perl
Dein fragwuerdiges Konstrukt richtig umsetzt - wer weiss warum?)
* Es gibt eine schoene Moeglichkeit, dem sprintf() das jeweils
korrekte Vorzeichen beizubringen
$time = sprintf '%04d-%02d-%02dT%02d:%02d:%02d%+02d:00',
$year, $mon, $mday, $hour, $min, $sec, $diff;
Das Problem ist, dass ich s?printf nur aus der Doku aus dem Kamelbuch
kenne und es da nur sehr spartanisch beschrieben ist. C(\+\+)? hab ich
noch nicht gelernt, daher awr ich gezwungen etwas zu experimentieren und
das war das Ergebnis :)
$ perldoc -f sprintf
liefert hier leider
No documentation found for "perlfunc".
Hab perl als debian-paket installiert, das paket perl-doc ist auch
installiert, aber die perlfunc-Sektion fehlt aus mir unerklaerlichen
Gruenden.

Wo findet man denn eine gute Doku zu printf?
Was bedeutet die 0 vor der Laengenangabe in den printf-Symbolen?

Danke,
-Thomas
Marc Lucksch
2004-10-07 18:12:21 UTC
Permalink
Post by Thomas Wittek
Wo findet man denn eine gute Doku zu printf?
Was bedeutet die 0 vor der Laengenangabe in den printf-Symbolen?
Danke,
-Thomas
geht man perlfunc?
Wahrscheinlich aber nicht

Gute Doku:
Online:

www.perldoc.com

Die 0 bedeutet:
anstatt
" 1" ("%3d")
schreibt er
"001" ("%03d")
--
$_='';s%%`^.*`s;.*;uhtnmo;;a>lha~a>inu~a>fmk~a>rou~a>duM~a>btl~s;&&&&&&;!d1!l2!b3!i4!f5!r6q(?);e;Z`
`}a>&&&`sub# "1#{#"_=shift#;s^"2^"3#^;``;~`return
#"_#}``^!&&`"1(#""2)#\.`Z%;
s~Z~print~g;s/#/\\/g;s/`(.)(.+?)`(.+?)`/s$1$2$1$3$1g\;/g;s;&;(.);g;y^"^$^;print;
Florian Diesch
2004-10-08 14:36:27 UTC
Permalink
Post by Thomas Wittek
Hab perl als debian-paket installiert, das paket perl-doc ist auch
installiert, aber die perlfunc-Sektion fehlt aus mir unerklaerlichen
Gruenden.
In perl-doc_5.8.4-2.3 (sarge) ist es dabei
Post by Thomas Wittek
Wo findet man denn eine gute Doku zu printf?
man printf (manpages-dev)



Florian
--
begin signature_virus
Hi! I'm a signature virus. Please copy me to your signature to help me spread.
end
Loading...