Table of Contents |
Recipe 4.2. Determining the Last Day of the MonthProblemGiven a month and a year, determine the last day of the month. SolutionXSLT 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.0You 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> DiscussionThis 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 AlsoSee Recipe 4.5 for ways to store calendar metadata in XML. |
Table of Contents |