我有一个名为"DateSet"的字符串,值为"16/10/2008"。我想在这个数值上增加5个工作日。我想我必须把值转换成某种东西,这样它就知道这是一个日期。
我使用xslt 1.0,并使用自定义软件将xslt转换为word文档。现在显示:
<w:p>
<w:r>
<w:t>Some text [DateSet]</w:t>
</w:r>
</w:p>
其中[DateSet]16/2008
但我想让它展示的是:
<w:p>
<w:r>
<w:t>Some text [DateSet+5business days]</w:t>
</w:r>
</w:p>
其中[日期集+5个工作日]应显示2008年10月23日
我需要使用ms:format日期并以某种方式转换它吗?
从您的描述中,听起来好像您已经将日期字符串从上下文中隔离出来,这样您就可以使用它并用新日期替换它。好的如果这不是真的,你的第一个问题就是把它变成现实。
扩展函数ms:format-date()可能会对您有所帮助,但浏览一下它的文档,我不知道该怎么做。
给定一个日期,我认为在XSLT1.0中执行所需日期运算的最简单方法是:
- 将日期转换为整数(例如儒略日数字)
- 执行日期运算
- 将返回的整数转换为日期
要将日期转换为整数,可以使用以下模板;它基于Robert G.Tantzen,"算法199:日历日期和儒略日数字之间的转换"CACM 6.8(1963年8月):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>
对于假期,你将不得不咨询一些你感兴趣的时期的外部信息来源;祝你好运
将生成的日期转换回日历日期可以使用以下模板完成,再次转录自Tantzen 1963:
<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 < 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 < 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或其他格式,则需要更改它。
祝你好运。
我已经尝试解决您的问题,但您需要针对未来的需求增强此功能。
对于XSLT1.0,您需要导入一些扩展库,您可以在http://xsltsl.sourceforge.net/下载http://prdownloads.sourceforge.net/xsltsl/xsltsl-1.2.1.zipZIP文件,并在我生成的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> </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 > $LastDayOfMonth">
<xsl:choose>
<xsl:when test="($CurrentMonth + 1) = 12 or ($CurrentMonth + 1) < 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) > 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 > $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值即可检查其输出。
输入:
21/08/2013
输出:
Current given Date is : 21/08/2013
Updated date is : 28/08/2013
输入:
16/10/2008
输出:
Current given Date is : 16/10/2008
Updated date is : 23/10/2008