Subject: [xsl] Timezone concept broken in XPath 2.0? From: Michael Ludwig <mlu@xxxxxxxxxxxxx> Date: Wed, 05 Nov 2008 19:37:29 +0100 |
On the Saxon mailing list, I read the following statement by Michael Kay in reply to someone who had relied on XPath 2.0 timezone adjustment functions and found them to yield incorrect results after a recent change back from DST:
adjust-dateTime-to-timezone() with one argument adjusts the time to the "implicit timezone", which is initialized to the time zone offset of the machine (or more precisely, the current user's locale). Whereas you want to adjust it to whatever the civil timezone was at the time in question. That requires knowledge that Saxon doesn't have available - daylight savings time starts/ends in different parts of the world on different dates, and Saxon doesn't know which part of the world you are in.
Forgive the DPH who is posting Perl, and consider how timezone and DST intricacies are automatically and reliably handled by standard library functions, which are, dare I say, timezone-aware:
MiLu@FLUNDER:~ > cat sommerzeit.pl use strict; use warnings; $ENV{TZ} = shift || 'Europe/Berlin'; # timezone parameter my $ts_switch = 1224980000; # 26.10.2008 00:13:20 UTC my $sec_delta = shift || 0; # delta in seconds my $ts_start = $ts_switch + $sec_delta; my $ts_end = $ts_start + 5000; while ( $ts_start < $ts_end ) { print $ts_start, "\t", scalar localtime $ts_start, "\n"; $ts_start += 1000; }
MiLu@FLUNDER:~ > perl sommerzeit.pl 1224980000 Sun Oct 26 02:13:20 2008 1224981000 Sun Oct 26 02:30:00 2008 1224982000 Sun Oct 26 02:46:40 2008 1224983000 Sun Oct 26 02:03:20 2008 <<--<< switch back 1224984000 Sun Oct 26 02:20:00 2008
MiLu@FLUNDER:~ > perl sommerzeit.pl Europe/Moscow -7200 1224972800 Sun Oct 26 02:13:20 2008 1224973800 Sun Oct 26 02:30:00 2008 1224974800 Sun Oct 26 02:46:40 2008 1224975800 Sun Oct 26 02:03:20 2008 <<--<< switch back 1224976800 Sun Oct 26 02:20:00 2008
As you can see, the C library Perl uses (more precisely, the timezone database) knows that we switched back from summertime to wintertime in Germany ten days ago. If I pretend I was in Moscow, I can see that they did the same thing in that part of Russia two hours earlier (with respect to UTC). So the C library knows its way around the intricacies of the world's timezones. There is no need for the user of this library to keep track of this data - everything is taken care of. This is really nice to use.
This is possible because the concept of a timezone is not simplistically reduced to a timezone offset, as it seems to happen in XPath 2.0. Instead, timezone-awareness is built into functions like localtime().
In Saxon, this shortcoming of XPath 2.0 can be overcome by resorting to saxon:in-summer-time() and then manually adjusting the time by one hour.
Still, this sounds like a bit of a hack to me. There should be no need to manually specify how many seconds are reeled in or out when making the DST switch. Generally, it's a full hour, but who knows? Consider that Kabul deviates from UTC by +4:30 and Kathmandu by +5:45, so someone might also have DST deviate by partial hours, and then duration arithmetics using +/-PT1H falls flat on its nose.
# more /t2 timezone.xml <Urmel> <!-- Epoch seconds and W3C dates are equivalent here. $ date -u -d @1224980000 # using the UNIX date utility Sun Oct 26 00:13:20 UTC 2008 --> <W3CDate epoch="1224980000">2008-10-26T00:13:20Z</W3CDate> <W3CDate epoch="1224981000">2008-10-26T00:30:00Z</W3CDate> <W3CDate epoch="1224982000">2008-10-26T00:46:40Z</W3CDate> <W3CDate epoch="1224983000">2008-10-26T01:03:20Z</W3CDate> <W3CDate epoch="1224984000">2008-10-26T01:20:00Z</W3CDate> </Urmel>
# saxon timezone.xml timezone.xsl 2008-10-26 0:13:20 Z 2008-10-26 1:13:20 +01:00 2008-10-26 0:30:00 Z 2008-10-26 1:30:00 +01:00 2008-10-26 0:46:40 Z 2008-10-26 1:46:40 +01:00 2008-10-26 1:03:20 Z 2008-10-26 2:03:20 +01:00 2008-10-26 1:20:00 Z 2008-10-26 2:20:00 +01:00
I'm using the implicit timezone, which is Europe/Berlin, which right now (all of today, 05.11.2008, Gregorian calendar) happens to materialize as UTC+01:00. But this is now - two weeks ago it was UTC+02:00. That's why the first three lines of the output are wrong. DST was still in effect.
* adjust-date-to-timezone * adjust-dateTime-to-timezone * adjust-time-to-timezone
These functions don't hold what their names promise. The failure is in shortcutting the timezone to a xs:dayTimeDuration. An xs:dayTimeDuration is insufficient for this task.
A timezone database should be used, as saxon:in-summer-time() does. Every platform has one, I guess. Why aren't the functions specified to use a timezone database and then work like timezone-aware localtime() in Perl and C?
There are about 25 functions related to dates and times in the XPath 2.0 function library, but none of them seems to address this very common requirement of localizing temporal data. Instead, what XPath 2.0 sells as timezone adjustment is more like performing addition and substraction with temporal data, and in many parts of the world, this looks broken twice a year. Is it?
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] Image overflow in FOP, Sebastien | Thread | Re: [xsl] Timezone concept broken i, Deborah Pickett |
RE: [xsl] XPath "//", speed, and Sa, Lars Huttar | Date | Re: [xsl] Image overflow in FOP, J.Pietschmann |
Month |