在XSLT中忽略时间部分,将XML日期与节假日、周末对比
解决XSLT中日期与节假日/周末对比及日期调整问题
核心问题解决:统一日期时间格式
要对比orderDate与节假日,首先需要将orderDate的时间部分置为00:00:00,和节假日列表的时间格式统一。以下是两种实现方式:
方法1:利用XSLT 2.0+日期类型转换
<!-- 从orderDate属性提取标准化日期(时间强制置0) --> <xsl:variable name="normalizedOrderDate" as="xs:dateTime"> <xsl:value-of select="xs:dateTime(@orderDate) cast as xs:date || 'T00:00:00'"/> </xsl:variable>
方法2:字符串截取(兼容低版本XSLT)
<xsl:variable name="normalizedOrderDate" select="concat(substring(@orderDate, 1, 10), 'T00:00:00')"/>
对比节假日与周末
1. 判断是否为节假日
标准化后的日期可以直接和$holidays中的节点值匹配:
<!-- 检查当前标准化日期是否在节假日列表中 --> <xsl:variable name="isHoliday" select="$holidays/date[. = $normalizedOrderDate]"/>
2. 判断是否为周末
借助XSLT 2.0+的日期函数获取星期数(1=周一,7=周日):
<xsl:variable name="orderDateAsDate" as="xs:date" select="xs:date(substring(@orderDate, 1, 10))"/> <!-- 周六(6)或周日(7)判定为周末 --> <xsl:variable name="isWeekend" select="day-from-week($orderDateAsDate) = 6 or day-from-week($orderDateAsDate) = 7"/>
日期调整:加3天并避开节假日/周末
通过递归模板实现自动顺延逻辑(遇节假日或周末则额外加1天,直到得到有效工作日):
<xsl:template name="calculateAdjustedDate"> <xsl:param name="currentDate" as="xs:date"/> <xsl:param name="daysToAdd" as="xs:integer" select="3"/> <!-- 计算累加后的临时日期 --> <xsl:variable name="tempDate" as="xs:date" select="$currentDate + xs:dayTimeDuration(concat('P', $daysToAdd, 'D'))"/> <!-- 转换为带0时间的格式用于节假日对比 --> <xsl:variable name="tempDateTime" as="xs:dateTime" select="$tempDate || 'T00:00:00'"/> <!-- 判断是否需要顺延 --> <xsl:variable name="needsAdjustment" select="$holidays/date[. = $tempDateTime] or day-from-week($tempDate) = 6 or day-from-week($tempDate) = 7"/> <xsl:choose> <xsl:when test="$needsAdjustment"> <!-- 需要顺延则递归调用,额外加1天 --> <xsl:call-template name="calculateAdjustedDate"> <xsl:with-param name="currentDate" select="$tempDate"/> <xsl:with-param name="daysToAdd" select="1"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <!-- 返回最终有效日期 --> <xsl:value-of select="$tempDate || 'T00:00:00'"/> </xsl:otherwise> </xsl:choose> </xsl:template>
使用方式示例:
<!-- 提取orderDate的日期部分作为基准 --> <xsl:variable name="baseDate" as="xs:date" select="xs:date(substring(@orderDate, 1, 10))"/> <!-- 调用模板计算调整后的日期 --> <adjustedOrderDate> <xsl:call-template name="calculateAdjustedDate"> <xsl:with-param name="currentDate" select="$baseDate"/> </xsl:call-template> </adjustedOrderDate>
内容的提问来源于stack exchange,提问作者jritt
相关产品推荐
相关产品推荐

