XSLT:两个日期之间的年份差异
XSLT: Year difference between two dates
我想计算 XSLT 2.0 中两个日期之间的年份差异。我试过了:
xs:dayTimeDuration(xs:date('2007-03-02')-xs:date('2002-03-01'))
给我天数的差异:
P1827D
计算两个日期之间以年、月和天为单位的某种“规范化”xs:duration
的函数会有帮助,例如P1Y0M1D
在这个例子中,我可以从中提取年份 P1Y
。如上所述,从仅由天组成的 xs:duration
中提取年份是不可能的(而且也没有多大意义)。
那么如何计算两个日期的年差,而不是天数?
我猜 (!) 你想要 return 一个等于 age 以整年表示的结果,使用年龄增加的习惯规则每个生日一个。这可以使用以下模板(您可以将其转换为函数)进行计算:
<xsl:template name="age-in-years">
<xsl:param name="start-date"/>
<xsl:param name="end-date"/>
<xsl:variable name="start-year" select="year-from-date($start-date)"/>
<xsl:variable name="start-month" select="month-from-date($start-date)"/>
<xsl:variable name="start-day" select="day-from-date($start-date)"/>
<xsl:variable name="end-year" select="year-from-date($end-date)"/>
<xsl:variable name="end-month" select="month-from-date($end-date)"/>
<xsl:variable name="end-day" select="day-from-date($end-date)"/>
<xsl:value-of select="$end-year - $start-year - number(100 * $end-month + $end-day lt 100 * $start-month + $start-day)" />
</xsl:template>
请注意,这是假设 2 月 29 日出生的人的生日是 non-leap 年的 3 月 1 日。
我自己想出了一个递归的解决方案。它不是性能最好的,但它有效:
<xsl:function name="d:years-diff">
<xsl:param name="old.date" as="xs:date"/>
<xsl:param name="new.date" as="xs:date"/>
<xsl:variable name="one-year" select="xs:yearMonthDuration('P1Y')"/>
<xsl:choose>
<xsl:when test="$old.date + $one-year <= $new.date">
<xsl:sequence select="$one-year + d:years-diff($old.date + $one-year, $new.date)"/>
</xsl:when>
<xsl:otherwise>
<xsl:sequence select="xs:yearMonthDuration('P0Y')"/>
</xsl:otherwise>
</xsl:choose>
</xsl:function>
您可以使用以下代码验证函数:
<xsl:template match="/">
<xsl:text>
One day short of five years:
</xsl:text>
<xsl:value-of select="d:years-diff(xs:date('2002-03-02'), xs:date('2007-03-01'))"/>
<xsl:text>
Exactly 5 years:
</xsl:text>
<xsl:value-of select="d:years-diff(xs:date('2002-03-02'), xs:date('2007-03-02'))"/>
<xsl:text>
One day short of one year:
</xsl:text>
<xsl:value-of select="d:years-diff(xs:date('2007-03-02'), xs:date('2006-03-01'))"/>
<xsl:text>
Exactly one year:
</xsl:text>
<xsl:value-of select="d:years-diff(xs:date('2006-03-02'), xs:date('2007-03-02'))"/>
<xsl:text>
One year plus one day:
</xsl:text>
<xsl:value-of select="d:years-diff(xs:date('2006-03-02'), xs:date('2007-03-03'))"/>
<xsl:text>
Same dates:
</xsl:text>
<xsl:value-of select="d:years-diff(xs:date('2007-03-03'), xs:date('2007-03-03'))"/>
</xsl:template>
打印出:
One day short of five years:
P4Y
Exactly 5 years:
P5Y
One day short of one year:
P0M
Exactly one year:
P1Y
One year plus one day:
P1Y
Same dates:
P0M
我想计算 XSLT 2.0 中两个日期之间的年份差异。我试过了:
xs:dayTimeDuration(xs:date('2007-03-02')-xs:date('2002-03-01'))
给我天数的差异:
P1827D
计算两个日期之间以年、月和天为单位的某种“规范化”xs:duration
的函数会有帮助,例如P1Y0M1D
在这个例子中,我可以从中提取年份 P1Y
。如上所述,从仅由天组成的 xs:duration
中提取年份是不可能的(而且也没有多大意义)。
那么如何计算两个日期的年差,而不是天数?
我猜 (!) 你想要 return 一个等于 age 以整年表示的结果,使用年龄增加的习惯规则每个生日一个。这可以使用以下模板(您可以将其转换为函数)进行计算:
<xsl:template name="age-in-years">
<xsl:param name="start-date"/>
<xsl:param name="end-date"/>
<xsl:variable name="start-year" select="year-from-date($start-date)"/>
<xsl:variable name="start-month" select="month-from-date($start-date)"/>
<xsl:variable name="start-day" select="day-from-date($start-date)"/>
<xsl:variable name="end-year" select="year-from-date($end-date)"/>
<xsl:variable name="end-month" select="month-from-date($end-date)"/>
<xsl:variable name="end-day" select="day-from-date($end-date)"/>
<xsl:value-of select="$end-year - $start-year - number(100 * $end-month + $end-day lt 100 * $start-month + $start-day)" />
</xsl:template>
请注意,这是假设 2 月 29 日出生的人的生日是 non-leap 年的 3 月 1 日。
我自己想出了一个递归的解决方案。它不是性能最好的,但它有效:
<xsl:function name="d:years-diff">
<xsl:param name="old.date" as="xs:date"/>
<xsl:param name="new.date" as="xs:date"/>
<xsl:variable name="one-year" select="xs:yearMonthDuration('P1Y')"/>
<xsl:choose>
<xsl:when test="$old.date + $one-year <= $new.date">
<xsl:sequence select="$one-year + d:years-diff($old.date + $one-year, $new.date)"/>
</xsl:when>
<xsl:otherwise>
<xsl:sequence select="xs:yearMonthDuration('P0Y')"/>
</xsl:otherwise>
</xsl:choose>
</xsl:function>
您可以使用以下代码验证函数:
<xsl:template match="/">
<xsl:text>
One day short of five years:
</xsl:text>
<xsl:value-of select="d:years-diff(xs:date('2002-03-02'), xs:date('2007-03-01'))"/>
<xsl:text>
Exactly 5 years:
</xsl:text>
<xsl:value-of select="d:years-diff(xs:date('2002-03-02'), xs:date('2007-03-02'))"/>
<xsl:text>
One day short of one year:
</xsl:text>
<xsl:value-of select="d:years-diff(xs:date('2007-03-02'), xs:date('2006-03-01'))"/>
<xsl:text>
Exactly one year:
</xsl:text>
<xsl:value-of select="d:years-diff(xs:date('2006-03-02'), xs:date('2007-03-02'))"/>
<xsl:text>
One year plus one day:
</xsl:text>
<xsl:value-of select="d:years-diff(xs:date('2006-03-02'), xs:date('2007-03-03'))"/>
<xsl:text>
Same dates:
</xsl:text>
<xsl:value-of select="d:years-diff(xs:date('2007-03-03'), xs:date('2007-03-03'))"/>
</xsl:template>
打印出:
One day short of five years:
P4Y
Exactly 5 years:
P5Y
One day short of one year:
P0M
Exactly one year:
P1Y
One year plus one day:
P1Y
Same dates:
P0M