2011-04-04 14 views
7

Есть ли меньше, чем kludgey способ найти разницу в днях между двумя датами в xslt? Если это так, вы можете указать мне в правильном направлении. Я получаю даты в формате mm/dd/yyyy.Нахождение разницы между двумя датами в xslt

+1

Вы застряли с XSLT 1 или может вы использовать XSLT2? –

+4

В XSLT 1.0 у вас есть EXSLT 'date: difference', реализованный Jeni Tennison по адресу http://www.exslt.org/date/functions/difference/date.difference.template.xsl –

+0

Я бы рекомендовал использовать XSLT 2.0/XPath 2.0 для этого. –

ответ

4

Использование XSLT 2.0 (XPath 2.0) для этого:

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

когда это преобразование применяется на следующий документ XML:

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

разыскиваемый, правильный результат (разность составляет 450 дней) производится:

450 
+1

Единственное решение, которое помогло мне с датами на OSB – Tol182

+0

Еще один отличный answser - https://stackoverflow.com/questions/38604414/finding-the-difference-between-two-datetimes-in-xslt –

6

Более подходящая (и более короткая) альтернатива для XSLT 1.0 заключается в вычислении эквивалентных юлианских дат и вычитании их.

Шаблон:

<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"/> 

Использование:

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

Повторите для второй даты, и вы будете иметь два целых числа. Затем просто вычтите их.

6

Это можно легко сделать, используя следующее выражение:

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

Например:

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

даст результат

Смежные вопросы