RE: [xsl] Working with xs:date and xs:gYearMonth

Subject: RE: [xsl] Working with xs:date and xs:gYearMonth
From: "Michael Kay" <mhk@xxxxxxxxx>
Date: Fri, 25 Jun 2004 00:09:20 +0100
> Well, rather than use a baseline at all, since I am only interested in
> the previous and following months in the 21st century for my
> application, I came up with the following safe (if somewhat verbose)
> solution:

Some comments inline:
> 
> 
>   <xsl:variable name="today" select="current-date ()"  as="xs:date"/>
>   <xsl:param name="date" select="$today"  as="xs:date"/>

Why two variables with the same value? You could just declare the param, and
give it a default value of current-date().

>   <xsl:variable name="current-month" select="year-from-date 
> ($date)*12 + month-from-date ($date)" as="xs:integer"/>
> 
>   <xsl:variable name="first-of-previous-month" as="xs:date">
>     <xsl:variable name="local-month-1" 
> select="month-from-date ($date) - 1" as="xs:integer"/>
>     <xsl:variable name="local-month-2" as="xs:integer">
>       <xsl:choose>
> 	<xsl:when test="$local-month-1 eq 0"><xsl:value-of 
> select="xs:integer (12)"/></xsl:when>
> 	<xsl:otherwise><xsl:value-of 
> select="$local-month-1"/></xsl:otherwise>
>       </xsl:choose>

Try to avoid using xsl:value-of here: use xsl:sequence or xsl:copy-of. By
using xsl:value-of you are putting the integer into a text node, and then
extracting the integer from the text node again. Note also, xs:integer(12)
could be written 12. 

Personally, I would do this all in XPath:

<xsl:variable name="local-month-2" as="xs:integer"
         select="if ($local-month-1 eq 0) then 12 else $local-month-1"/>

>     </xsl:variable>
>     <xsl:variable name="local-year" as="xs:integer">
>       <xsl:choose>
> 	<xsl:when test="$local-month-2 eq 12"><xsl:value-of 
> select="year-from-date ($date) - 1" /></xsl:when>
> 	<xsl:otherwise><xsl:value-of select="year-from-date 
> ($date)" /></xsl:otherwise>
>       </xsl:choose>
>     </xsl:variable>

Similarly here:

<xsl:variable name="local-year" as="xs:integer" 
    select="year-from-date($date) - (if ($local-month-2 eq 12) then 1 else
0)"/>
 
>     <xsl:variable name="local-date" select="concat 
> (format-number ($local-year, '####'), '-', format-number 
> ($local-month-2, '00'), '-01')" as="xs:string"/>
>     <xsl:value-of select="xs:date ($local-date)"/>

Again, use xsl:sequence. You are converting the string $local-date to an
xs:date, then turning the xs:date into a text node, then turning the text
node back into a date.

Your coding style of doing the work with a sequence of local variables
inside an outer xsl:variable is interesting. I wouldn't have thought of
doing it this way, but I can't fault it.

Rather than using this conditional logic with a "carry" from the months into
the year, you could compute the year as ($current-month -1) idiv 12, and the
month as ($current-month -1) mod 12.

Similar observations apply to the code below.

Michael Kay

>   </xsl:variable>
> 
>   <xsl:variable name="first-of-following-month" as="xs:date">
>     <xsl:variable name="local-month-1" 
> select="month-from-date ($date) + 1" as="xs:integer"/>
>     <xsl:variable name="local-month-2" as="xs:integer">
>       <xsl:choose>
> 	<xsl:when test="$local-month-1 eq 13"><xsl:value-of 
> select="xs:integer (1)"/></xsl:when>
> 	<xsl:otherwise><xsl:value-of 
> select="$local-month-1"/></xsl:otherwise>
>       </xsl:choose>
>     </xsl:variable>
>     <xsl:variable name="local-year" as="xs:integer">
>       <xsl:choose>
> 	<xsl:when test="$local-month-2 eq 1"><xsl:value-of 
> select="year-from-date ($date) + 1" /></xsl:when>
> 	<xsl:otherwise><xsl:value-of select="year-from-date 
> ($date)" /></xsl:otherwise>
>       </xsl:choose>
>     </xsl:variable>
>     <xsl:variable name="local-date" select="concat 
> (format-number ($local-year, '####'), '-', format-number 
> ($local-month-2, '00'), '-01')" as="xs:string"/>
>     <xsl:value-of select="xs:date ($local-date)"/>
>   </xsl:variable>
> 
> I suppose I could generalize these into functions taking a duration,
> and performing iteraton, but I have no need.
> -- 
> Colin Paul Adams
> Preston Lancashire
> 
> --+------------------------------------------------------------------
> 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@xxxxxxxxxxxxxxxxxxxxxx>
> --+--
> 
> 


Current Thread