Reputation: 287
I'm trying to create an xsl transformation that will take in a date, add 27 days to it and check to see if that new date falls on a weekend and if it does, it will find the next non weekend day (Monday) and display it otherwise display it as is if it doesn't fall on a weekend. Is this possible and also this needs to take in account leap years.
Upvotes: 1
Views: 2779
Reputation: 25034
Various XSLT 2.0 solutions have been proposed.
In XSLT 1.0 or 2.0, you can use the jday
template defined here to calculate the Julian day number for the input date. Add 27; the sum is the Julian day number of the day 27 days after the input date.
For any Julian day number J, the easiest way to determine the day of the week is to calculate J mod 7: if J mod 7 = 0, the day is a Monday; if J mod 7 is 5 or 6, the day is a Saturday or Sunday.
To find the next Monday, add an appropriate number of days, and use the template jdate
to translate from the Julian day number to the date.
Upvotes: 0
Reputation: 163458
In XSLT 2.0, use
test="xs:integer(format-date($date, '[F1]', (), 'ISO', ())) ge 6"
This assumes that the implementation supports the ISO calendar, in which weakdays are numbered from 1=Monday to 7=Sunday.
Alternatively, perhaps better, get the number of days since a known Sunday, and take the result mod 7:
($date - xs:date('1900-MM-DD')) div xs:dateTimeDuration('P1D') mod 7 ge 5
Upvotes: 0
Reputation: 1113
Starting with your date:
<xsl:variable name="date" select="'2013-09-13T00:40:00'" />
Then, apparently, you can use:
<xsl:sequence select="$date +27*xs:dayTimeDuration('P1D')"/>
But this only works in XSLT 2.0, which I don't have.
You can check what day of the week it is by using:
<xsl:variable name="day-of-week">
<xsl:call-template name="calculate-day-of-the-week"> <!--0-6, where 0=Sun,1=Mon,2=Tue,3=Wed,4=Thu,5=Fri,6=Sat-->
<xsl:with-param name="date-time" select="$date" />
</xsl:call-template>
</xsl:variable>
<xsl:template name="calculate-day-of-the-week">
<xsl:param name="date-time"/>
<xsl:param name="date" select="substring-before($date-time,'T')"/>
<xsl:param name="year" select="substring-before($date,'-')"/>
<xsl:param name="month" select="substring-before(substring-after($date,'-'),'-')"/>
<xsl:param name="day" select="substring-after(substring-after($date,'-'),'-')"/>
<xsl:variable name="a" select="floor((14 - $month) div 12)"/>
<xsl:variable name="y" select="$year - $a"/>
<xsl:variable name="m" select="$month + 12 * $a - 2"/>
<xsl:value-of select="($day + $y + floor($y div 4) - floor($y div 100) + floor($y div 400) + floor((31 * $m) div 12)) mod 7"/>
</xsl:template>
'day-of-week' will give you a value of 0-6 (Sun to Sat). This will account for leap-years and will work in XSLT 1.0
Then you could use:
<xsl:if test="day-of-week=0>
<xsl:sequence select="$date +28*xs:dayTimeDuration('P1D')"/>
</xsl:if>
<xsl:if test="day-of-week=6>
<xsl:sequence select="$date +29*xs:dayTimeDuration('P1D')"/>
</xsl:if>
I can't test this code without XSLT 2.0, but hopefully this will get you going in the general direction.
Upvotes: 3