|
Subject: Re: [xsl] Getting years from duration From: Wolfgang Laun <wolfgang.laun@xxxxxxxxx> Date: Sat, 8 Jun 2013 17:09:41 +0200 |
Here's a simple function that avoids all problems arising from the
conversion of two dates to a duration. Age in completed years can be
computed by a simple comparison of months and days:
<xsl:function name="wl:age-in-years" as="xs:integer">
<xsl:param name="birth" as="xs:date"/>
<xsl:param name="death" as="xs:date"/>
<xsl:variable name="birthYear" as="xs:integer"
select="year-from-date($birth)"/>
<xsl:variable name="birthMonth" as="xs:integer"
select="month-from-date($birth)"/>
<xsl:variable name="birthDay" as="xs:integer"
select="day-from-date($birth)"/>
<xsl:variable name="deathYear" as="xs:integer"
select="year-from-date($death)"/>
<xsl:variable name="deathMonth" as="xs:integer"
select="month-from-date($death)"/>
<xsl:variable name="deathDay" as="xs:integer"
select="day-from-date($death)"/>
<xsl:choose>
<xsl:when test="$deathMonth > $birthMonth">
<xsl:sequence select="$deathYear - $birthYear"/>
</xsl:when>
<xsl:when test="$deathMonth < $birthMonth">
<xsl:sequence select="$deathYear - $birthYear - 1"/>
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="$deathDay >= $birthDay">
<xsl:sequence select="$deathYear - $birthYear"/>
</xsl:when>
<xsl:otherwise><!-- $deathDay < $birthDay -->
<xsl:sequence select="$deathYear - $birthYear - 1"/>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:function>
On 08/06/2013, Martin Holmes <mholmes@xxxxxxx> wrote:
> We came up against what looked like a very simple XPath issue today, and
> hit a brick wall with it. Given data that looks like this:
>
> <person role="author">
> <persName>Milton, John</persName>
> <birth when="1600-12-09"/>
> <death when="1674-11-08"/>
> </person>
>
> we want to calculate the age of the person at death. So we thought:
> subtract the death date from the birth date to get a duration, then
> extract the years from the duration:
>
> <xsl:template match="person">
>
> <xsl:variable name="life" select="xs:date(death/@when) -
> xs:date(birth/@when)"/>
>
> <xsl:variable name="age" select="years-from-duration($life)"/>
>
> <xsl:text>Age at death: </xsl:text>
> <xsl:value-of select="$age"/>
>
> </xsl:template>
>
>
> However, the only value we were able to get back, after trying all
> manner of permutations and casts, was zero. It appears that what comes
> back from the date subtraction (which I think uses the
> op:subtract-dates() operator) is always an xs:dayTimeDuration, and that
> cannot AFAIKS be manipulated into anything from which a year can be
> extracted.
>
> It's always possible to get the number of days and divide by 365.25, but
> it seems strange to have to do that. Given the range of date- and
> duration-related functions, I'm sure there must be some better way of
> getting the result. Does anyone know?
>
> This is using Saxon 9.4.0.6.
>
> Cheers,
> Martin
| Current Thread |
|---|
|
| <- Previous | Index | Next -> |
|---|---|---|
| Re: [xsl] Getting years from durati, Martin Holmes | Thread | Re: [xsl] Getting years from durati, Martin Holmes |
| [xsl] Double records when grouping , Jean-Pierre Lamon | Date | Re: [xsl] Getting years from durati, Martin Holmes |
| Month |