xsl-list
[Top] [All Lists]

RE: eXSLT date:add template

2006-01-16 04:31:40
The XPath 2.0 functions take the same view: 29 Feb plus one year is 28 Feb.

You can't avoid surprises with date arithmetic. It's not only leap years: 31
March plus 6 months minus 6 months is 30 March.

Michael Kay
http://www.saxonica.com/ 

-----Original Message-----
From: Fraser Goffin [mailto:goffinf(_at_)hotmail(_dot_)com] 
Sent: 16 January 2006 10:58
To: mail(_at_)jenitennison(_dot_)com
Cc: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
Subject: [xsl] eXSLT date:add template

I recently had a need to do some date calculations in XSLT 
(1.0) and I 
thought it would be a good opportunity to take a look at the 
eXSLT function 
and template library.

What I wanted to do was, given a start date (lets call it startDate), 
calculate a new date (lets call it endDate) to be startDate + 
1 year - 1 
day.

I settled on calling the date:add template twice, the first 
time to add the 
duration P1Y and the second time to subtract the day from the 
result of the 
first call (duration -P1D).

This works fine until we get to those pesky leap year dates 
(and even for 
these I'm not saying the implementation is wrong - I am just 
looking for 
clarification of the design). The date that I have a question 
over is (not 
surprisingly) the 29th February !. An example :-

Note: 2004 is a leap year.

The input doc looks like this :-

<eXLST_dateAdd_Test1>
    <startDate>2004-02-29</startDate>
</eXLST_dateAdd_Test1>

and the output like this :-

<eXLST_dateAdd_Test1>
    <startDate>2004-02-29</startDate>
    <currentDatePlus1Year>2005-02-28</currentDatePlus1Year>
    <endDate>2005-02-27</endDate>
</eXLST_dateAdd_Test1>

Here endDate is shown as the 27th Feb. One might expect this 
to be the 28th, 
but it all depends on whether adding 1 year to the 29th Feb 
should be 28th 
Feb in the following year or 01 March. The implementation 
takes the position 
that it should be 28th Feb and therefore, subtracting 1 day 
yields 27th.

This seems reasonable.

BUT, if I use a startDate of 2004-2-28 I will also get the 
same result. H'mm 
now I'm not so sure, maybe adding 1 year to 29th February 
SHOULD be 01 March 
after all ??

Comments

Fraser.

Here's the simple XSLT I was using to test with :-

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; 
xmlns:date="http://exslt.org/dates-and-times"; 
extension-element-prefixes="date">
    <xsl:import href="../functions/add/date.add.template.xsl"/>
    <xsl:output method="xml" version="1.0" encoding="UTF-8" 
indent="yes"/>
    <xsl:template match="*|@*|text()">
        <xsl:copy>
            <xsl:apply-templates select="*|@*|text()|comment()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="/">
        <xsl:apply-templates/>
    </xsl:template>
    <xsl:template match="startDate">
        <xsl:copy-of select="."/>
            <!-- TASK: Add 1 Year minus 1 day -->
            <!-- Add 1 Year -->
            <xsl:variable name="currentDatePlus1Year">
                <xsl:call-template name="date:add">
                    <xsl:with-param name="date-time" select="."/>
                    <xsl:with-param name="duration" select="'P1Y'"/>
                </xsl:call-template>
            </xsl:variable>
           <currentDatePlus1Year><xsl:value-of 
select="$currentDatePlus1Year"/></currentDatePlus1Year>
            <!-- Subtract 1 Day -->
            <xsl:variable name="endDate">
                <xsl:call-template name="date:add">
                    <xsl:with-param name="date-time" 
select="$currentDatePlus1Year"/>
                    <xsl:with-param name="duration" select="'-P1D'"/>
                </xsl:call-template>
            </xsl:variable>
            <endDate>
                <xsl:value-of select="$endDate"/>
            </endDate>
    </xsl:template>
</xsl:stylesheet>



--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: 
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--





--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--



<Prev in Thread] Current Thread [Next in Thread>