[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

# Re: [xsl] Getting years from duration

 Subject: Re: [xsl] Getting years from duration From: Martin Holmes Date: Fri, 7 Jun 2013 21:07:18 -0700

On 13-06-07 08:57 PM, Michael Sokolov wrote:
```Yeah, that's a bit surprising.  But if you think about it there's a kind
of logic to it -- once you start working with dayTimeDuration, there
isn't any sensible way to know how many years that corresponded to
(because of leap years/seconds, and the Gregorian switch-over year and
so on), as you said yourself.
```

That's true, and it's interesting too. In one sense a duration abstracted from its start and end points loses some of its meaning.

This will do what you want I think:

```let \$d2 := year-from-date(xs:date("1674-11-08"))
let \$d1 := year-from-date(xs:date("1600-12-09"))
return \$d2 - \$d1```

```If you're concerned about rounding (ie you think that 11 years 11 months
should be == 12 years), then you could add 6 months:```

```let \$d2 := year-from-date(xs:date("1674-11-08") +
xs:yearMonthDuration("P6M"))
let \$d1 := year-from-date(xs:date("1600-12-09"))
return \$d2 - \$d1
```

That works nicely. A function that would actually subtract the dates in a more methodical way -- subtracting days, "carrying" any overage to the months, then subtracting the months and carrying, then the years, could give a meaningful result in years, months and days, too. I'll hack that up tomorrow and see if it works. The day subtraction would have to be sensitive to month-length and leap-day.

```Cheers,
Martin```

-Mike

```PS sorry for the XQuery instead of XSL, but the functions and datatypes
are the same...```

On 6/7/2013 11:26 PM, Martin Holmes 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
```