如何在xslt 1.0中仅获取两个日期之间的工作日

时间:2015-04-02 11:22:46

标签: xslt-1.0

我需要帮助才能计算xslt 1.0中两个日期之间的工作日(即不包括星期六和星期日)

2 个答案:

答案 0 :(得分:2)

  

仅计算工作日(即不包括周六和周日)   xslt 1.0中的两个日期

如果可以假设两个给定日期在星期六或星期日落下,您可以使用以下示例中显示的方法:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="/">
    <output>
        <workdays>
            <xsl:call-template name="duration-in-workdays">
                <xsl:with-param name="start-date" select="'2015-04-02'" />
                <xsl:with-param name="end-date" select="'2015-04-08'" />
            </xsl:call-template>
        </workdays>
    </output>
</xsl:template> 

<xsl:template name="duration-in-workdays">
    <!-- assumes start-date and end-date are both workdays -->
    <xsl:param name="start-date"/>
    <xsl:param name="end-date"/>
    <xsl:variable name="start">
        <xsl:call-template name="JDN">
            <xsl:with-param name="date" select="$start-date" />
        </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="end">
        <xsl:call-template name="JDN">
            <xsl:with-param name="date" select="$end-date" />
        </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="start-weekday" select="($start + 1) mod 7" />
    <xsl:variable name="end-weekday" select="($end + 1) mod 7" />
    <xsl:variable name="weeks" select="floor(($end - $start) div 7)" />
    <xsl:variable name="days" select="($end - $start) mod 7" />

    <xsl:value-of select="5 * $weeks + $days - 2*($start-weekday > $end-weekday)"/>
</xsl:template> 

<xsl:template name="JDN">
    <xsl:param name="date"/>
    <xsl:variable name="year" select="substring($date, 1, 4)"/>
    <xsl:variable name="month" select="substring($date, 6, 2)"/>
    <xsl:variable name="day" select="substring($date, 9, 2)"/>
    <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) + 365*$y + floor($y div 4) - floor($y div 100) + floor($y div 400) - 32045" />
</xsl:template> 

</xsl:stylesheet>

</xsl:stylesheet>

警告:未经过彻底测试。

答案 1 :(得分:0)

<xsl:template match="/">
    <xsl:value-of select="this:WorkDayDifference(xs:date('2014-05-01'),xs:date('2014-05-12'))"/>
    

</xsl:template>

    <xsl:function name="this:WorkDayDifference">
        <xsl:param name="startDate" as="xs:date"/>
        <xsl:param name="endDate" as="xs:date"/>
        <xsl:variable name="endDateDay" select="this:day-of-week($endDate)"/>
        <xsl:variable name="days" select="days-from-duration($endDate - $startDate)"/>
        <xsl:variable name="dow1" select="this:day-of-week($startDate)"/>
        <xsl:variable name="dow2" select="this:day-of-week($endDate)"/>
        <xsl:variable name="weeks" select="xs:integer($days div 7)"/>
        <xsl:variable name="offset" select="if($dow2 ge $dow1) then if($endDateDay = 6 or $endDateDay = 0)then(-6)else(-5) else if($endDateDay = 6 or $endDateDay = 0)then(-1)else(0)"/>
        <xsl:variable name="wdays" select="sum((0,1,1,1,1,1,0,0,1,1,1,1,1,0)[position() ge $dow1 + 1 and position() le ($dow2 + 7)]) + $weeks * 5 + $offset + 1"/>
        <xsl:value-of select="number($wdays)"/>
    </xsl:function>
    
    <xsl:function name="this:day-of-week" as="xs:integer?" >
        <xsl:param name="date" as="xs:anyAtomicType?"/>
        <xsl:sequence select="if (empty($date)) then () else (xs:integer((xs:date($date) - xs:date('1901-01-06')) div xs:dayTimeDuration('P1D')) mod 7)"/>
    </xsl:function>