xsl-list
[Top] [All Lists]

Re: [xsl] dateTime fun

2006-12-21 10:13:48
James A. Robinson wrote:
On Wed, 20 Dec 2006 20:24:29 -0800 I wrote:
< < So I'm dealing with a schema which has an attribute: < < <xs:simpleType name="time">
<     <xs:union  memberTypes="
<           xs:gYear xs:gYearMonth xs:date xs:dateTime"  />
<   </xs:simpleType>
< < I had to write a function to let someone compare two of these 'time'
< simple types.  It appeared as though the only way to do comparisions
< was with equal times, so that mean converting everything to xs:dateTime.

True, but that does not need to be as hard as you think. I tried applying date:parse-date from EXSLT, but it was not supported by Saxon (not sure you use Saxon, though). But I may have a simpler solution for you.

The details of what I need are:

  'time' may be xs:dateTime, xs:date, xs:gYear, xs:gYearMonth
   $a is a 'time' in a document
   $b is a 'time' provided by a user

   Given $a and $b I want to allow for eq, lt, le, gt, ge
   comparision of $a and $b)

You created quite a complex function. I today pondered a bit about your question and I came up with the following solution. I requires that you do not add gMonth, gDay etc to the list, because it employs padding the date.

What I do is, in fact, the same as you: make the value a dateTime and compare on the resulting value. However, I don't believe you need so many, long functions. In fact, you only need 8 lines, including the declaration. Here's what I tried:

1) Take a "picture" string, I call it a "null-date": 0001-01-01T00:00:00.000
2) Apply that to your stringized date/datetime/year/yearmonth
3) Convert the result.

For instance, take a gYear value "2006", use the null-date as overlay (see function below) and you get "2006-01-01T00:00:00.000", which is a comparable dateTime. The same applies to gYearMonth "2006-06" which would become "2006-06-01T00:00:00.000", and so on.

Here's the whole template. Call it on itself and it will show you that it works for your four datatypes. You can use any operation on the result of running date:parse-date. I used the EXSLT date namespace, but you are of course free to choose your own.

Cheers,

Abel Braaksma
http://www.nuntia.nl


<xsl:stylesheet version="2.0"
   xmlns:xs = "http://www.w3.org/2001/XMLSchema";
   xmlns:date="http://exslt.org/dates-and-times";
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
<xsl:output method="text"/>

   <xsl:template match="/" >
<xsl:variable name="dateTime" as="xs:dateTime">2006-12-30T16:12:22.234</xsl:variable>
       <xsl:variable name="date" as="xs:date">2006-12-30</xsl:variable>
<xsl:variable name="yearMonth" as="xs:gYearMonth">2006-12</xsl:variable>
       <xsl:variable name="year" as="xs:gYear">2006</xsl:variable>
dateTime : <xsl:value-of select="$dateTime" />
       date      : <xsl:value-of select="$date" />
       yearMonth : <xsl:value-of select="$yearMonth" />
       year      : <xsl:value-of select="$year" />
Conv dateTime : <xsl:value-of select="date:parse-date($dateTime)" />
       Conv date      : <xsl:value-of select="date:parse-date($date)" />
Conv yearMonth : <xsl:value-of select="date:parse-date($yearMonth)" />
       Conv year      : <xsl:value-of select="date:parse-date($year)" />
$year lt $date : <xsl:value-of select="date:parse-date($year) gt date:parse-date($date)" /> </xsl:template> <xsl:function name="date:parse-date" as="xs:dateTime">
       <xsl:param name="parsable-date" />
<xsl:variable name="null-date">0001-01-01T00:00:00.000</xsl:variable>
       <xsl:variable name="padded-date" select="
           concat(xs:string($parsable-date),
               substring($null-date
               , string-length(xs:string($parsable-date)) + 1
               , 40))" />
<xsl:value-of select="xs:dateTime(substring($padded-date, 1, 23))" />
   </xsl:function>

</xsl:stylesheet>



--~------------------------------------------------------------------
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>
--~--

<Prev in Thread] Current Thread [Next in Thread>