"adjust-dateTime-to-timezone" without the second parameter will convert a
dateTime to the implicit timezone which, in Saxon 9.3 at least, seems to be
the UTC offset currently applying on the computer running the stylesheet. Hence
"adjust-dateTime-to-timezone(current-dateTime())" will return local time
accurately.
However, if summertime or DST applies in a particular territory and a
datetime, that falls outside the period the current UTC offset is in force, is
passed into "adjust-dateTime-to-timezone", then the result is not the
localtime representation of the datetime value. Is this a bug, a design
decision or an ambiguity?
I did bingle around for how to convert an arbitrary datetime into localtime
but I couldn't find any so I had a go at writing my own. It turns out writing a
custom function for Summertime/DST isn't that difficult as the format-date
function can return the day of the week for a given date which can then be
used to extrapolate the dates at the weekends at which the UTC offset changes.
Here is my function:
<!-- adjusts a dateTime to UK local time account for GMT/BST -->
<xsl:function name="mynamespace:adjust-dateTime-to-uk-local-time"
as="xs:dateTime">
<xsl:param name="DATETIMEIN" as="xs:dateTime"/>
<xsl:variable name="ADJUSTGMT" select="adjust-dateTime-to-
timezone($DATETIMEIN, xs:dayTimeDuration('PT0H'))"/>
<!-- BST starts at 1 a.m UTC on last Sunday in March -->
<xsl:variable name="BSTSTARTS" select="xs:dateTime(concat(year-from-
dateTime($ADJUSTGMT), '-03-',
31 - xs:integer(replace(replace(replace(replace(replace(replace(replace(
format-date(xs:date(concat(year-from-dateTime($ADJUSTGMT), '-03-31Z')),
'[Fn, 2-2]')
, 'su', '0'), 'mo', '1'), 'tu', '2'), 'we', '3'), 'th', '4'), 'fr', '5'),
'sa', '6')),
'T01:00:00Z'))" as="xs:dateTime"/>
<!-- BST ends at 1 a.m UTC on last Sunday in October -->
<xsl:variable name="BSTENDS" select="xs:dateTime(concat(year-from-
dateTime($ADJUSTGMT), '-10-',
31 - xs:integer(replace(replace(replace(replace(replace(replace(replace(
format-date(xs:date(concat(year-from-dateTime($ADJUSTGMT), '-10-31Z')),
'[Fn, 2-2]')
, 'su', '0'), 'mo', '1'), 'tu', '2'), 'we', '3'), 'th', '4'), 'fr', '5'),
'sa', '6')),
'T01:00:00Z'))" as="xs:dateTime"/>
<xsl:choose>
<xsl:when test="$ADJUSTGMT ge $BSTSTARTS and $ADJUSTGMT lt $BSTENDS">
<!--return UTC +1 in summer-->
<xsl:value-of select="adjust-dateTime-to-timezone($DATETIMEIN,
xs:dayTimeDuration('PT1H'))"/>
</xsl:when>
<xsl:otherwise> <!--return UTC +0 in winter -->
<xsl:value-of select="$ADJUSTGMT"/>
</xsl:otherwise>
</xsl:choose>
</xsl:function>
It could easily be modified for other countries with summertime/DST.
Note that the function won't necessarily work for historical dates as the
present method of determining the datetime of the changeovers has only been in
force since 2002.
--~------------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--