Icebreaker
Icebreaker

Reputation: 287

How to check if a date falls on a weekend in an XSLT file

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

Answers (3)

C. M. Sperberg-McQueen
C. M. Sperberg-McQueen

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

Michael Kay
Michael Kay

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

Family
Family

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

Related Questions