/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999-2003 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, Lotus
 * Development Corporation., http://www.lotus.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

package org.apache.xalan.lib;


import java.util.Date;
import java.util.TimeZone;
import java.util.Calendar;
import java.text.SimpleDateFormat;
import java.text.DateFormat;
import java.text.ParseException;
import org.apache.xpath.objects.XString;
import org.apache.xpath.objects.XNumber;
import org.apache.xpath.objects.XBoolean;
import org.apache.xpath.objects.XObject;

/**
 * <meta name="usage" content="general"/>
 * This class contains EXSLT dates and times extension functions.
 * It is accessed by specifying a namespace URI as follows:
 * <pre>
 *    xmlns:datetime="http://exslt.org/dates-and-times"
 * </pre>
 * 
 * The documentation for each function has been copied from the relevant
 * EXSLT Implementer page.
 * 
 * @see <a href="http://www.exslt.org/">EXSLT</a>
 */

public class ExsltDatetime
{
    // Datetime formats (era and zone handled separately).
    static final String dt = "yyyy-MM-dd'T'HH:mm:ss";
    static final String d = "yyyy-MM-dd";
    static final String gym = "yyyy-MM";
    static final String gy = "yyyy";
    static final String gmd = "--MM-dd";
    static final String gm = "--MM--";
    static final String gd = "---dd";
    static final String t = "HH:mm:ss";

    /**
     * The date:date-time function returns the current date and time as a date/time string. 
     * The date/time string that's returned must be a string in the format defined as the 
     * lexical representation of xs:dateTime in 
     * <a href="http://www.w3.org/TR/xmlschema-2/#dateTime">[3.2.7 dateTime]</a> of
     * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a>.
     * The date/time format is basically CCYY-MM-DDThh:mm:ss, although implementers should consult
     * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a> and 
     * <a href="http://www.iso.ch/markete/8601.pdf">[ISO 8601]</a> for details.
     * The date/time string format must include a time zone, either a Z to indicate Coordinated 
     * Universal Time or a + or - followed by the difference between the difference from UTC 
     * represented as hh:mm. 
     */
    public static XString dateTime()
    {
      Calendar cal = Calendar.getInstance();
      Date datetime = cal.getTime();
      // Format for date and time.
      SimpleDateFormat dateFormat = new SimpleDateFormat(dt);
      
      StringBuffer buff = new StringBuffer(dateFormat.format(datetime));
      // Must also include offset from UTF.
      // Get the offset (in milliseconds).
      int offset = cal.get(Calendar.ZONE_OFFSET) + cal.get(Calendar.DST_OFFSET);
      // If there is no offset, we have "Coordinated
      // Universal Time."
      if (offset == 0)
        buff.append("Z");
      else
      {
        // Convert milliseconds to hours and minutes
        int hrs = offset/(60*60*1000);
        // In a few cases, the time zone may be +/-hh:30.
        int min = offset%(60*60*1000);
        char posneg = hrs < 0? '-': '+';
        buff.append(posneg + formatDigits(hrs) + ':' + formatDigits(min));
      }
      return new XString(buff.toString());
    }
    
    /**
     * Represent the hours and minutes with two-digit strings.
     * @param q hrs or minutes.
     * @return two-digit String representation of hrs or minutes.
     */
    private static String formatDigits(int q)
    {
      String dd = String.valueOf(Math.abs(q));
      return dd.length() == 1 ? '0' + dd : dd;
    }

    /**
     * The date:date function returns the date specified in the date/time string given 
     * as the argument. If no argument is given, then the current local date/time, as 
     * returned by date:date-time is used as a default argument. 
     * The date/time string that's returned must be a string in the format defined as the 
     * lexical representation of xs:dateTime in 
     * <a href="http://www.w3.org/TR/xmlschema-2/#dateTime">[3.2.7 dateTime]</a> of
     * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a>.
     * If the argument is not in either of these formats, date:date returns an empty string (''). 
     * The date/time format is basically CCYY-MM-DDThh:mm:ss, although implementers should consult 
     * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a> and 
     * <a href="http://www.iso.ch/markete/8601.pdf">[ISO 8601]</a> for details. 
     * The date is returned as a string with a lexical representation as defined for xs:date in 
     * [3.2.9 date] of [XML Schema Part 2: Datatypes]. The date format is basically CCYY-MM-DD, 
     * although implementers should consult [XML Schema Part 2: Datatypes] and [ISO 8601] for details.
     * If no argument is given or the argument date/time specifies a time zone, then the date string 
     * format must include a time zone, either a Z to indicate Coordinated Universal Time or a + or - 
     * followed by the difference between the difference from UTC represented as hh:mm. If an argument 
     * is specified and it does not specify a time zone, then the date string format must not include 
     * a time zone. 
     */
    public static XString date(String datetimeIn)
      throws ParseException
    {
      String[] edz = getEraDatetimeZone(datetimeIn);
      String leader = edz[0];
      String datetime = edz[1];
      String zone = edz[2];
      if (datetime == null || zone == null) 
        return new XString("");
                    
      String[] formatsIn = {dt, d};
      String formatOut = d;
      Date date = testFormats(datetime, formatsIn);
      if (date == null) return new XString("");
      
      SimpleDateFormat dateFormat = new SimpleDateFormat(formatOut);
      dateFormat.setLenient(false);
      String dateOut = dateFormat.format(date);      
      if (dateOut.length() == 0)
          return new XString("");
      else        
        return new XString(leader + dateOut + zone);
    }
    
    
    /**
     * See above.
     */
    public static XString date()
    {
      String datetime = dateTime().toString();
      String date = datetime.substring(0, datetime.indexOf("T"));
      String zone = datetime.substring(getZoneStart(datetime));
      return new XString(date + zone);
    }
    
    /**
     * The date:time function returns the time specified in the date/time string given 
     * as the argument. If no argument is given, then the current local date/time, as 
     * returned by date:date-time is used as a default argument. 
     * The date/time string that's returned must be a string in the format defined as the 
     * lexical representation of xs:dateTime in 
     * <a href="http://www.w3.org/TR/xmlschema-2/#dateTime">[3.2.7 dateTime]</a> of
     * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a>. 
     * If the argument string is not in this format, date:time returns an empty string (''). 
     * The date/time format is basically CCYY-MM-DDThh:mm:ss, although implementers should consult 
     * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a> and 
     * <a href="http://www.iso.ch/markete/8601.pdf">[ISO 8601]</a> for details.
     * The date is returned as a string with a lexical representation as defined for xs:time in 
     * <a href="http://www.w3.org/TR/xmlschema-2/#time">[3.2.8 time]</a> of [XML Schema Part 2: Datatypes].
     * The time format is basically hh:mm:ss, although implementers should consult [XML Schema Part 2: 
     * Datatypes] and [ISO 8601] for details. 
     * If no argument is given or the argument date/time specifies a time zone, then the time string 
     * format must include a time zone, either a Z to indicate Coordinated Universal Time or a + or - 
     * followed by the difference between the difference from UTC represented as hh:mm. If an argument 
     * is specified and it does not specify a time zone, then the time string format must not include 
     * a time zone. 
     */
    public static XString time(String timeIn)
      throws ParseException      
    {
      String[] edz = getEraDatetimeZone(timeIn);
      String time = edz[1];
      String zone = edz[2];
      if (time == null || zone == null) 
        return new XString("");
                    
      String[] formatsIn = {dt, d};
      String formatOut =  t;
      Date date = testFormats(time, formatsIn);
      if (date == null) return new XString("");
      SimpleDateFormat dateFormat = new SimpleDateFormat(formatOut);
      String out = dateFormat.format(date);
      return new XString(out + zone);
    }

    /**
     * See above.
     */
    public static XString time()
    {
      String datetime = dateTime().toString();
      String time = datetime.substring(datetime.indexOf("T")+1);
      String zone = datetime.substring(getZoneStart(datetime));      
      return new XString(time + zone);
    } 
       
    /**
     * The date:year function returns the year of a date as a number. If no 
     * argument is given, then the current local date/time, as returned by 
     * date:date-time is used as a default argument.
     * The date/time string specified as the first argument must be a right-truncated 
     * string in the format defined as the lexical representation of xs:dateTime in one 
     * of the formats defined in 
     * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a>.
     * The permitted formats are as follows: 
     *   xs:dateTime (CCYY-MM-DDThh:mm:ss) 
     *   xs:date (CCYY-MM-DD) 
     *   xs:gYearMonth (CCYY-MM) 
     *   xs:gYear (CCYY) 
     * If the date/time string is not in one of these formats, then NaN is returned. 
     */
    public static XNumber year(String datetimeIn)
      throws ParseException
    {
      String[] edz = getEraDatetimeZone(datetimeIn);
      boolean ad = edz[0].length() == 0; // AD (Common Era -- empty leader)
      String datetime = edz[1];
      if (datetime == null) 
        return new XNumber(Double.NaN);
      
      String[] formats = {dt, d, gym, gy};
      double yr = getNumber(datetime, formats, Calendar.YEAR);
      if (ad || yr == Double.NaN)
        return new XNumber(yr);
      else
        return new XNumber(-yr);
    }
     
    /**
     * See above.
     */
    public static XNumber year()
    {
      Calendar cal = Calendar.getInstance();
      return new XNumber(cal.get(Calendar.YEAR));
    }
    
    /**
     * The date:year function returns the month of a date as a number. If no argument 
     * is given, then the current local date/time, as returned by date:date-time is used 
     * as a default argument. 
     * The date/time string specified as the first argument is a left or right-truncated 
     * string in the format defined as the lexical representation of xs:dateTime in one of 
     * the formats defined in 
     * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a>.
     * The permitted formats are as follows: 
     *    xs:dateTime (CCYY-MM-DDThh:mm:ss) 
     *    xs:date (CCYY-MM-DD) 
     *    xs:gYearMonth (CCYY-MM)
     *    xs:gMonth (--MM--) 
     *    xs:gMonthDay (--MM-DD)
     * If the date/time string is not in one of these formats, then NaN is returned. 
     */
    public static XNumber monthInYear(String datetimeIn)
      throws ParseException
    {
      String[] edz = getEraDatetimeZone(datetimeIn);
      String datetime = edz[1];
      if (datetime == null)
        return new XNumber(Double.NaN);      
      
      String[] formats = {dt, d, gym, gm, gmd};
      return new XNumber(getNumber(datetime, formats, Calendar.MONTH));
    }
    
    /**
     * See above.
     */
    public static XNumber monthInYear()
    {      
      Calendar cal = Calendar.getInstance();
      return new XNumber(cal.get(Calendar.MONTH));
   }
    
    /**
     * The date:week-in-year function returns the week of the year as a number. If no argument 
     * is given, then the current local date/time, as returned by date:date-time is used as the 
     * default argument. For the purposes of numbering, counting follows ISO 8601: week 1 in a year 
     * is the week containing the first Thursday of the year, with new weeks beginning on a Monday. 
     * The date/time string specified as the argument is a right-truncated string in the format 
     * defined as the lexical representation of xs:dateTime in one of the formats defined in 
     * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a>. The 
     * permitted formats are as follows: 
     *    xs:dateTime (CCYY-MM-DDThh:mm:ss) 
     *    xs:date (CCYY-MM-DD) 
     * If the date/time string is not in one of these formats, then NaN is returned. 
     */
    public static XNumber weekInYear(String datetimeIn)
      throws ParseException
    {
      String[] edz = getEraDatetimeZone(datetimeIn);
      String datetime = edz[1];
      if (datetime == null) 
        return new XNumber(Double.NaN);      
      
      String[] formats = {dt, d};
      return new XNumber(getNumber(datetime, formats, Calendar.WEEK_OF_YEAR));
    }
        
    /**
     * See above.
     */
    public static XNumber weekInYear()
    {
       Calendar cal = Calendar.getInstance();
      return new XNumber(cal.get(Calendar.WEEK_OF_YEAR));
   }

    /**
     * The date:day-in-year function returns the day of a date in a year 
     * as a number. If no argument is given, then the current local
     * date/time, as returned by date:date-time is used the default argument.
     * The date/time string specified as the argument is a right-truncated 
     * string in the format defined as the lexical representation of xs:dateTime
     * in one of the formats defined in 
     * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a>. 
     * The permitted formats are as follows:
     *     xs:dateTime (CCYY-MM-DDThh:mm:ss)
     *     xs:date (CCYY-MM-DD) 
     * If the date/time string is not in one of these formats, then NaN is returned. 
     */
    public static XNumber dayInYear(String datetimeIn)
      throws ParseException
    {
      String[] edz = getEraDatetimeZone(datetimeIn);
      String datetime = edz[1];
      if (datetime == null) 
        return new XNumber(Double.NaN);            
      
      String[] formats = {dt, d};
      return new XNumber(getNumber(datetime, formats, Calendar.DAY_OF_YEAR));
    }
    
    /**
     * See above.
     */
    public static XNumber dayInYear()
    {
       Calendar cal = Calendar.getInstance();
      return new XNumber(cal.get(Calendar.DAY_OF_YEAR));
   }
    

    /**
     * The date:day-in-month function returns the day of a date as a number. 
     * If no argument is given, then the current local date/time, as returned 
     * by date:date-time is used the default argument. 
     * The date/time string specified as the argument is a left or right-truncated 
     * string in the format defined as the lexical representation of xs:dateTime 
     * in one of the formats defined in 
     * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a>. 
     * The permitted formats are as follows: 
     *      xs:dateTime (CCYY-MM-DDThh:mm:ss) 
     *      xs:date (CCYY-MM-DD) 
     *      xs:gMonthDay (--MM-DD) 
     *      xs:gDay (---DD) 
     * If the date/time string is not in one of these formats, then NaN is returned. 
     */
    public static XNumber dayInMonth(String datetimeIn)
      throws ParseException
    {
      String[] edz = getEraDatetimeZone(datetimeIn);
      String datetime = edz[1];
      String[] formats = {dt, d, gmd, gd};
      double day = getNumber(datetime, formats, Calendar.DAY_OF_MONTH);
      return new XNumber(day);
    }
    
    /**
     * See above.
     */
    public static XNumber dayInMonth()
    {
      Calendar cal = Calendar.getInstance();
      return new XNumber(cal.get(Calendar.DAY_OF_MONTH));
   }
    
    /**
     * The date:day-of-week-in-month function returns the day-of-the-week 
     * in a month of a date as a number (e.g. 3 for the 3rd Tuesday in May). 
     * If no argument is given, then the current local date/time, as returned 
     * by date:date-time is used the default argument. 
     * The date/time string specified as the argument is a right-truncated string
     * in the format defined as the lexical representation of xs:dateTime in one 
     * of the formats defined in 
     * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a>. 
     * The permitted formats are as follows: 
     *      xs:dateTime (CCYY-MM-DDThh:mm:ss) 
     *      xs:date (CCYY-MM-DD) 
     * If the date/time string is not in one of these formats, then NaN is returned. 
     */
    public static XNumber dayOfWeekInMonth(String datetimeIn)
      throws ParseException
    {
      String[] edz = getEraDatetimeZone(datetimeIn);
      String datetime = edz[1];
      if (datetime == null) 
        return new XNumber(Double.NaN);            

      String[] formats =  {dt, d};
      return new XNumber(getNumber(datetime, formats, Calendar.DAY_OF_WEEK_IN_MONTH));
    }
    
    /**
     * See above.
     */
    public static XNumber dayOfWeekInMonth()
    {
       Calendar cal = Calendar.getInstance();
      return new XNumber(cal.get(Calendar.DAY_OF_WEEK_IN_MONTH));
   }
      
    
    /**
     * The date:day-in-week function returns the day of the week given in a 
     * date as a number. If no argument is given, then the current local date/time, 
     * as returned by date:date-time is used the default argument. 
     * The date/time string specified as the argument is a right-truncated string 
     * in the format defined as the lexical representation of xs:dateTime in one 
     * of the formats defined in 
     * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a>. 
     * The permitted formats are as follows: 
     *      xs:dateTime (CCYY-MM-DDThh:mm:ss) 
     *      xs:date (CCYY-MM-DD) 
     * If the date/time string is not in one of these formats, then NaN is returned. 
                            The numbering of days of the week starts at 1 for Sunday, 2 for Monday and so on up to 7 for Saturday.  
     */
    public static XNumber dayInWeek(String datetimeIn)
      throws ParseException
    {
      String[] edz = getEraDatetimeZone(datetimeIn);
      String datetime = edz[1];
      if (datetime == null) 
        return new XNumber(Double.NaN);            

      String[] formats = {dt, d};
      return new XNumber(getNumber(datetime, formats, Calendar.DAY_OF_WEEK));
    }
    
    /**
     * See above.
     */
    public static XNumber dayInWeek()
    {
       Calendar cal = Calendar.getInstance();
      return new XNumber(cal.get(Calendar.DAY_OF_WEEK));
   }        

    /**
     * The date:hour-in-day function returns the hour of the day as a number. 
     * If no argument is given, then the current local date/time, as returned 
     * by date:date-time is used the default argument. 
     * The date/time string specified as the argument is a right-truncated 
     * string  in the format defined as the lexical representation of xs:dateTime
     * in one of the formats defined in 
     * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a>. 
     * The permitted formats are as follows: 
     *     xs:dateTime (CCYY-MM-DDThh:mm:ss) 
     *     xs:time (hh:mm:ss) 
     * If the date/time string is not in one of these formats, then NaN is returned. 
     */
    public static XNumber hourInDay(String datetimeIn)
      throws ParseException
    {
      String[] edz = getEraDatetimeZone(datetimeIn);
      String datetime = edz[1];
      if (datetime == null) 
        return new XNumber(Double.NaN);            
      
      String[] formats = {dt, t};
      return new XNumber(getNumber(datetime, formats, Calendar.HOUR_OF_DAY));
    }
    
    /**
     * See above.
     */
    public static XNumber hourInDay()
    {
       Calendar cal = Calendar.getInstance();
      return new XNumber(cal.get(Calendar.HOUR_OF_DAY));
   }
    
    /**
     * The date:minute-in-hour function returns the minute of the hour 
     * as a number. If no argument is given, then the current local
     * date/time, as returned by date:date-time is used the default argument. 
     * The date/time string specified as the argument is a right-truncated 
     * string in the format defined as the lexical representation of xs:dateTime
     * in one of the formats defined in 
     * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a>. 
     * The permitted formats are as follows: 
     *      xs:dateTime (CCYY-MM-DDThh:mm:ss) 
     *      xs:time (hh:mm:ss) 
     * If the date/time string is not in one of these formats, then NaN is returned. 
     */
    public static XNumber minuteInHour(String datetimeIn)
      throws ParseException
    {
      String[] edz = getEraDatetimeZone(datetimeIn);
      String datetime = edz[1];
      if (datetime == null) 
        return new XNumber(Double.NaN);            
      
      String[] formats = {dt,t};
      return new XNumber(getNumber(datetime, formats, Calendar.MINUTE));
    }    
    
    /**
     * See above.
     */
   public static XNumber minuteInHour()
    {
       Calendar cal = Calendar.getInstance();
      return new XNumber(cal.get(Calendar.MINUTE));
   }    

    /**
     * The date:second-in-minute function returns the second of the minute 
     * as a number. If no argument is given, then the current local 
     * date/time, as returned by date:date-time is used the default argument. 
     * The date/time string specified as the argument is a right-truncated 
     * string in the format defined as the lexical representation of xs:dateTime
     * in one of the formats defined in 
     * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a>. 
     * The permitted formats are as follows: 
     *      xs:dateTime (CCYY-MM-DDThh:mm:ss) 
     *      xs:time (hh:mm:ss) 
     * If the date/time string is not in one of these formats, then NaN is returned. 
     */
    public static XNumber secondInMinute(String datetimeIn)
      throws ParseException
    {
      String[] edz = getEraDatetimeZone(datetimeIn);
      String datetime = edz[1];
      if (datetime == null) 
        return new XNumber(Double.NaN);            
      
      String[] formats = {dt, t};
      return new XNumber(getNumber(datetime, formats, Calendar.SECOND));
    }

    /**
     * See above.
     */
    public static XNumber secondInMinute()
    {
       Calendar cal = Calendar.getInstance();
      return new XNumber(cal.get(Calendar.SECOND));
    }
       
    /**
     * The date:leap-year function returns true if the year given in a date 
     * is a leap year. If no argument is given, then the current local
     * date/time, as returned by date:date-time is used as a default argument. 
     * The date/time string specified as the first argument must be a 
     * right-truncated string in the format defined as the lexical representation
     * of xs:dateTime in one of the formats defined in 
     * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a>. 
     * The permitted formats are as follows: 
     *    xs:dateTime (CCYY-MM-DDThh:mm:ss) 
     *    xs:date (CCYY-MM-DD) 
     *    xs:gYearMonth (CCYY-MM) 
     *    xs:gYear (CCYY) 
     * If the date/time string is not in one of these formats, then NaN is returned. 
     */
    public static XObject leapYear(String datetimeIn)
      throws ParseException
    {
      String[] edz = getEraDatetimeZone(datetimeIn);
      String datetime = edz[1];
      if (datetime == null) 
        return new XNumber(Double.NaN);            
            
      String[] formats = {dt, d, gym, gy};
      double dbl = getNumber(datetime, formats, Calendar.YEAR);
      if (dbl == Double.NaN) 
        return new XNumber(Double.NaN);
      int yr = (int)dbl;
      return new XBoolean(yr % 400 == 0 || (yr % 100 != 0 && yr % 4 == 0));
    }
    
    /**
     * See above.
     */
    public static XBoolean leapYear()
    {
      Calendar cal = Calendar.getInstance();
      int yr = (int)cal.get(Calendar.YEAR);
      return new XBoolean(yr % 400 == 0 || (yr % 100 != 0 && yr % 4 == 0));      
    }    
       
    /**
     * The date:month-name function returns the full name of the month of a date. 
     * If no argument is given, then the current local date/time, as returned by 
     * date:date-time is used the default argument. 
     * The date/time string specified as the argument is a left or right-truncated 
     * string in the format defined as the lexical representation of xs:dateTime in
     *  one of the formats defined in 
     * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a>. 
     * The permitted formats are as follows: 
     *    xs:dateTime (CCYY-MM-DDThh:mm:ss) 
     *    xs:date (CCYY-MM-DD) 
     *    xs:gYearMonth (CCYY-MM) 
     *    xs:gMonth (--MM--) 
     * If the date/time string is not in one of these formats, then an empty string ('') 
     * is returned. 
     * The result is an English month name: one of 'January', 'February', 'March', 
     * 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November' 
     * or 'December'. 
     */
    public static XString monthName(String datetimeIn)
      throws ParseException
    {
      String[] edz = getEraDatetimeZone(datetimeIn);
      String datetime = edz[1];
      if (datetime == null) 
        return new XString("");
      
      String[] formatsIn = {dt, d, gym, gm};
      String formatOut = "MMMM";
      return new XString (getNameOrAbbrev(datetimeIn, formatsIn, formatOut));    
    }
    
    /**
     * See above.
     */
    public static XString monthName()
    {
      Calendar cal = Calendar.getInstance();
      String format = "MMMM";
      return new XString(getNameOrAbbrev(format));  
    }
        
    /**
     * The date:month-abbreviation function returns the abbreviation of the month of 
     * a date. If no argument is given, then the current local date/time, as returned 
     * by date:date-time is used the default argument. 
     * The date/time string specified as the argument is a left or right-truncated 
     * string in the format defined as the lexical representation of xs:dateTime in 
     * one of the formats defined in 
     * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a>. 
     * The permitted formats are as follows: 
     *    xs:dateTime (CCYY-MM-DDThh:mm:ss) 
     *    xs:date (CCYY-MM-DD) 
     *    xs:gYearMonth (CCYY-MM) 
     *    xs:gMonth (--MM--) 
     * If the date/time string is not in one of these formats, then an empty string ('') 
     * is returned. 
     * The result is a three-letter English month abbreviation: one of 'Jan', 'Feb', 'Mar', 
     * 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov' or 'Dec'. 
     * An implementation of this extension function in the EXSLT date namespace must conform 
     * to the behaviour described in this document. 
     */
    public static XString monthAbbreviation(String datetimeIn)
      throws ParseException
    {
      String[] edz = getEraDatetimeZone(datetimeIn);
      String datetime = edz[1];
      if (datetime == null) 
        return new XString("");
      
      String[] formatsIn = {dt, d, gym, gm};
      String formatOut = "MMM";
      return new XString (getNameOrAbbrev(datetimeIn, formatsIn, formatOut));
    }
    
    /**
     * See above.
     */
    public static XString monthAbbreviation()
    {
      String format = "MMM";
      return new XString(getNameOrAbbrev(format));  
    }
        
    /**
     * The date:day-name function returns the full name of the day of the week 
     * of a date.  If no argument is given, then the current local date/time, 
     * as returned by date:date-time is used the default argument. 
     * The date/time string specified as the argument is a left or right-truncated 
     * string in the format defined as the lexical representation of xs:dateTime 
     * in one of the formats defined in 
     * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a>. 
     * The permitted formats are as follows: 
     *     xs:dateTime (CCYY-MM-DDThh:mm:ss) 
     *     xs:date (CCYY-MM-DD) 
     * If the date/time string is not in one of these formats, then the empty string ('') 
     * is returned. 
     * The result is an English day name: one of 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 
     * 'Thursday' or 'Friday'. 
     * An implementation of this extension function in the EXSLT date namespace must conform 
     * to the behaviour described in this document. 
     */
    public static XString dayName(String datetimeIn)
      throws ParseException
    {
      String[] edz = getEraDatetimeZone(datetimeIn);
      String datetime = edz[1];
      if (datetime == null) 
        return new XString("");
            
      String[] formatsIn = {dt, d};
      String formatOut = "EEEE";
      return new XString (getNameOrAbbrev(datetimeIn, formatsIn, formatOut));    
    }
    
    /**
     * See above.
     */
    public static XString dayName()
    {
      String format = "EEEE";
      return new XString(getNameOrAbbrev(format));        
    }    
    
    /**
     * The date:day-abbreviation function returns the abbreviation of the day 
     * of the week of a date. If no argument is given, then the current local 
     * date/time, as returned  by date:date-time is used the default argument. 
     * The date/time string specified as the argument is a left or right-truncated 
     * string in the format defined as the lexical representation of xs:dateTime 
     * in one of the formats defined in 
     * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a>. 
     * The permitted formats are as follows: 
     *     xs:dateTime (CCYY-MM-DDThh:mm:ss) 
     *     xs:date (CCYY-MM-DD) 
     * If the date/time string is not in one of these formats, then the empty string 
     * ('') is returned. 
     * The result is a three-letter English day abbreviation: one of 'Sun', 'Mon', 'Tue', 
     * 'Wed', 'Thu' or 'Fri'. 
     * An implementation of this extension function in the EXSLT date namespace must conform 
     * to the behaviour described in this document. 
     */
    public static XString dayAbbreviation(String datetimeIn)
      throws ParseException
    {
      String[] edz = getEraDatetimeZone(datetimeIn);
      String datetime = edz[1];
      if (datetime == null) 
        return new XString("");            
      
      String[] formatsIn = {dt, d};
      String formatOut = "EEE";
      return new XString (getNameOrAbbrev(datetimeIn, formatsIn, formatOut));
    }
    
    /**
     * See above.
     */
    public static XString dayAbbreviation()
    {
      String format = "EEE";
      return new XString(getNameOrAbbrev(format));              
    }
    
    /**
     * Returns an array with the 3 components that a datetime input string 
     * may contain: - (for BC era), datetime, and zone. If the zone is not
     * valid, return null for that component.
     */
    private static String[] getEraDatetimeZone(String in)
    {
      String leader = "";
      String datetime = in;
      String zone = "";
      if (in.charAt(0)=='-' && !in.startsWith("--"))
      {
        leader = "-"; //  '+' is implicit , not allowed
        datetime = in.substring(1);
      }
      int z = getZoneStart(datetime);
      if (z > 0)
      {
        zone = datetime.substring(z);
        datetime = datetime.substring(0, z);
      }
      else if (z == -2)
        zone = null;
      //System.out.println("'" + leader + "' " + datetime + " " + zone);
      return new String[]{leader, datetime, zone};  
    }    
    
    /**
     * Get the start of zone information if the input ends
     * with 'Z' or +/-hh:mm. If a zone string is not
     * found, return -1; if the zone string is invalid,
     * return -2.
     */
    private static int getZoneStart (String datetime)
    {
      if (datetime.indexOf("Z") == datetime.length()-1)
        return datetime.length()-1;
      else if (datetime.length() >=6 
      		&& datetime.charAt(datetime.length()-3) == ':'
      		&& (datetime.charAt(datetime.length()-6) == '+' 
      		    || datetime.charAt(datetime.length()-6) == '-'))      		    
      {
        try
        {
          SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm");
          dateFormat.setLenient(false);
          Date d = dateFormat.parse(datetime.substring(datetime.length() -5));
          return datetime.length()-6;
        }
        catch (ParseException pe)
        {
          System.out.println("ParseException " + pe.getErrorOffset());
          return -2; // Invalid.
        }

      }
        return -1; // No zone information.
    }
    
    /**
     * Attempt to parse an input string with the allowed formats, returning
     * null if none of the formats work.
     */
    private static Date testFormats (String in, String[] formats)
      throws ParseException
    {
      for (int i = 0; i <formats.length; i++)
      {
        try
        {
          SimpleDateFormat dateFormat = new SimpleDateFormat(formats[i]);
          dateFormat.setLenient(false);          
          return dateFormat.parse(in);
        }
        catch (ParseException pe)
        {
        }
      }
      return null;
    }
    
    
    /**
     * Parse the input string and return the corresponding calendar field
     * number.
     */
    private static double getNumber(String in, String[] formats, int calField)
      throws ParseException
    {
      Calendar cal = Calendar.getInstance();
      cal.setLenient(false);
      // Try the allowed formats, from longest to shortest.
      Date date = testFormats(in, formats);
      if (date == null) return Double.NaN;
      cal.setTime(date);
      return cal.get(calField);
    }    
     
    /**
     *  Get the full name or abbreviation of the month or day.
     */
    private static String getNameOrAbbrev(String in, 
                                         String[] formatsIn,
                                         String formatOut)
      throws ParseException
    {
      for (int i = 0; i <formatsIn.length; i++) // from longest to shortest.
      {
        try
        {
          SimpleDateFormat dateFormat = new SimpleDateFormat(formatsIn[i]);
          dateFormat.setLenient(false);
          Date dt = dateFormat.parse(in);          
          dateFormat.applyPattern(formatOut);
          return dateFormat.format(dt);
        }
        catch (ParseException pe)
        {
        }
      }
      return "";
    }
    /**
     * Get the full name or abbreviation for the current month or day 
     * (no input string).
     */
    private static String getNameOrAbbrev(String format)
    {
      Calendar cal = Calendar.getInstance();
      SimpleDateFormat dateFormat = new SimpleDateFormat(format);
      return dateFormat.format(cal.getTime());
    }

}