Last day of a month or a year in XSLT
bpel, oracle, xml, xquery, xslt
Solution
If your processor supports only XSLT 1.0, you can determine the last day of month of any given date by calling the following named template:
<xsl:template name="last-day-of-month">
<xsl:param name="date"/>
<xsl:param name="y" select="substring($date, 1, 4)"/>
<xsl:param name="m" select="substring($date, 6, 2)"/>
<xsl:param name="cal" select="'312831303130313130313031'"/>
<xsl:param name="leap" select="not($y mod 4) and $y mod 100 or not($y mod 400)"/>
<xsl:param name="month-length" select="substring($cal, 2*($m - 1) + 1, 2) + ($m=2 and $leap)" />
<xsl:value-of select="concat($y, '-', $m, '-', $month-length)" />
</xsl:template>
Example call:
<output>
<xsl:call-template name="last-day-of-month">
<xsl:with-param name="date">2012-10-20T20:18:33</xsl:with-param>
</xsl:call-template>
</output>
returns:
<output>2012-10-31</output>
Example call:
<output>
<xsl:call-template name="last-day-of-month">
<xsl:with-param name="date">2012-02-15</xsl:with-param>
</xsl:call-template>
</output>
returns:
<output>2012-02-29</output>
Added:
For completion, in XSLT 2.0 you can do:
xs:date($given-date) - xs:dayTimeDuration(concat('P', day-from-date($given-date) - 1, 'D')) + xs:yearMonthDuration('P1M') - xs:dayTimeDuration('P1D')
Problem
i'm having some issues to make this work on a transformation in Oracle Bpel I receive a date, and a group criteria: mm/yyyy or: yyyy. So, I have to construct an 'start day' and an 'end date' with the date I receive. if the criteria is mm/yyyy, the start day will be the first day of the given month/year, and the end date, the last day of the given month/year. I know there is a function called: functx:last-day-of-month But I cannot make this work in Oracle Bpel, so that's why i'm using this answer: Last day of previous month in XSLT Just want to know how to do that with any given month. Example: for the given date: 2012-10-20T20:18:33 I should return the dates: Start date: 2012-10-01 End date: 2012-10-31 Thanks a lot for any help.