xsl-list
[Top] [All Lists]

RE: Working with xs:date and xs:gYearMonth

2004-06-24 16:09:20
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(_at_)lists(_dot_)mulberrytech(_dot_)com>
--+--