Finding the difference between 2 dates in xslt
Asked Answered
S

3

8

Is there a less then kludgey way of finding the difference in days between 2 dates in xslt? If so can you point me in the right direction. I am receiving dates in the format of mm/dd/yyyy.

Stereotyped answered 4/4, 2011 at 21:50 Comment(3)
Are you stuck with XSLT 1 or can you use XSLT2?Ethelinda
In XSLT 1.0 you have EXSLT date:difference implemented by Jeni Tennison at exslt.org/date/functions/difference/…Palladous
I'd recommend using XSLT 2.0/XPath 2.0 for this.Passageway
P
6

Use XSLT 2.0 (XPath 2.0) for this:

<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:my="my:my">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/">
     <xsl:variable name="vDate1"
        select="my:dateFromUsDate(/*/d1)"/>
     <xsl:variable name="vDate2"
        select="my:dateFromUsDate(/*/d2)"/>

   <xsl:sequence select=
   "($vDate1 - $vDate2) div xs:dayTimeDuration('P1D')"/>
 </xsl:template>

 <xsl:function name="my:dateFromUsDate" as="xs:date">
  <xsl:param name="pUsDate" as="xs:string"/>

  <xsl:sequence select=
  "xs:date(concat(substring($pUsDate,7,4),
                  '-',
                  substring($pUsDate,1,2),
                  '-',
                  substring($pUsDate,4,2)
                 )
          )
  "/>
 </xsl:function>
</xsl:stylesheet>

when this transformation is applied on the following XML document:

<t>
 <d1>04/06/2011</d1>
 <d2>01/11/2010</d2>
</t>

the wanted, correct result (the difference is 450 days) is produced:

450
Passageway answered 6/4, 2011 at 13:35 Comment(3)
the only one solution out there that helped me with dates on OSBWryneck
Another Perfect answser - #38604914Hexad
@RudraprasadPradhan, Yes, one way is to follow the answer by BuffaloPassageway
M
11

A nicer (and shorter) alternative for XSLT 1.0 is to compute the equivalent Julian dates and subtract them.

Template:

<xsl:template name="calculate-julian-day">
    <xsl:param name="year"/>
    <xsl:param name="month"/>
    <xsl:param name="day"/>

    <xsl:variable name="a" select="floor((14 - $month) div 12)"/>
    <xsl:variable name="y" select="$year + 4800 - $a"/>
    <xsl:variable name="m" select="$month + 12 * $a - 3"/>

    <xsl:value-of select="$day + floor((153 * $m + 2) div 5) + $y * 365 + floor($y div 4) - floor($y div 100) + floor($y div 400) - 32045"/>

Usage:

<xsl:variable name="dateInv" select="'20120406'" />
<xsl:call-template name="calculate-julian-day">
    <xsl:with-param name="year" select="substring($date,1,4)"/>
    <xsl:with-param name="month" select="substring($date,5,2)"/>
    <xsl:with-param name="day" select="substring($date,7,2)"/>
</xsl:call-template>

Repeat for the second date and you'll have two integers. Then, simply subtract them.

Marandamarasca answered 11/4, 2012 at 9:18 Comment(0)
S
8

This could be easily done using the following expression:

days-from-duration(xs:date('yyyy-MM-dd')-xs:date('yyyy-MM-dd'))

For example:

days-from-duration(xs:date('2012-06-30')-xs:date('2012-06-18')) 

will give result of 12

Spiculum answered 20/6, 2012 at 16:43 Comment(0)
P
6

Use XSLT 2.0 (XPath 2.0) for this:

<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:my="my:my">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/">
     <xsl:variable name="vDate1"
        select="my:dateFromUsDate(/*/d1)"/>
     <xsl:variable name="vDate2"
        select="my:dateFromUsDate(/*/d2)"/>

   <xsl:sequence select=
   "($vDate1 - $vDate2) div xs:dayTimeDuration('P1D')"/>
 </xsl:template>

 <xsl:function name="my:dateFromUsDate" as="xs:date">
  <xsl:param name="pUsDate" as="xs:string"/>

  <xsl:sequence select=
  "xs:date(concat(substring($pUsDate,7,4),
                  '-',
                  substring($pUsDate,1,2),
                  '-',
                  substring($pUsDate,4,2)
                 )
          )
  "/>
 </xsl:function>
</xsl:stylesheet>

when this transformation is applied on the following XML document:

<t>
 <d1>04/06/2011</d1>
 <d2>01/11/2010</d2>
</t>

the wanted, correct result (the difference is 450 days) is produced:

450
Passageway answered 6/4, 2011 at 13:35 Comment(3)
the only one solution out there that helped me with dates on OSBWryneck
Another Perfect answser - #38604914Hexad
@RudraprasadPradhan, Yes, one way is to follow the answer by BuffaloPassageway

© 2022 - 2024 — McMap. All rights reserved.