XSL template for adding days
I can’t believe it’s so complex to add couple of days to a certain date. I needed an XSLT way of calculating dates with input parameters for date (format YYYY-MM-DD) and number of days (number). I know, some of you say use EXSLT. After not getting it to work, I’ve decided to do my own version.
Please note that this template is not for calculating more than one month (for example to add 50 days. And date has to be in ISO format (YYYY-MM-DD). It can be a starting point for your modifications and needs to work with dates.
<xsl:template name="calcDate">
<xsl:param name="date"/>
<xsl:param name="days"/>
<xsl:param name="oldMonth"><xsl:value-of select="substring($date,6,2)"/></xsl:param>
<xsl:param name="oldYear"><xsl:value-of select="substring($date,1,4)"/></xsl:param>
<xsl:param name="oldDay"><xsl:value-of select="substring($date,9,2)"/></xsl:param>
<xsl:param name="newMonth">
<xsl:choose>
<xsl:when test="$oldMonth = '01'">
<xsl:choose>
<xsl:when test="number($oldDay) + $days <= 31">01</xsl:when>
<xsl:otherwise>02</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="$oldMonth = '02'">
<xsl:choose>
<xsl:when test="($oldYear mod 4 = 0 and number($oldDay) + $days <= 29) or ($oldYear mod 4 != 0 and number($oldDay) + $days <= 28)">02</xsl:when>
<xsl:otherwise>03</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="$oldMonth = '03'">
<xsl:choose>
<xsl:when test="number($oldDay) + $days <= 31">03</xsl:when>
<xsl:otherwise>04</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="$oldMonth = '04'">
<xsl:choose>
<xsl:when test="number($oldDay) + $days <= 30">04</xsl:when>
<xsl:otherwise>05</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="$oldMonth = '05'">
<xsl:choose>
<xsl:when test="number($oldDay) + $days <= 31">05</xsl:when>
<xsl:otherwise>06</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="$oldMonth = '06'">
<xsl:choose>
<xsl:when test="number($oldDay) + $days <= 30">06</xsl:when>
<xsl:otherwise>07</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="$oldMonth = '07'">
<xsl:choose>
<xsl:when test="number($oldDay) + $days <= 31">07</xsl:when>
<xsl:otherwise>08</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="$oldMonth = '08'">
<xsl:choose>
<xsl:when test="number($oldDay) + $days <= 31">08</xsl:when>
<xsl:otherwise>09</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="$oldMonth = '09'">
<xsl:choose>
<xsl:when test="number($oldDay) + $days <= 30">09</xsl:when>
<xsl:otherwise>10</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="$oldMonth = '10'">
<xsl:choose>
<xsl:when test="number($oldDay) + $days <= 31">10</xsl:when>
<xsl:otherwise>11</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="$oldMonth = '11'">
<xsl:choose>
<xsl:when test="number($oldDay) + $days <= 30">11</xsl:when>
<xsl:otherwise>12</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="$oldMonth = '12'">
<xsl:choose>
<xsl:when test="number($oldDay) + $days <= 31">12</xsl:when>
<xsl:otherwise>01</xsl:otherwise>
</xsl:choose>
</xsl:when>
</xsl:choose>
</xsl:param>
<xsl:param name="newYear">
<xsl:choose>
<xsl:when test="$oldMonth = '12' and (number($oldDay) + $days) >= 31"><xsl:value-of select="number($oldYear) + 1"/></xsl:when>
<xsl:otherwise><xsl:value-of select="$oldYear"/></xsl:otherwise>
</xsl:choose>
</xsl:param>
<xsl:param name="newDay">
<xsl:choose>
<xsl:when test="$oldMonth = '01'">
<xsl:choose>
<xsl:when test="$newMonth = $oldMonth"><xsl:value-of select="number($oldDay) + $days"/></xsl:when>
<xsl:otherwise><xsl:value-of select="number($oldDay) + $days - 31"/></xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="$oldMonth = '02'">
<xsl:choose>
<xsl:when test="$newMonth = $oldMonth"><xsl:value-of select="number($oldDay) + $days"/></xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="$oldYear mod 4 = 0">
<xsl:value-of select="number($oldDay) + $days - 29"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="number($oldDay) + $days - 28"/>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="$oldMonth = '03'">
<xsl:choose>
<xsl:when test="$newMonth = $oldMonth"><xsl:value-of select="number($oldDay) + $days"/></xsl:when>
<xsl:otherwise><xsl:value-of select="number($oldDay) + $days - 31"/></xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="$oldMonth = '04'">
<xsl:choose>
<xsl:when test="$newMonth = $oldMonth"><xsl:value-of select="number($oldDay) + $days"/></xsl:when>
<xsl:otherwise><xsl:value-of select="number($oldDay) + $days - 30"/></xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="$oldMonth = '05'">
<xsl:choose>
<xsl:when test="$newMonth = $oldMonth"><xsl:value-of select="number($oldDay) + $days"/></xsl:when>
<xsl:otherwise><xsl:value-of select="number($oldDay) + $days - 31"/></xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="$oldMonth = '06'">
<xsl:choose>
<xsl:when test="$newMonth = $oldMonth"><xsl:value-of select="number($oldDay) + $days"/></xsl:when>
<xsl:otherwise><xsl:value-of select="number($oldDay) + $days - 30"/></xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="$oldMonth = '07'">
<xsl:choose>
<xsl:when test="$newMonth = $oldMonth"><xsl:value-of select="number($oldDay) + $days"/></xsl:when>
<xsl:otherwise><xsl:value-of select="number($oldDay) + $days - 31"/></xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="$oldMonth = '08'">
<xsl:choose>
<xsl:when test="$newMonth = $oldMonth"><xsl:value-of select="number($oldDay) + $days"/></xsl:when>
<xsl:otherwise><xsl:value-of select="number($oldDay) + $days - 31"/></xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="$oldMonth = '09'">
<xsl:choose>
<xsl:when test="$newMonth = $oldMonth"><xsl:value-of select="number($oldDay) + $days"/></xsl:when>
<xsl:otherwise><xsl:value-of select="number($oldDay) + $days - 30"/></xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="$oldMonth = '10'">
<xsl:choose>
<xsl:when test="$newMonth = $oldMonth"><xsl:value-of select="number($oldDay) + $days"/></xsl:when>
<xsl:otherwise><xsl:value-of select="number($oldDay) + $days - 31"/></xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="$oldMonth = '11'">
<xsl:choose>
<xsl:when test="$newMonth = $oldMonth"><xsl:value-of select="number($oldDay) + $days"/></xsl:when>
<xsl:otherwise><xsl:value-of select="number($oldDay) + $days - 30"/></xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="$oldMonth = '12'">
<xsl:choose>
<xsl:when test="$newMonth = $oldMonth"><xsl:value-of select="number($oldDay) + $days"/></xsl:when>
<xsl:otherwise><xsl:value-of select="number($oldDay) + $days - 31"/></xsl:otherwise>
</xsl:choose>
</xsl:when>
</xsl:choose>
</xsl:param>
<xsl:value-of select="$newYear"/>
<xsl:text>-</xsl:text>
<xsl:value-of select="$newMonth" />
<xsl:text>-</xsl:text>
<xsl:if test="$newDay < 10">0</xsl:if><xsl:value-of select="$newDay"/>
</xsl:if>
</xsl:template>
Usage:
Copy-paste the upper code to the end of your XSL stylesheet (after the last </xsl:template> tag in your data view. Then in your data view you can call the template.
<xsl:call-template name=”calcDate”>
<xsl:with-param name=”date” select=”substring-before(@Created,’T')”/>
<xsl:with-param name=”days” select=”5″/>
</xsl:call-template>
This will return five days from the created date.
There probably IS a better way, I just couldn’t find it.



Wow! It looks really complicated. Have you tried using custom XSLT functions (EXSLT is just an example, but you could create your own functions as well)? I have described the process on my blog @ http://blog.mastykarz.nl/extending-content-query-web-part-xslt-custom-functions/. It’s about extending the Content Query Web Part but I’m pretty sure you could do the same for any other XSLT-using Web Part.
I’d like to something similar but need to add up to 90 days. This is interesting. However, it’s a bit beyond my reach technically. I’ve tried following the directions you gave above using SharePoint designer and I keep getting an error:
This Web Part does not have a valid XSLT stylesheet: Error: End tag ‘xsl:when’ does not match the start tag ‘xsl:value-of’
Hi, Curious in Indiana!
The problem is because of a mismatching end tag. I’ve updated the post to have easier selectable text. Perhaps the quotes were the problem. Othewise if the problem persists, please verify that you have all the <xsl:value-of … tags finishing with a slash before closing them />
Is it just me, or is it crazy that it’s not much easier to do this CRITICAL and BASIC operation inside a SharePoint Designer XPATH Expression filter. Umm.. dateadd maybe?
@JCNET: I was looking for a solution, I couldn’t find anything that worked. If you know an XPATH expression that would work, please let me know.
Very cool – I was in the same boat as you. Thanks!