/* DateFormat.java -- Class for formatting/parsing date/times
   Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005
   Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package java.text;

import gnu.java.locale.LocaleHelper;

import java.text.spi.DateFormatProvider;

import java.io.InvalidObjectException;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.ServiceLoader;
import java.util.TimeZone;

/**
 * @author Per Bothner (bothner@cygnus.com)
 * @date October 25, 1998.
 */
/* Written using "Java Class Libraries", 2nd edition, plus online
 * API docs for JDK 1.2 beta from http://www.javasoft.com.
 * Status:  Mostly complete; search for FIXME to see omissions.
 */

public abstract class DateFormat extends Format implements Cloneable
{
  private static final long serialVersionUID = 7218322306649953788L;

  // Names fixed by serialization spec.
  protected Calendar calendar;
  protected NumberFormat numberFormat;

  // (Values determined using a test program.)
  public static final int FULL = 0;
  public static final int LONG = 1;
  public static final int MEDIUM = 2;
  public static final int SHORT = 3;
  public static final int DEFAULT = MEDIUM;

  /* These constants need to have these exact values.  They
   * correspond to index positions within the localPatternChars
   * string for a given locale.  Each locale may specify its
   * own character for a particular field, but the position
   * of these characters must correspond to an appropriate field
   * number (as listed below), in order for their meaning to
   * be determined.  For example, the US locale uses
   * the string "GyMdkHmsSEDFwWahKzYeugAZ", where 'G' is the character
   * for era, 'y' for year, and so on down to 'Z' for time zone.
   */
  /**
   * Represents the position of the era
   * pattern character in the array of
   * localized pattern characters.
   * For example, 'AD' is an era used
   * in the Gregorian calendar system.
   * In the U.S. locale, this is 'G'.
   */
  public static final int ERA_FIELD = 0;
  /**
   * Represents the position of the year
   * pattern character in the array of
   * localized pattern characters.
   * In the U.S. locale, this is 'y'.
   */
  public static final int YEAR_FIELD = 1;
  /**
   * Represents the position of the month
   * pattern character in the array of
   * localized pattern characters.
   * In the U.S. locale, this is 'M'.
   */
  public static final int MONTH_FIELD = 2;
  /**
   * Represents the position of the date
   * or day of the month pattern character
   * in the array of localized pattern
   * characters.  In the U.S. locale,
   * this is 'd'.
   */
  public static final int DATE_FIELD = 3;
  /**
   * Represents the position of the 24
   * hour pattern character in the array of
   * localized pattern characters.
   * In the U.S. locale, this is 'k'.
   * This field numbers hours from 1 to 24.
   */
  public static final int HOUR_OF_DAY1_FIELD = 4;
  /**
   * Represents the position of the 24
   * hour pattern character in the array of
   * localized pattern characters.
   * In the U.S. locale, this is 'H'.
   * This field numbers hours from 0 to 23.
   */
  public static final int HOUR_OF_DAY0_FIELD = 5;
  /**
   * Represents the position of the minute
   * pattern character in the array of
   * localized pattern characters.
   * In the U.S. locale, this is 'm'.
   */
  public static final int MINUTE_FIELD = 6;
  /**
   * Represents the position of the second
   * pattern character in the array of
   * localized pattern characters.
   * In the U.S. locale, this is 's'.
   */
  public static final int SECOND_FIELD = 7;
  /**
   * Represents the position of the millisecond
   * pattern character in the array of
   * localized pattern characters.
   * In the U.S. locale, this is 'S'.
   */
  public static final int MILLISECOND_FIELD = 8;
  /**
   * Represents the position of the day of the
   * week pattern character in the array of
   * localized pattern characters.
   * In the U.S. locale, this is 'E'.
   */
  public static final int DAY_OF_WEEK_FIELD = 9;
  /**
   * Represents the position of the day of the
   * year pattern character in the array of
   * localized pattern characters.
   * In the U.S. locale, this is 'D'.
   */
  public static final int DAY_OF_YEAR_FIELD = 10;
  /**
   * Represents the position of the day of the
   * week in the month pattern character in the
   * array of localized pattern characters.
   * In the U.S. locale, this is 'F'.
   */
  public static final int DAY_OF_WEEK_IN_MONTH_FIELD = 11;
  /**
   * Represents the position of the week of the
   * year pattern character in the array of
   * localized pattern characters.
   * In the U.S. locale, this is 'w'.
   */
  public static final int WEEK_OF_YEAR_FIELD = 12;
  /**
   * Represents the position of the week of the
   * month pattern character in the array of
   * localized pattern characters.
   * In the U.S. locale, this is 'W'.
   */
  public static final int WEEK_OF_MONTH_FIELD = 13;
  /**
   * Represents the position of the am/pm
   * pattern character in the array of
   * localized pattern characters.
   * In the U.S. locale, this is 'a'.
   */
  public static final int AM_PM_FIELD = 14;
  /**
   * Represents the position of the 12
   * hour pattern character in the array of
   * localized pattern characters.
   * In the U.S. locale, this is 'h'.
   * This field numbers hours from 1 to 12.
   */
  public static final int HOUR1_FIELD = 15;
  /**
   * Represents the position of the 12
   * hour pattern character in the array of
   * localized pattern characters.
   * In the U.S. locale, this is 'K'.
   * This field numbers hours from 0 to 11.
   */
  public static final int HOUR0_FIELD = 16;
  /**
   * Represents the position of the generic
   * timezone pattern character in the array of
   * localized pattern characters.
   * In the U.S. locale, this is 'z'.
   */
  public static final int TIMEZONE_FIELD = 17;

  public static class Field extends Format.Field
  {
    static final long serialVersionUID = 7441350119349544720L;

    private int calendarField;

    public static final DateFormat.Field ERA
        = new Field("era", Calendar.ERA);
    public static final DateFormat.Field YEAR
        = new Field("year", Calendar.YEAR);
    public static final DateFormat.Field MONTH
        = new Field("month", Calendar.MONTH);
    public static final DateFormat.Field DAY_OF_MONTH
        = new Field("day of month", Calendar.DAY_OF_MONTH);
    public static final DateFormat.Field HOUR_OF_DAY1
        = new Field("hour of day 1", Calendar.HOUR_OF_DAY);
    public static final DateFormat.Field HOUR_OF_DAY0
        = new Field("hour of day 0", Calendar.HOUR_OF_DAY);
    public static final DateFormat.Field MINUTE
        = new Field("minute", Calendar.MINUTE);
    public static final DateFormat.Field SECOND
        = new Field("second", Calendar.SECOND);
    public static final DateFormat.Field MILLISECOND
        = new Field("millisecond", Calendar.MILLISECOND);
    public static final DateFormat.Field DAY_OF_WEEK
        = new Field("day of week", Calendar.DAY_OF_WEEK);
    public static final DateFormat.Field DAY_OF_YEAR
        = new Field("day of year", Calendar.DAY_OF_YEAR);
    public static final DateFormat.Field DAY_OF_WEEK_IN_MONTH
        = new Field("day of week in month", Calendar.DAY_OF_WEEK_IN_MONTH);
    public static final DateFormat.Field WEEK_OF_YEAR
        = new Field("week of year", Calendar.WEEK_OF_YEAR);
    public static final DateFormat.Field WEEK_OF_MONTH
        = new Field("week of month", Calendar.WEEK_OF_MONTH);
    public static final DateFormat.Field AM_PM
        = new Field("am/pm", Calendar.AM_PM);
    public static final DateFormat.Field HOUR1
        = new Field("hour1", Calendar.HOUR);
    public static final DateFormat.Field HOUR0
        = new Field("hour0", Calendar.HOUR);
    public static final DateFormat.Field TIME_ZONE
        = new Field("timezone", Calendar.ZONE_OFFSET);

    static final DateFormat.Field[] allFields =
    {
      ERA, YEAR, MONTH, DAY_OF_MONTH, HOUR_OF_DAY1,
      HOUR_OF_DAY0, MINUTE, SECOND, MILLISECOND,
      DAY_OF_WEEK, DAY_OF_YEAR, DAY_OF_WEEK_IN_MONTH,
      WEEK_OF_YEAR, WEEK_OF_MONTH, AM_PM, HOUR1, HOUR0,
      TIME_ZONE
    };

    // For deserialization
    private Field()
    {
      super("");
    }

    protected Field(String name, int calendarField)
    {
      super(name);
      this.calendarField = calendarField;
    }

    public int getCalendarField()
    {
      return calendarField;
    }

    public static Field ofCalendarField(int calendarField)
    {
      if (calendarField >= allFields.length || calendarField < 0)
        throw new IllegalArgumentException("no such calendar field ("
                                           + calendarField + ")");

      return allFields[calendarField];
    }

    protected Object readResolve() throws InvalidObjectException
    {
      String s = getName();

      for (int i=0;i<allFields.length;i++)
        if (s.equals(allFields[i].getName()))
          return allFields[i];

      throw new InvalidObjectException("no such DateFormat field called " + s);
    }
  }

  /**
   * This method initializes a new instance of <code>DateFormat</code>.
   */
  protected DateFormat ()
  {
  }

  /**
   * This method tests this object for equality against the specified object.
   * The two objects will be considered equal if an only if the specified
   * object:
   * <P>
   * <ul>
   * <li>Is not <code>null</code>.</li>
   * <li>Is an instance of <code>DateFormat</code>.</li>
   * <li>Has equal numberFormat field as this object.</li>
   * <li>Has equal (Calendar) TimeZone rules as this object.</li>
   * <li>Has equal (Calendar) isLenient results.</li>
   * <li>Has equal Calendar first day of week and minimal days in week
   * values.</li>
   * </ul>
   * Note that not all properties of the Calendar are relevant for a
   * DateFormat. For formatting only the fact whether or not the
   * TimeZone has the same rules and whether the calendar is lenient
   * and has the same week rules is compared for this implementation
   * of equals. Other properties of the Calendar (such as the time)
   * are not taken into account.
   *
   * @param obj The object to test for equality against.
   *
   * @return <code>true</code> if the specified object is equal to this object,
   * <code>false</code> otherwise.
   */
  public boolean equals (Object obj)
  {
    if (!(obj instanceof DateFormat))
      return false;

    DateFormat d = (DateFormat) obj;
    TimeZone tz = getTimeZone();
    TimeZone tzd = d.getTimeZone();
    if (tz.hasSameRules(tzd))
      if (isLenient() == d.isLenient())
        {
          Calendar c = getCalendar();
          Calendar cd = d.getCalendar();
          if ((c == null && cd == null)
              ||
              (c.getFirstDayOfWeek() == cd.getFirstDayOfWeek()
               &&
               c.getMinimalDaysInFirstWeek()
               == cd.getMinimalDaysInFirstWeek()))
            return ((numberFormat == null && d.numberFormat == null)
                    || numberFormat.equals(d.numberFormat));
        }

    return false;
  }

  /**
   * This method returns a copy of this object.
   *
   * @return A copy of this object.
   */
  public Object clone ()
  {
    // We know the superclass just call's Object's generic cloner.
    return super.clone ();
  }

  /**
   * This method formats the specified <code>Object</code> into a date string
   * and appends it to the specified <code>StringBuffer</code>.
   * The specified object must be an instance of <code>Number</code> or
   * <code>Date</code> or an <code>IllegalArgumentException</code> will be
   * thrown.
   *
   * @param obj The <code>Object</code> to format.
   * @param buf The <code>StringBuffer</code> to append the resultant
   * <code>String</code> to.
   * @param pos Is updated to the start and end index of the
   * specified field.
   *
   * @return The <code>StringBuffer</code> supplied on input, with the
   * formatted date/time appended.
   */
  public final StringBuffer format (Object obj,
                                    StringBuffer buf, FieldPosition pos)
  {
    if (obj instanceof Number)
      obj = new Date(((Number) obj).longValue());
    else if (! (obj instanceof Date))
      throw new IllegalArgumentException
        ("Cannot format given Object as a Date");

    return format ((Date) obj, buf, pos);
  }

  /**
    * Formats the date argument according to the pattern specified.
    *
    * @param date The formatted date.
    */
  public final String format (Date date)
  {
    StringBuffer sb = new StringBuffer ();
    format (date, sb, new FieldPosition (MONTH_FIELD));
    return sb.toString();
  }

  /**
   * This method formats a <code>Date</code> into a string and appends it
   * to the specified <code>StringBuffer</code>.
   *
   * @param date The <code>Date</code> value to format.
   * @param buf The <code>StringBuffer</code> to append the resultant
   * <code>String</code> to.
   * @param pos Is updated to the start and end index of the
   * specified field.
   *
   * @return The <code>StringBuffer</code> supplied on input, with the
   * formatted date/time appended.
   */
  public abstract StringBuffer format (Date date,
                                       StringBuffer buf, FieldPosition pos);

  /**
   * This method returns a list of available locales supported by this
   * class.
   */
  public static Locale[] getAvailableLocales()
  {
    return Locale.getAvailableLocales();
  }

  /**
    * This method returns the <code>Calendar</code> object being used by
    * this object to parse/format datetimes.
    *
    * @return The <code>Calendar</code> being used by this object.
    *
    * @see java.util.Calendar
    */
  public Calendar getCalendar ()
  {
    return calendar;
  }

  private static DateFormat computeInstance (int style, Locale loc,
                                             boolean use_date, boolean use_time)
  {
    return computeInstance (style, style, loc, use_date, use_time);
  }

  private static DateFormat computeInstance (int dateStyle, int timeStyle,
                                             Locale loc, boolean use_date,
                                             boolean use_time)
    throws MissingResourceException
  {
    if (loc.equals(Locale.ROOT))
      return computeDefault(dateStyle,timeStyle,use_date,use_time);

    ResourceBundle res =
      ResourceBundle.getBundle("gnu.java.locale.LocaleInformation",
                               loc, ClassLoader.getSystemClassLoader());

    String pattern = null;
    if (use_date)
      {
        String name, def;
        switch (dateStyle)
          {
          case FULL:
            name = "fullDateFormat";
            def = "EEEE MMMM d, yyyy G";
            break;
          case LONG:
            name = "longDateFormat";
            def = "MMMM d, yyyy";
            break;
          case MEDIUM:
            name = "mediumDateFormat";
            def = "d-MMM-yy";
            break;
          case SHORT:
            name = "shortDateFormat";
            def = "M/d/yy";
            break;
          default:
            throw new IllegalArgumentException ();
          }
        try
          {
            pattern = res == null ? def : res.getString(name);
          }
        catch (MissingResourceException x)
          {
            pattern = def;
          }
      }

    if (use_time)
      {
        if (pattern == null)
          pattern = "";
        else
          pattern += " ";

        String name, def;
        switch (timeStyle)
          {
          case FULL:
            name = "fullTimeFormat";
            def = "h:mm:ss;S 'o''clock' a z";
            break;
          case LONG:
            name = "longTimeFormat";
            def = "h:mm:ss a z";
            break;
          case MEDIUM:
            name = "mediumTimeFormat";
            def = "h:mm:ss a";
            break;
          case SHORT:
            name = "shortTimeFormat";
            def = "h:mm a";
            break;
          default:
            throw new IllegalArgumentException ();
          }

        String s;
        try
          {
            s = res == null ? def : res.getString(name);
          }
        catch (MissingResourceException x)
          {
            s = def;
          }
        pattern += s;
      }

    return new SimpleDateFormat (pattern, loc);
  }

  private static DateFormat computeDefault (int dateStyle, int timeStyle,
                                            boolean use_date, boolean use_time)
  {
    String pattern = null;
    if (use_date)
      {
        switch (dateStyle)
          {
          case FULL:
            pattern = "EEEE MMMM d, yyyy G";
            break;
          case LONG:
            pattern = "MMMM d, yyyy";
            break;
          case MEDIUM:
            pattern = "d-MMM-yy";
            break;
          case SHORT:
            pattern = "M/d/yy";
          default:
            throw new IllegalArgumentException ();
          }
      }

    if (use_time)
      {
        if (pattern == null)
          pattern = "";
        else
          pattern += " ";

        switch (timeStyle)
          {
          case FULL:
            pattern += "h:mm:ss;S 'o''clock' a z";
            break;
          case LONG:
            pattern += "h:mm:ss a z";
            break;
          case MEDIUM:
            pattern += "h:mm:ss a";
            break;
          case SHORT:
            pattern += "h:mm a";
            break;
          default:
            throw new IllegalArgumentException ();
          }
      }

    return new SimpleDateFormat (pattern, Locale.ROOT);
  }

 /**
   * This method returns an instance of <code>DateFormat</code> that will
   * format using the default formatting style for dates.
   *
   * @return A new <code>DateFormat</code> instance.
   */
  public static final DateFormat getDateInstance ()
  {
    return getDateInstance (DEFAULT, Locale.getDefault());
  }

  /**
   * This method returns an instance of <code>DateFormat</code> that will
   * format using the specified formatting style for dates.
   *
   * @param style The type of formatting to perform.
   *
   * @return A new <code>DateFormat</code> instance.
   */
  public static final DateFormat getDateInstance (int style)
  {
    return getDateInstance (style, Locale.getDefault());
  }

  /**
   * This method returns an instance of <code>DateFormat</code> that will
   * format using the specified formatting style for dates.  The specified
   * localed will be used in place of the default.
   *
   * @param style The type of formatting to perform.
   * @param loc The desired locale.
   *
   * @return A new <code>DateFormat</code> instance.
   */
  public static final DateFormat getDateInstance (int style, Locale loc)
  {
    try
      {
        return computeInstance (style, loc, true, false);
      }
    catch (MissingResourceException e)
      {
        for (DateFormatProvider p :
               ServiceLoader.load(DateFormatProvider.class))
          {
            for (Locale l : p.getAvailableLocales())
              {
                if (l.equals(loc))
                  {
                    DateFormat df = p.getDateInstance(style, loc);
                    if (df != null)
                      return df;
                    break;
                  }
              }
          }
        return getDateInstance(style,
                               LocaleHelper.getFallbackLocale(loc));
      }
  }

  /**
   * This method returns a new instance of <code>DateFormat</code> that
   * formats both dates and times using the <code>SHORT</code> style.
   *
   * @return A new <code>DateFormat</code>instance.
   */
  public static final DateFormat getDateTimeInstance ()
  {
    return getDateTimeInstance (DEFAULT, DEFAULT, Locale.getDefault());
  }

  /**
   * This method returns a new instance of <code>DateFormat</code> that
   * formats both dates and times using the <code>DEFAULT</code> style.
   *
   * @return A new <code>DateFormat</code>instance.
   */
  public static final DateFormat getDateTimeInstance (int dateStyle,
                                                      int timeStyle)
  {
    return getDateTimeInstance (dateStyle, timeStyle, Locale.getDefault());
  }

  /**
   * This method returns a new instance of <code>DateFormat</code> that
   * formats both dates and times using the specified styles.
   *
   * @param dateStyle The desired style for date formatting.
   * @param timeStyle The desired style for time formatting
   *
   * @return A new <code>DateFormat</code>instance.
   */
  public static final DateFormat getDateTimeInstance (int dateStyle,
                                                      int timeStyle,
                                                      Locale loc)
  {
    try
      {
        return computeInstance (dateStyle, timeStyle, loc, true, true);
      }
    catch (MissingResourceException e)
      {
        for (DateFormatProvider p :
               ServiceLoader.load(DateFormatProvider.class))
          {
            for (Locale l : p.getAvailableLocales())
              {
                if (l.equals(loc))
                  {
                    DateFormat df = p.getDateTimeInstance(dateStyle,
                                                          timeStyle, loc);
                    if (df != null)
                      return df;
                    break;
                  }
              }
          }
        return getDateTimeInstance(dateStyle, timeStyle,
                                   LocaleHelper.getFallbackLocale(loc));
      }
  }

  /**
   * This method returns a new instance of <code>DateFormat</code> that
   * formats both dates and times using the <code>SHORT</code> style.
   *
   * @return A new <code>DateFormat</code>instance.
   */
  public static final DateFormat getInstance ()
  {
    // JCL book says SHORT.
    return getDateTimeInstance (SHORT, SHORT, Locale.getDefault());
  }

  /**
   * This method returns the <code>NumberFormat</code> object being used
   * by this object to parse/format time values.
   *
   * @return The <code>NumberFormat</code> in use by this object.
   */
  public NumberFormat getNumberFormat ()
  {
    return numberFormat;
  }

 /**
   * This method returns an instance of <code>DateFormat</code> that will
   * format using the default formatting style for times.
   *
   * @return A new <code>DateFormat</code> instance.
   */
  public static final DateFormat getTimeInstance ()
  {
    return getTimeInstance (DEFAULT, Locale.getDefault());
  }

  /**
   * This method returns an instance of <code>DateFormat</code> that will
   * format using the specified formatting style for times.
   *
   * @param style The type of formatting to perform.
   *
   * @return A new <code>DateFormat</code> instance.
   */
  public static final DateFormat getTimeInstance (int style)
  {
    return getTimeInstance (style, Locale.getDefault());
  }

  /**
   * This method returns an instance of <code>DateFormat</code> that will
   * format using the specified formatting style for times.  The specified
   * localed will be used in place of the default.
   *
   * @param style The type of formatting to perform.
   * @param loc The desired locale.
   *
   * @return A new <code>DateFormat</code> instance.
   */
  public static final DateFormat getTimeInstance (int style, Locale loc)
  {
    try
      {
        return computeInstance (style, loc, false, true);
      }
    catch (MissingResourceException e)
      {
        for (DateFormatProvider p :
               ServiceLoader.load(DateFormatProvider.class))
          {
            for (Locale l : p.getAvailableLocales())
              {
                if (l.equals(loc))
                  {
                    DateFormat df = p.getTimeInstance(style, loc);
                    if (df != null)
                      return df;
                    break;
                  }
              }
          }
        return getTimeInstance(style,
                               LocaleHelper.getFallbackLocale(loc));
      }
  }

  /**
   * This method returns the <code>TimeZone</code> object being used by
   * this instance.
   *
   * @return The time zone in use.
   */
  public TimeZone getTimeZone ()
  {
    return calendar.getTimeZone();
  }

  /**
   * This method returns a hash value for this object.
   *
   * @return A hash value for this object.
   */
  public int hashCode ()
  {
    if (numberFormat != null)
      return numberFormat.hashCode();
    else
      return 0;
  }

  /**
   * This method indicates whether or not the parsing of date and time
   * values should be done in a lenient value.
   *
   * @return <code>true</code> if date/time parsing is lenient,
   * <code>false</code> otherwise.
   */
  public boolean isLenient ()
  {
    return calendar.isLenient();
  }

  /**
   * This method parses the specified date/time string.
   *
   * @param source The string to parse.
   * @return The resultant date.
   *
   * @exception ParseException If the specified string cannot be parsed.
   */
  public Date parse (String source) throws ParseException
  {
    ParsePosition pos = new ParsePosition(0);
    Date result = parse (source, pos);
    if (result == null)
      {
        int index = pos.getErrorIndex();
        if (index < 0)
          index = pos.getIndex();
        throw new ParseException("invalid Date syntax in \""
                                 + source + '\"', index);
      }
    return result;
  }

  /**
   * This method parses the specified <code>String</code> into a
   * <code>Date</code>.  The <code>pos</code> argument contains the
   * starting parse position on method entry and the ending parse
   * position on method exit.
   *
   * @param source The string to parse.
   * @param pos The starting parse position in entry, the ending parse
   * position on exit.
   *
   * @return The parsed date, or <code>null</code> if the string cannot
   * be parsed.
   */
  public abstract Date parse (String source, ParsePosition pos);

  /**
   * This method is identical to <code>parse(String, ParsePosition)</code>,
   * but returns its result as an <code>Object</code> instead of a
   * <code>Date</code>.
   *
   * @param source The string to parse.
   * @param pos The starting parse position in entry, the ending parse
   * position on exit.
   *
   * @return The parsed date, or <code>null</code> if the string cannot
   * be parsed.
   */
  public Object parseObject (String source, ParsePosition pos)
  {
    return parse(source, pos);
  }

  /**
   * This method specified the <code>Calendar</code> that should be used
   * by this object to parse/format datetimes.
   *
   * @param calendar The new <code>Calendar</code> for this object.
   *
   * @see java.util.Calendar
   */
  public void setCalendar (Calendar calendar)
  {
    this.calendar = calendar;
  }

  /**
   * This method specifies whether or not this object should be lenient in
   * the syntax it accepts while parsing date/time values.
   *
   * @param lenient <code>true</code> if parsing should be lenient,
   * <code>false</code> otherwise.
   */
  public void setLenient (boolean lenient)
  {
    calendar.setLenient(lenient);
  }

  /**
   * This method specifies the <code>NumberFormat</code> object that should
   * be used by this object to parse/format times.
   *
   * @param numberFormat The <code>NumberFormat</code> in use by this object.
   */
  public void setNumberFormat (NumberFormat numberFormat)
  {
    this.numberFormat = numberFormat;
  }

  /**
   * This method sets the time zone that should be used by this object.
   *
   * @param timeZone The new time zone.
   */
  public void setTimeZone (TimeZone timeZone)
  {
    calendar.setTimeZone(timeZone);
  }
}
