开发者

date minus another date in xslt

开发者 https://www.devze.com 2023-03-05 12:30 出处:网络
Hope someon开发者_开发知识库e can help. I am trying to compare 2 dates inside an XML file and using a XSLT to do some calculation:

Hope someon开发者_开发知识库e can help. I am trying to compare 2 dates inside an XML file and using a XSLT to do some calculation:

For example I have 2 dates in XML: 2011-05-23 and 2011-04-29. I want to do calculation inside XSLT like below:

('2011-05-23'-'2011-04-29')*30 = 24*30= 720

Can anyone shed any light?


An XSLT 2.0 solution

<?xml version="1.0"?>
<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:template match="/">
<xsl:value-of select="days-from-duration(
                                         xs:date('2011-05-23')
                                         - xs:date(xs:date('2011-04-29'))
                      )*30"/>
</xsl:template>
</xsl:stylesheet>

Yields: 720

  • xs:date() function evaluates the dates, which can be used to perform date operations
  • subtracting the second date from the first yields the xdt:dayTimeDuration P24D (24 days)
  • days-from-duration() extracts the days component from the xdt:dayTimeDuration (24)
  • then you can use that number to perform normal arethmatic (e.g. 24*30=720)


It might be worth looking at the EXSLT - date:difference solution. I believe that should do what you want, and there's even a straight XSLT implementation available.

Be aware though that the returned value is in duration format as specified in the XML Schema Part 2: Datatypes Second Edition, so it's likely you will need to process the result to derive the unit you wish to use in calculation (for instance in your example above you're expecting a result detailing the number of days difference - so you would need to pull out the relevant unit you want to work with, the result from date:difference in that case would most likely be "P24D").


Here's two templates I sometimes use for date calculations:

<xsl:template name="calcseconds">
  <xsl:param name="date" />
  <xsl:value-of select="(((substring($date,1,4) - 1970) * 365)+floor((substring($date,1,4) - 1970) div 4)+substring('000,031,059,090,120,151,181,212,243,273,304,334,365',substring($date,6,2)*4-3,3)+(substring($date,9,2)-1)+(1-floor(((substring($date,1,4) mod 4) + 2) div 3))*floor((substring($date,6,2)+17) div 20))*86400+(substring($date,12,2)*3600)+(substring($date,15,2)*60)+substring($date,18,2)" />
</xsl:template>

<xsl:template name="calcdays">
  <xsl:param name="date" />
  <xsl:value-of select="(((substring($date,1,4) - 1970) * 365)+floor((substring($date,1,4) - 1970) div 4)+substring('000,031,059,090,120,151,181,212,243,273,304,334,365',substring($date,6,2)*4-3,3)+(substring($date,9,2)-1)+(1-floor(((substring($date,1,4) mod 4) + 2) div 3))*floor((substring($date,6,2)+17) div 20))" />
</xsl:template>

They're a bit of a mouthful, but they'll calculate the number of seconds/days since midnight 1st January 1970 as an integer, which you can then do straight arithmetic on. They rely on the date format being yyyy-mm-dd hh:mm:ss, but manipulation of the parameters of the substring calls should allow you to process dates in any format you need.

0

精彩评论

暂无评论...
验证码 换一张
取 消