RE: [xsl] Date Difference

Subject: RE: [xsl] Date Difference
From: "Haarman, Michael" <mhaarman@xxxxxxxxx>
Date: Mon, 19 Dec 2005 18:15:29 -0600
> -----Original Message-----
> From: Wendell Piez

> If you want your dates to have "dateness", XPath 2.0 is the way to 
> go, and Mike H has shown the way forward.

As much as to say "over yonder".  Wendell reminds me that I failed to
account for single digit days, as well.  It matters because the cast to
xs:date demands a normalized, standardized and reliable lexical form:


FWIW, the following stylesheet, much revised, does just what is required and
nothing more, over the following instance XML:


<?xml version="1.0"?>


<?xml version="1.0" encoding="utf-8"?>

<xsl:stylesheet xmlns:xsl="";
  exclude-result-prefixes="xs fn">

  <xsl:template match="/">

  <xsl:template match="*/dateRange">

    <xsl:variable name="dateOne">
      <xsl:call-template name="correctDate">
        <xsl:with-param name="dateParts" 
                        select="fn:tokenize(date[1], '/')"/>
    <xsl:variable name="dateTwo">
      <xsl:call-template name="correctDate">
        <xsl:with-param name="dateParts" 
                        select="fn:tokenize(date[2], '/')"/>

      <xsl:value-of select="xs:date($dateOne) - xs:date($dateTwo)"/>


  <xsl:template name="correctDate">
    <xsl:param name="dateParts"/>
    <xsl:value-of select="$dateParts[3]"/>
    <xsl:call-template name="pad">
      <xsl:with-param name="digits" select="$dateParts[1]"/>
    <xsl:call-template name="pad">
      <xsl:with-param name="digits" select="$dateParts[2]"/>

  <xsl:template name="pad">
    <xsl:param name="digits"/>
      <xsl:when test="fn:string-length($digits) = 1">
        <xsl:value-of select="concat('0', $digits)"/>
        <xsl:value-of select="$digits"/>


Producing this output with Saxon 8:

<?xml version="1.0" encoding="UTF-8"?>

I have broken out two parameterized templates: one to correct a supplied
date in 'Merkin grade-school form to ISO form and another pre-padding a zero
to any supplied string if a single digit.

All very instructive.  The machines are simple and have correspondingly
strict lexical requirements.  fn:replace() no longer made sense when each
token of the string needed touched.  And fn:tokenize() is slick as snot.

The result carries a leading minus when the first supplied date temporally
precedes the second.


Current Thread