How to find the 3rd Wednesday of the month in XSLT 1.0

无人久伴 提交于 2019-12-08 04:25:53

问题


I have to find the next 3rd Wednesday of a month and I can't seem to come up with a good solution on XSLT to do this. For instance, today is August 11th so the next 3rd Wednesday of the month is August 16th. But if today is August 17th then the next 3rd Wednesday of the month will be Sept 20th.

Is there anyway to do this in XSLT 1.0?


回答1:


Interesting problem - let's make it more generic:

Calculating N-th day-of-week in a given month, using pure XSLT 1.0:

<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> 

Example of call:

<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>

returns 2017-08-16, the date of the 3rd Wednesday in August 2017.


Demo showing calculation of the 3rd Wednesday in every month in the years 2014-2017: http://xsltransform.net/a9Gixf/1



来源:https://stackoverflow.com/questions/45639629/how-to-find-the-3rd-wednesday-of-the-month-in-xslt-1-0

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!