<?xml version="1.0"?>
<!--
$Id: date-util.xslt,v 1.38 2007/05/29 18:10:04 plehegar Exp $

This XSLT stylesheet offers 3 functions:
- makeDateFriendly take a date in format YYYYMMDD (param: date) and transforms it in the format dd Month YYYY 
- makeMonthFriendly takes the number of a month (param: month) and gives its literal from
- makeDateNumeric takes a date in format dd Month YYYY (param: friendlyDate) and givtes it literal form (YYYYMMDD)
-->
<?xml-stylesheet href="http://www.w3.org/StyleSheets/base.css" type="text/css"?>
<?xml-stylesheet href="http://www.w3.org/2002/02/style-xsl.css" type="text/css"?>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:date="http://www.w3.org/2001/08/date-util.xslt" version="1.0" xmlns:str="http://www.w3.org/2001/10/str-util.xsl">

  <xsl:import href="../10/str-util.xsl"/>
<div xmlns="http://www.w3.org/1999/xhtml">
           <h1>
    <a href="http://www.w3.org/">
      <img src="http://www.w3.org/Icons/w3c_home" alt="W3C" />
    </a>

    XSLT Templates to manipulate dates</h1>
    <h2>Status</h2>
    <p>The templates in this stylesheet are used in several other ones. Please don't modify it without letting me know and don't break the current exposed API.</p>
    <h2>Templates</h2>

    <dl>
        <dt>date:makeDateFriendly</dt>
        <dd>Parameter: <code>date</code> being a date in YYYYMMDD format. Transforms it into an English litteral date (e.g. 20001005 -> 5 October 2001)</dd>
        <dt>date:makeMonthFriendly</dt>
        <dd>Parameter: 0&lt;<code>month</code>&lt;13. Transforms it into an English litteral month (e.g. 10->October)</dd>
        <dt>date:makeDateNumeric</dt>
        <dd>Parameter: <code>friendlyDate</code> (an English litteral date). Transforms it into a numeric date, format YYYYMMDD. If a non-null<code>format-iso</code> parameter is passed, it will be formated ala YYYY-MM-DD</dd>
        <dt>date:makeAbbrDateNumeric</dt>
        <dd>Parameter: <code>abbrDate</code>. Transforms a date ala "Sep 12 2002" into a date formatted ala YYYY-MM-DD</dd>
	<dt>date:extract-date</dt>
        <dd>Parameter: <code>year</code>, <code>string</code> (optional, default value to the value of the current node). Extracts a date from <code>string</code> within the given year (works for date formated ala 16 April 2002) and returns it as YYYYMMDD</dd>
        <dt>date:extract-date-between</dt>
        <dd>Parameter: <code>low_bound</code>, <code>high_bound</code>. Extract any date from the current node which is between <code>low_bound</code> and <code>high_bound</code></dd>
    </dl>
<hr/>
<address>$Id: date-util.xslt,v 1.38 2007/05/29 18:10:04 plehegar Exp $<br/><a href="../../People/Dom/">Dominique Hazael-Massieux</a></address>
<hr/>
</div>

<xsl:variable name="date:month_list" select="document('../../2000/04/mem-news/date-util.xml')/dummyRoot/months"/>

<xsl:template name="date:makeDateFriendly">
        <xsl:param name="date"/>
        <xsl:variable name="year" select="substring($date,1,4)"/>
        <xsl:value-of select="concat(number(substring($date,7,2)),' ')"/><xsl:call-template name="date:makeMonthFriendly"><xsl:with-param name="month" select="substring($date,5,2)"/></xsl:call-template><xsl:value-of select="concat(' ',$year)"/>
</xsl:template>

<xsl:template name="date:makeMonthFriendly">
        <xsl:param name="month"/>
        <xsl:value-of select="$date:month_list/month[@num=number($month)]"/>
</xsl:template>

<xsl:template name="date:makeDateNumeric">
        <xsl:param name="friendlyDate"/>
        <xsl:param name="format-iso"/>
        <xsl:variable name="separator">
          <xsl:if test="$format-iso">
            <xsl:text>-</xsl:text>
          </xsl:if>
        </xsl:variable>
        <xsl:variable name="friendlyDate2" select="normalize-space($friendlyDate)"/>
        <xsl:value-of select="concat(
                              substring-after(substring-after($friendlyDate2,' '),' '),
                              $separator,
                              format-number($date:month_list/month[.=substring-before(substring-after($friendlyDate2,' '),' ')]/@num,'00'),
                              $separator,
                              format-number(number(translate(substring-before($friendlyDate2,' '),'dhrst','')),'00')
                              )"/>
</xsl:template>


<xsl:template name="date:makeAbbrDateNumeric">
  <xsl:param name="abbrDate"/>
  <xsl:value-of select="concat(
                        substring-after(substring-after($abbrDate,' '),' '),'-',
                        format-number($date:month_list/month[@abbr=substring-before($abbrDate,' ')]/@num,'00'),'-',
                        format-number(number(substring-before(substring-after($abbrDate,' '),' ')),'00')
                        )"/>
</xsl:template>

  <xsl:template name="date:extract-date">
    <xsl:param name="string" select="normalize-space(.)"/>
    <xsl:param name="year"/>
    <xsl:if test="contains($string,concat(' ',$year))">
      <!-- Cut what's before the word before the year (supposingly the month) -->
      <xsl:variable name="before-month">
        <xsl:call-template name="str:keep-before-last">
          <xsl:with-param name="string" select="substring-before($string,concat(' ',$year))"/>
          <xsl:with-param name="delimiter" select="' '"/>
        </xsl:call-template>
      </xsl:variable>
      <!-- The month is what's between the year and the before-month strings -->
      <xsl:variable name="month" select="normalize-space(substring-after(substring-before($string,$year),concat($before-month,' ')))"/> 

      <!-- The day is the last word of the before-month string -->
      <xsl:variable name="day">
        <xsl:variable name="before-day">          
          <xsl:call-template name="str:keep-before-last">
            <xsl:with-param name="string" select="$before-month"/>
            <xsl:with-param name="delimiter" select="' '"/>
          </xsl:call-template>
        </xsl:variable>

        <!-- And the complete date is the concatenation of the day, month and year -->
        <xsl:value-of select="normalize-space(substring-after(substring-before($string,concat($month,' ',$year)),concat($before-day,' ')))"/> 
      </xsl:variable>

      <!-- We make it numeric so that we can manipulate it more easily -->
      <xsl:variable name="date">
        <xsl:call-template name="date:makeDateNumeric">
          <xsl:with-param name="friendlyDate" select="concat($day,' ',$month,' ',$year)"/>
        </xsl:call-template>
      </xsl:variable>

      <!-- Is that a number ? If yes, we have probably found what we were looking for -->
      <xsl:if test="number($date)">
        <xsl:value-of select="concat($date,' ')"/>
      </xsl:if>

      <!-- and we extract the date in the remaining of the string -->
      <xsl:if test="contains(substring-after($string,$year),$year)">
        <xsl:call-template name="date:extract-date">
          <xsl:with-param name="year" select="$year"/>
          <xsl:with-param name="string" select="substring-after($string,$year)"/>
        </xsl:call-template>
      </xsl:if>
    </xsl:if>
  </xsl:template>

  <xsl:template name="date:extract-date-between">
    <xsl:param name="low_bound"/>
    <xsl:param name="high_bound"/>

    <xsl:variable name="year1" select="substring($low_bound,1,4)"/>
    <xsl:variable name="year2" select="substring($high_bound,1,4)"/>
    <xsl:if test="$year1 &lt;= $year2 and normalize-space($year1)">
      <xsl:variable name="date">
        <xsl:call-template name="date:extract-date">
          <xsl:with-param name="year" select="$year1"/>
        </xsl:call-template>
      </xsl:variable>
      <xsl:call-template name="date:test-bound">
        <xsl:with-param name="string" select="$date"/>
        <xsl:with-param name="low_bound" select="$low_bound"/>
        <xsl:with-param name="high_bound" select="$high_bound"/>
      </xsl:call-template>

      <xsl:if test="$year1 &lt; $year2">
        <xsl:call-template name="date:extract-date-between">
          <xsl:with-param name="low_bound" select="concat($year1+1,'0101')"/>
          <xsl:with-param name="high_bound" select="$high_bound"/>
        </xsl:call-template>
      </xsl:if>
    </xsl:if>
  </xsl:template>

  <!-- Not for external use, API free -->
  <xsl:template name="date:test-bound">
    <xsl:param name="string"/>
    <xsl:param name="low_bound"/>
    <xsl:param name="high_bound"/>
    <xsl:if test="substring-before($string,' ') &lt; $high_bound and substring-before($string,' ') &gt; $low_bound">
      <xsl:value-of select="concat(substring-before($string,' '),' ')"/>
    </xsl:if>
    <xsl:if test="normalize-space(substring-after($string,' '))">
      <xsl:call-template name="date:test-bound">
        <xsl:with-param name="string" select="substring-after($string,' ')"/>
        <xsl:with-param name="low_bound" select="$low_bound"/>
        <xsl:with-param name="high_bound" select="$high_bound"/>
      </xsl:call-template>
    </xsl:if>
  </xsl:template>
</xsl:stylesheet>




