RE: [xsl] Date Difference

Subject: RE: [xsl] Date Difference
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Wed, 21 Dec 2005 00:57:56 -0000
> In laymans terms is there anyway for me to tell if a date is 
> either equal
> or in the future in a few # of lines?

Assuming XPath 2.0:

if ($date ge current-date()) then ... else ...

Michael Kay
http://www.saxonica.com/


> 
> Or does someone have a function that will do this ?
> 
> Regards,
> 
> Tom Maciejewski
> 
> 
> 
>                                                               
>                                                               
>           
>                       "Haarman,                               
>                                                               
>           
>                       Michael"                 To:       
> "'xsl-list@xxxxxxxxxxxxxxxxxxxxxx'" 
> <xsl-list@xxxxxxxxxxxxxxxxxxxxxx>        
>                       <mhaarman@xxxxxxx        cc:            
>                                                               
>           
>                       om>                      Subject:  RE: 
> [xsl] Date Difference                                         
>            
>                                                               
>                                                               
>           
>                       12/19/2005 04:33                        
>                                                               
>           
>                       PM                                      
>                                                               
>           
>                       Please respond to                       
>                                                               
>           
>                       xsl-list                                
>                                                               
>           
>                                                               
>                                                               
>           
>                                                               
>                                                               
>           
> 
> 
> 
> 
> Three questions below.
> 
> > From: David Carlisle
> >
> > > I basically have two strings :   "9/11/2004"  and "10/25/2005"
> > > and would like to produce the number of days between the two.
> >
> > I didn't know there was a month 25.
> 
> (M)M/DD/YYYY is a standard lexical representation in America.
> 
> 
> > XSLT2 has date arithmetic built in but only if you have your
> > dates in a
> > standard format
> 
> I had a moment this morning and have been meaning to *get a 
> round tuit* and
> begin with XSLT2.  Reading the OP I said to myself: here is a 
> simple and
> illustrative chore to undertake.  I have raised a few questions.
> 
> I built an XML instance using the OP's datapoints:
> 
> testDate2.xml:
> --------------
> 
> <?xml version="1.0"?>
> <data>
> <dateRange>
> <date>9/11/2004</date>
> <dateStandard>2004-09-11</dateStandard>
> <date>10/25/2005</date>
> <dateStandard>2005-10-25</dateStandard>
> </dateRange>
> </data>
> 
> testDate2.xsl:
> --------------
> 
> <?xml version="1.0" encoding="utf-8"?>
> 
> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
>   xmlns:xs="http://www.w3.org/2001/XMLSchema";
>   xmlns:fn="http://www.w3.org/2005/xpath-functions";
>   version="2.0"
>   exclude-result-prefixes="xs fn">
> 
>   <xsl:template match="/">
>     <output>
>       <xsl:apply-templates/>
>     </output>
>   </xsl:template>
> 
>   <xsl:template match="*/dateRange">
>     <!-- normalized data points -->
>     <xsl:variable name="earlier" select="dateStandard[1]" 
> as="xs:date"/>
>     <xsl:variable name="later" select="dateStandard[2]" as="xs:date"/>
> 
>     <!-- padding month to two digits -->
>     <xsl:variable name="earlierPadded">
>       <xsl:choose>
>         <xsl:when 
> test="fn:string-length(substring-before(date[1], '/')) =
> 1">
>           <xsl:value-of select="concat('0',date[1])"/>
>         </xsl:when>
>         <xsl:otherwise>
>           <xsl:value-of select="date[1]"/>
>         </xsl:otherwise>
>       </xsl:choose>
>     </xsl:variable>
>     <xsl:variable name="laterPadded">
>       <xsl:choose>
>         <xsl:when 
> test="fn:string-length(substring-before(date[2], '/')) =
> 1">
>           <xsl:value-of select="concat('0',date[2])"/>
>         </xsl:when>
>         <xsl:otherwise>
>           <xsl:value-of select="date[2]"/>
>         </xsl:otherwise>
>       </xsl:choose>
>     </xsl:variable>
> 
>     <!-- get standardized date strings -->
>     <xsl:variable name="regexE"
>       select="xs:date(fn:replace($earlierPadded, '(.*)/(.*)/(.*)',
> '$3-$1-$2'))"/>
>     <xsl:variable name="regexL"
>       select="xs:date(fn:replace($laterPadded, '(.*)/(.*)/(.*)',
> '$3-$1-$2'))"/>
> 
> 
>     <durationLaterFromEarlier>
>       <xsl:value-of select="$later - $earlier"/>
>     </durationLaterFromEarlier>
>     <durationEarlierFromLater>
>       <xsl:value-of select="$earlier - $later"/>
>     </durationEarlierFromLater>
> 
>     <durationLaterFromEarlier>
>       <xsl:value-of select="$regexL - $regexE"/>
>     </durationLaterFromEarlier>
>     <durationEarlierFromLater>
>       <xsl:value-of select="$regexE - $regexL"/>
>     </durationEarlierFromLater>
>   </xsl:template>
> 
> </xsl:stylesheet>
> 
> 
> 
> Using Saxon 8, this yields the desired result:
> 
> result.xml
> --------------
> 
> <?xml version="1.0" encoding="UTF-8"?>
> <output>
> <durationLaterFromEarlier>P409D</durationLaterFromEarlier><dur
> ationEarlierFr
> 
> omLater>-P409D</durationEarlierFromLater><durationLaterFromEar
> lier>P409D</du
> 
> rationLaterFromEarlier><durationEarlierFromLater>-P409D</durat
> ionEarlierFrom
> 
> Later>
> </output>
> 
> 
> 
> Questions:
> 
> A)
> Is there a reason the operators described within the op: 
> namespace in the
> CR
> are not available?  I began with statements like:
> 
> op:subtract-dates($earlier, $later)
> 
> and only much later found the sentences clarifying these operators:
> 
> <quote>
> Functions defined with the op prefix are described here to 
> underpin the
> definitions of the operators in [XML Path Language (XPath) 
> 2.0], [XQuery
> 1.0: An XML Query Language] and [XSL Transformations (XSLT) 
> Version 2.0].
> These functions are not available directly to users, and there is no
> requirement that implementations should actually provide 
> these functions.
> </quote>
> 
> The functional notation seems much more intuitive to me than using
> arithmetic operations on dates.  Which is the greater value?  
> Simple math
> on
> date values was drummed out of me very early in my 
> grade-school career.
> 
> B)
> This statement:
> 
>     <xsl:variable name="later" select="dateStandard[2]" as="xs:date"/>
> 
> seemed to work fine, but this one later:
> 
>     <xsl:variable name="regexE"
>       select="fn:replace($earlierPadded, '(.*)/(.*)/(.*)', '$3-$1-$2')
>              as="xs:date"/>
> 
> threw an error when the value of $regexE was used in the 
> later arithmetic,
> complaining that it was still a string.  Stating it in the 
> following manner
> corrected the error:
> 
>     <xsl:variable name="regexE"
>       select="xs:date(fn:replace($earlierPadded, '(.*)/(.*)/(.*)',
> '$3-$1-$2'))"/>
> 
> I suspect I am missing an implicit cast somewhere that makes the first
> statement work and renders the as= attribute moot.
> 
> C)
> Any idiomatic corrections to the stylesheet or notational shortcuts I
> missed?
> 
> 
> TIA,
> 
> Mike
> 
> -----------------------------------
> Mike Haarman,
> XSL Developer,
> Internet Broadcasting Systems, Inc.
> 
> 
> 
> **************************************************************
> ***********
> This message and any attachments (the "message") are confidential and
> intended solely for the addressees.
> Any unauthorised use or dissemination is prohibited. 
> E-mails are susceptible to alteration.   
> Neither SOCIETE GENERALE nor any of its subsidiaries or affiliates 
> shall be liable for the message if altered, changed or falsified. 
> 
> **************************************************************
> ***********

Current Thread