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 |