【问题标题】:How to find the 3rd Wednesday of the month in XSLT 1.0如何在 XSLT 1.0 中找到每月的第三个星期三
【发布时间】:2017-08-11 16:19:14
【问题描述】:

我必须找到一个月的下一个第三个星期三,我似乎无法在 XSLT 上找到一个好的解决方案来执行此操作。例如,今天是 8 月 11 日,因此该月的下一个第三个星期三是 8 月 16 日。但如果今天是 8 月 17 日,那么该月的下一个第三个星期三将是 9 月 20 日。

在 XSLT 1.0 中是否可以这样做?

【问题讨论】:

  • 您实际上是在处理输入 XML 文件吗?还是这是纯粹的数学学术练习?
  • 有一个输入 XML 文件包含今天的日期
  • @S.Menon 计算 this 月的第三个星期三已经够复杂了(从我下面的回答中可以看出)。如果您需要任何月的下一个第三个星期三,您需要(a)找到月的第三个星期三,(b)将其与给定日期进行比较,如有必要 (c) 找到 个月的第三个星期三。

标签: xml xslt xslt-1.0


【解决方案1】:

有趣的问题 - 让我们更通用:

使用纯 XSLT 1.0 计算给定月份的第 N 天:

<xsl:template name="Nth-weekday-of-month">
    <xsl:param name="year"/>
    <xsl:param name="month"/><!-- 1..12 = Jan..Dec -->
    <xsl:param name="weekday"/><!-- 0..6 = Sun..Sat -->
    <xsl:param name="N"/>
    <!-- month starts on ... -->
    <xsl:variable name="first-of-month">
        <xsl:call-template name="JDN">
            <xsl:with-param name="year" select="$year" />
            <xsl:with-param name="month" select="$month" />
            <xsl:with-param name="day" select="1" />
        </xsl:call-template>
    </xsl:variable>
    <!-- ... day of week -->
    <xsl:variable name="dow-first-of-month" select="($first-of-month + 1) mod 7"/>
    <!-- distance to next day-of-week -->
    <xsl:variable name="diff" select="(7 + $weekday - $dow-first-of-month) mod 7"/>
    <!-- next day-of-week -->
        <xsl:call-template name="GD">
            <xsl:with-param name="JDN" select="$first-of-month + $diff + 7*($N - 1)" />
        </xsl:call-template>
</xsl:template> 

<xsl:template name="JDN">
    <xsl:param name="year"/>
    <xsl:param name="month"/>
    <xsl:param name="day"/>
    <!-- calculate JDN  -->
    <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:template name="GD">
    <xsl:param name="JDN"/>
    <xsl:variable name="f" select="$JDN + 1401 + floor((floor((4 * $JDN + 274277) div 146097) * 3) div 4) - 38"/>
    <xsl:variable name="e" select="4*$f + 3"/>
    <xsl:variable name="g" select="floor(($e mod 1461) div 4)"/>
    <xsl:variable name="h" select="5*$g + 2"/>
    <xsl:variable name="D" select="floor(($h mod 153) div 5 ) + 1"/>
    <xsl:variable name="M" select="(floor($h div 153) + 2) mod 12 + 1"/>
    <xsl:variable name="Y" select="floor($e div 1461) - 4716 + floor((14 - $M) div 12)"/>

    <xsl:value-of select="$Y" />    
    <xsl:value-of select="format-number($M, '-00')"/>
    <xsl:value-of select="format-number($D, '-00')"/>
</xsl:template> 

调用示例:

<xsl:call-template name="Nth-weekday-of-month">
    <xsl:with-param name="year" select="2017" />
    <xsl:with-param name="month" select="8" />
    <xsl:with-param name="weekday" select="3" />
    <xsl:with-param name="N" select="3" />
</xsl:call-template>

返回2017-08-16,即 2017 年 8 月第三个星期三的日期。


演示 2014-2017 年每个月第三个星期三的计算:http://xsltransform.net/a9Gixf/1

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-11-30
    • 2013-05-15
    • 1970-01-01
    • 1970-01-01
    • 2019-02-12
    • 2021-08-21
    • 2014-05-10
    相关资源
    最近更新 更多