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: Wed, 23 Jun 2004 04:19:58 +0100
The gXX types aren't very well supported by functions and operators in XPath
2.0, in fact, they're a bit of a dead end, as you've discovered. They don't
even support ordering comparisons.

I personally find that for any serious work using dates and durations, it's
much easier to do it using numbers than using the purpose-built data types.
A useful trick is to convert a yearMonthDuration to an integer number of
months by dividing by P1M, and to convert back by multiplying by P1M. 

You can represent the current month as

<xsl:variable name="current-month" 
              select="year-from-date($today)*12 + month-from-date($today)"
              as="xs:integer"/>

and then get the previous month as

<xsl:variable name="previous-month" 
              select="$current-month - 1" 
              as="xs:integer"/>

and you can get the date on the first of the previous month as

<xsl:variable name="one-month"
              select="xs:yearMonthDuration('P1M')"
              as="xdt:yearMonthDuration"/>

<xsl:variable name="first-of-previous-month"
              select="xs:date('0000-01-01') + ($previous-month *
$one-month)"
              as="xs:date"/>

Michael Kay

> -----Original Message-----
> From: Colin Paul Adams [mailto:colin@xxxxxxxxxxxxxxxxxx] 
> Sent: 22 June 2004 20:06
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: [xsl] Working with xs:date and xs:gYearMonth
> 
> I'm trying to write a transform for generating calendards from some 
> xml event data.
> 
> I shall want to highlight the entry for today (if the calendar happens
> to be displaying the current month), so I set up a global variable
> named today:
> 
> 
>    <xsl:variable name="today" select="current-date()"  as="xs:date"/>
>    
> I also want to be able to pass a parameter to name the month to
> display, defaulting to the current month, so:
> 
>      <xsl:param name="date" select="xs:gYearMonth($today)"  
> as="xs:gYearMonth"/>
> 
> As I want to generate a hyperlink to the previous month, I want a
> variable that I can put into the query string of a URL so:
> 
>      <xsl:variable name="previous_month"
>         select="xs:gYearMonth(xs:date($date) -
>         xdt:yearMonthDuration('P0Y1M'))" as="xs:gYearMonth"/>
> 
> But when I try to reference this variable:
> 
> <th id="lastmonth"><a 
> href="/onevoice/members/calendar?date='{$previous_month}'">&#1
> 71;</a></th>
> 
> saxon (8.0b) gives me:
> 
> Error at attribute on line 60 of 
> file:/home/colin/onevoice/members/calendar.xsl:
>   Cannot convert gYearMonth to xs:date
> Transformation failed: Run-time errors were reported
> 
> How am I supposed to go about this?
> -- 
> 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