2013-08-19 30 views
3

我有一個名爲「DateSet」的值爲「16/10/2008」的字符串。我想爲此值添加5個工作日。我假設我必須將價值轉換成某種東西,以便它知道這是一個日期。如何將5個工作日添加到現有值xslt

我使用xslt 1.0,並使用自定義軟件將xslt轉換爲word文檔。 現在它顯示:

<w:p> 
    <w:r> 
    <w:t>Some text [DateSet]</w:t> 
    </w:r> 
</w:p> 

其中[DateSet] 16/10/2008

,但我想它表明的是:

<w:p> 
    <w:r> 
    <w:t>Some text [DateSet+5business days]</w:t> 
    </w:r> 
</w:p> 

其中[DateSet + 5business天]應該顯示23/10/2008

我需要使用ms:format-date並以某種方式轉換它嗎?

回答

1

我試圖解決您的問題,但您需要針對您的未來要求進行改進。

對於XSLT 1.0需要導入一些擴展庫,你可以在http://xsltsl.sourceforge.net/發現,下載http://prdownloads.sourceforge.net/xsltsl/xsltsl-1.2.1.zip ZIP文件,並導入了在這裏給我產生的XSLT:

XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:doc="http://xsltsl.org/xsl/documentation/1.0" xmlns:dt="http://xsltsl.org/date-time" 
    xmlns:str="http://xsltsl.org/string" xmlns:dp="http://www.dpawson.co.uk" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xdt="http://www.w3.org/2005/02/xpath-datatypes" 
    extension-element-prefixes="doc str"> 

    <xsl:import href="xsltsl-1.2.1/stdlib.xsl"/> 
    <xsl:import href="xsltsl-1.2.1/date-time.xsl"/> 
    <xsl:param name="CurrentDate">21/08/2013</xsl:param> 
    <xsl:param name="CurrentYear" select="substring-after(substring-after($CurrentDate,'/'),'/')"/> 
    <xsl:param name="CurrentMonth" select="substring-before(substring-after($CurrentDate,'/'),'/')"/> 
    <xsl:param name="CurrentDay" select="substring-before($CurrentDate,'/')"/> 

    <xsl:template match="/"> 
    <xsl:text>Current given Date is : </xsl:text><xsl:value-of select="$CurrentDate"/><xsl:text>&#10;</xsl:text> 
    <xsl:call-template name="GetCompleteUpdatedDate"> 
     <xsl:with-param name="UpdatedDay"> 
     <xsl:call-template name="UpdateDay"> 
      <xsl:with-param name="CurrentDay" select="$CurrentDay"/> 
      <xsl:with-param name="LastDayOfMonth"> 
      <xsl:call-template name="dt:calculate-last-day-of-month"> 
       <xsl:with-param name="month" select="$CurrentMonth"/> 
      </xsl:call-template> 
      </xsl:with-param> 
     </xsl:call-template> 
     </xsl:with-param> 
     <xsl:with-param name="LastDayOfMonth"> 
     <xsl:call-template name="dt:calculate-last-day-of-month"> 
      <xsl:with-param name="month" select="$CurrentMonth"/> 
     </xsl:call-template> 
     </xsl:with-param> 
    </xsl:call-template> 
    </xsl:template> 

    <xsl:template name="UpdateDay"> 
    <xsl:param name="LastDayOfMonth"/> 
    <xsl:param name="CurrentDay"/> 
    <xsl:param name="RequiredDaysAddition">5</xsl:param> 
    <xsl:param name="SaturdaySundayCount">0</xsl:param> 
    <xsl:variable name="DayOfWeek"> 
     <xsl:call-template name="dt:calculate-day-of-the-week"> 
     <xsl:with-param name="year" select="$CurrentYear"/> 
     <xsl:with-param name="month" select="$CurrentMonth"/> 
     <xsl:with-param name="day" select="$CurrentDay"/> 
     </xsl:call-template> 
    </xsl:variable> 
    <xsl:variable name="DayAbbreviation"> 
     <xsl:call-template name="dt:get-day-of-the-week-abbreviation"> 
     <xsl:with-param name="day-of-the-week" select="$DayOfWeek"/> 
     </xsl:call-template> 
    </xsl:variable> 
    <xsl:choose> 
     <xsl:when test="$RequiredDaysAddition != 0"> 
     <xsl:choose> 
      <xsl:when test="$DayAbbreviation = 'Sun' or $DayAbbreviation = 'Sat'"> 
      <xsl:call-template name="UpdateDay"> 
       <xsl:with-param name="LastDayOfMonth" select="$LastDayOfMonth"/> 
       <xsl:with-param name="CurrentDay" select="$CurrentDay + 1"/> 
       <xsl:with-param name="RequiredDaysAddition" select="$RequiredDaysAddition - 1"/> 
       <xsl:with-param name="SaturdaySundayCount" select="$SaturdaySundayCount + 1"/> 
      </xsl:call-template> 
      </xsl:when> 
      <xsl:otherwise> 
      <xsl:call-template name="UpdateDay"> 
       <xsl:with-param name="LastDayOfMonth" select="$LastDayOfMonth"/> 
       <xsl:with-param name="CurrentDay" select="$CurrentDay + 1"/> 
       <xsl:with-param name="RequiredDaysAddition" select="$RequiredDaysAddition - 1"/> 
       <xsl:with-param name="SaturdaySundayCount" select="$SaturdaySundayCount"/> 
      </xsl:call-template> 
      </xsl:otherwise> 
     </xsl:choose> 
     </xsl:when> 
     <xsl:otherwise> 
     <xsl:value-of select="$CurrentDay + $SaturdaySundayCount"/> 
     </xsl:otherwise> 
    </xsl:choose> 
    </xsl:template> 

    <xsl:template name="GetCompleteUpdatedDate"> 
    <xsl:param name="UpdatedDay"/> 
    <xsl:param name="LastDayOfMonth"/> 
    <xsl:variable name="NewMonth"> 
     <xsl:choose> 
     <xsl:when test="$UpdatedDay &gt; $LastDayOfMonth"> 
      <xsl:choose> 
      <xsl:when test="($CurrentMonth + 1) = 12 or ($CurrentMonth + 1) &lt; 12"> 
       <xsl:value-of select="$CurrentMonth + 1"/> 
      </xsl:when> 
      <xsl:otherwise> 
       <xsl:value-of select="($CurrentMonth + 1) - 12"/> 
      </xsl:otherwise> 
      </xsl:choose> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:value-of select="$CurrentMonth"/> 
     </xsl:otherwise> 
     </xsl:choose> 
    </xsl:variable> 
    <xsl:variable name="NewYear"> 
     <xsl:choose> 
     <xsl:when test="($CurrentMonth + 1) &gt; 12"> 
      <xsl:value-of select="$CurrentYear + 1"/> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:value-of select="$CurrentYear"/> 
     </xsl:otherwise> 
     </xsl:choose> 
    </xsl:variable> 
    <xsl:variable name="IsNewYearLeapYear"> 
     <xsl:call-template name="IsYearLeapYear"><xsl:with-param name="Year" select="$NewYear"/></xsl:call-template> 
    </xsl:variable> 
    <xsl:variable name="NewDay"> 
     <xsl:choose> 
     <xsl:when test="$UpdatedDay &gt; $LastDayOfMonth"> 
      <xsl:value-of select="$UpdatedDay - $LastDayOfMonth"/> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:value-of select="$UpdatedDay"/> 
     </xsl:otherwise> 
     </xsl:choose> 
    </xsl:variable> 
    <xsl:text>Updated date is : </xsl:text><xsl:value-of select="concat(format-number($NewDay,'00'), '/', format-number($NewMonth,'00'), '/', $NewYear)"/> 
    </xsl:template> 

    <xsl:template name="IsYearLeapYear"> 
    <xsl:param name="Year"/> 
    <xsl:choose> 
     <xsl:when test="($Year mod 4 = 0 and $Year mod 100 != 0) or $Year mod 400 = 0">True</xsl:when> 
     <xsl:otherwise>False</xsl:otherwise> 
    </xsl:choose> 
    </xsl:template> 

</xsl:stylesheet> 

您只需更改$ CurrentDate值以檢查其輸出。

INPUT:

21/08/2013 

輸出:

Current given Date is : 21/08/2013 
Updated date is : 28/08/2013 

INPUT:

16/10/2008 

OUTPUT:

Current given Date is : 16/10/2008 
Updated date is : 23/10/2008 
+0

這似乎是個訣竅!該代碼對於新人來說更容易理解。感謝堆! – Simon

+0

該解決方案有一個錯誤。例如,如果您輸入的日期是星期五(例如,2016年11月18日),併爲RequiredDaysAddition指定了「1」,那麼它將返回19/11/2016,當它返回21/11/2016時。 – Chloraphil

1

從您的描述中,聽起來好像您已經從上下文中隔離了日期字符串,因此您可以使用它並將其替換爲新日期。好。如果那不是真的,你的第一個問題將會是真實的。

擴展函數ms:format-date()可能會幫助你,但看着its documentation我看不出如何。

給定一個日期,我想執行你在XSLT 1.0需要將那種日期計算最簡單的方法:

  1. 轉換日期爲整數(如儒略日數)。
  2. 執行日期算術。
  3. 將重新解析的整數轉換爲日期。

要將日期轉換爲整數,可以使用以下模板;它基於Robert G. Tantzen的「算法199:日曆日期和Julian日數之間的轉換」CACM 6.8(8月1963):444.它要求您從日期字符串中解析出年份,月份和日期數字,並通過他們在一個參數。

<xsl:template name="jday"> 
    <!--* JDay: convert a triple of integers representing 
    * Gregorian year, month, and day numbers to the 
    * number of the Julian day beginning at noon on that 
    * date. 
    * Transcribed from Robert G. Tantzen, "Algorithm 
    * 199: Conversions between calendar date and Julian 
    * day number" CACM 6.8 (Aug 1963): 444. 
     *--> 
    <xsl:param name="year" select="1963"/> 
    <xsl:param name="month" select="08"/> 
    <xsl:param name="day" select="13"/> 

    <xsl:variable name="y"> 
<xsl:choose> 
    <xsl:when test="$month > 2"> 
    <xsl:value-of select="$year"/> 
    </xsl:when> 
    <xsl:otherwise> 
    <xsl:value-of select="$year - 1"/> 
    </xsl:otherwise> 
</xsl:choose> 
    </xsl:variable> 
    <xsl:variable name="m"> 
<xsl:choose> 
    <xsl:when test="$month > 2"> 
    <xsl:value-of select="$month - 3"/> 
    </xsl:when> 
    <xsl:otherwise> 
    <xsl:value-of select="$month + 9"/> 
    </xsl:otherwise> 
</xsl:choose> 
    </xsl:variable> 
    <xsl:variable name="d" select="$day"/> 
    <xsl:variable name="c" select="floor($y div 100)"/> 
    <xsl:variable name="ya" select="$y - 100 * $c"/> 

    <!--* H holds the offset between Julian day 0 
     * and the beginning of the common era. 
     *--> 
    <xsl:variable name="H" select="1721119"/> 
    <!--* Calculate the Julian day that begins on the 
     * given date. 
     *--> 
    <xsl:value-of select="floor(($c * 146097) div 4) 
      + floor(($ya * 1461) div 4) 
      + floor((($m * 153) + 2) div 5) 
      + $d 
      + $H"/> 

</xsl:template> 

執行日期計算可能有點棘手:平日,日五個工作日之後的版本(我猜)七個日曆天之後,除非假期在這一時期出現。對於週末,我估計五個工作日後的日期是下週五。給定朱利安日數$ j,可以通過計算$ j mod 7:0 =星期一,1 =星期二,...,6 =星期日得到星期幾。所以,你的計算可能看起來像

<xsl:choose> 
    <xsl:when test="$j mod 7 = 5"> 
    <xsl:value-of select="$j + 6"/> 
    </xsl:when> 
    <xsl:when test="$j mod 7 = 6"> 
    <xsl:value-of select="$j + 5"/> 
    </xsl:when> 
    <xsl:otherwise> 
    <xsl:value-of select="$j + 7"/> 
    </xsl:otherwise> 
</xsl:choose> 

假期,你將不得不請教你感興趣的時期信息的一些外部來源;祝你好運。

轉換所產生的天數回日曆日期可以用下面的模板來完成,從1963年Tantzen再次轉錄:

<xsl:template name="jdate"> 
    <!--* JDate: given a Julian day number, return an ISO 
    * 8601 date. 
    * Transcribed from Robert G. Tantzen, "Algorithm 
    * 199: Conversions between calendar date and Julian 
    * day number" CACM 6.8 (Aug 1963): 444. 
     *--> 
    <xsl:param name="j" select="2438255"/> 

    <!--* dce: days in the common era (i.e. since 
     * 0000-03-01; Tantzen uses 1 Mar, not 1 Jan, 
     * as his epoch to simplify calculations). *--> 
    <xsl:variable name="dce" select="$j - 1721119"/> 

    <!--* cce: full centuries in the common era. *--> 
    <xsl:variable name="cce" 
       select="floor((4 * $dce - 1) div 146097)"/> 

    <!--* dcc4: days in current century, times 4. *--> 
    <xsl:variable name="dcc4" 
       select="(4 * $dce - 1) - (146097 * $cce)"/> 

    <!--* dcc: days in current century. *--> 
    <xsl:variable name="dcc4" 
       select="floor($dcc4 div 4)"/> 

    <!--* ycc: years in current century. *--> 
    <xsl:variable name="ycc" 
       select="floor((4 * $dcc + 3) div 1461)"/> 

    <!--* dcy4: days in current year, times 4. *--> 
    <xsl:variable name="dcy4" 
       select="(4 * $dcc + 3) - (1461 * $ycc)"/> 

    <!--* dcy: days in current year. *--> 
    <xsl:variable name="dcy" 
       select="floor(($dcy4 + 4) div 4)"/> 

    <!--* rgtm: RGT month number (0 Mar, 1 Apr ... 12 Feb). *--> 
    <xsl:variable name="rgtm" 
       select="floor((5 * $dcy - 3) div 153)"/> 

    <!--* dcm5: days in current month (minus 1) times 5. *--> 
    <xsl:variable name="dcm5" 
       select="5 * $dcy - 3 - 153 * $rgtm"/> 

    <!--* d: day number in current month. *--> 
    <xsl:variable name="d" 
       select="floor(($dcm5 + 5) div 5)"/> 

    <!--* rgty: RGT year number. *--> 
    <xsl:variable name="rgty" 
       select="100 * $cce + $ycc"/> 

    <!--* y: Gregorian year number. *--> 
    <xsl:variable name="y"> 
<xsl:choose> 
    <xsl:when test="$rgtm &lt; 10"> 
    <xsl:value-of select="$rgty"/> 
    </xsl:when> 
    <xsl:otherwise> 
    <xsl:value-of select="$rgty + 1"/> 
    </xsl:otherwise> 
</xsl:choose> 
    </xsl:variable> 

    <!--* m: Gregorian month number. *--> 
    <xsl:variable name="m"> 
<xsl:choose> 
    <xsl:when test="$rgtm &lt; 10"> 
    <xsl:value-of select="$rgtm + 3"/> 
    </xsl:when> 
    <xsl:otherwise> 
    <xsl:value-of select="$rgtm - 9"/> 
    </xsl:otherwise> 
</xsl:choose> 
    </xsl:variable> 

    <!--* Return value in ISO 8601 format *--> 
    <xsl:value-of select="concat(
      format-number($y,'0000'), 
      '-', 
      format-number($m,'00'), 
      '-', 
      format-number($d,'00') 
      )"/> 
</xsl:template> 

需要注意的是書面,這將返回ISO格式的日期;如果您想要dd/mm/yyyy或mm/dd/yyyy或其他格式,則需要更改它。

祝你好運。