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

Subject: Re: [xsl] Working with xs:date and xs:gYearMonth
From: Colin Paul Adams <colin@xxxxxxxxxxxxxxxxxx>
Date: 24 Jun 2004 14:43:53 +0100
>>>>> "Michael" == Michael Kay <mhk@xxxxxxxxx> writes:

    Michael> Saxon's date arithmetic on BC dates is probably
    Michael> unreliable because of these problems, it's not something
    Michael> that is very well tested. It would be safer to use a
    Michael> later date as a baseline.

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:


  <xsl:variable name="today" select="current-date ()"  as="xs:date"/>
  <xsl:param name="date" select="$today"  as="xs: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>
    </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>
    <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>

  <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

Current Thread