Previous Page Next Page

Recipe 4.2. Determining the Last Day of the Month

Problem

Given a month and a year, determine the last day of the month.

Solution

XSLT 1.0
<xsl:template name="ckbk:last-day-of-month">
     <xsl:param name="month"/>
     <xsl:param name="year"/>
     <xsl:choose>
       <xsl:when test="$month = 2 and 
          not($year mod 4) and 
          ($year mod 100 or not($year mod 400))">
         <xsl:value-of select="29"/>
          </xsl:when>
       <xsl:otherwise>
         <xsl:value-of 
          select="substring('312831303130313130313031',
                         2 * $month - 1,2)"/>
       </xsl:otherwise>
     </xsl:choose>
</xsl:template>

XSLT 2.0

You can translate the 1.0 recipe to a function or take advantage of date math and subtract a day from the first of the following month. This solution is easier to understand but the former is probably faster:

<xsl:function name="ckbk:last-day-of-month" as="xs:integer">

    <xsl:param name="month" as="xs:integer"/>
    <xsl:param name="year" as="xs:integer"/>

    <!--First of the month in given year -->
    <xsl:variable name="date" 
            select="xs:date(concat(xs:string($year),
                         '-',format-number($month,'00'),'-01'))"
            as="xs:date"/>

    <xsl:variable name="m" 
            select="xdt:yearMonthDuration('P1M')" 
            as="xdt:yearMonthDuration"/>

    <xsl:variable name="d" 
            select="xdt:dayTimeDuration('P1D')" 
            as="xdt:dayTimeDuration"/>
 
    <xsl:sequence select="day-from-date(($date + $m) - $d)"/>

</xsl:function>

Discussion

This function has potential application for constructing pages of a calendar. It is simple enough to understand once you know the rules governing a leap year. This function was translated from Lisp, in which the number of days in each month was extracted from a list. I choose to use substring to accomplish the same task. You may prefer to place the logic in additional when elements. You might also store data about each month, including its length, in XML.

See Also

See Recipe 4.5 for ways to store calendar metadata in XML.


Previous Page Next Page