OSDN Git Service

Imported Classpath 0.18.
[pf3gnuchains/gcc-fork.git] / libjava / classpath / java / text / DateFormat.java
1 /* DateFormat.java -- Class for formatting/parsing date/times
2    Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005
3    Free Software Foundation, Inc.
4
5 This file is part of GNU Classpath.
6
7 GNU Classpath is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11  
12 GNU Classpath is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU Classpath; see the file COPYING.  If not, write to the
19 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301 USA.
21
22 Linking this library statically or dynamically with other modules is
23 making a combined work based on this library.  Thus, the terms and
24 conditions of the GNU General Public License cover the whole
25 combination.
26
27 As a special exception, the copyright holders of this library give you
28 permission to link this library with independent modules to produce an
29 executable, regardless of the license terms of these independent
30 modules, and to copy and distribute the resulting executable under
31 terms of your choice, provided that you also meet, for each linked
32 independent module, the terms and conditions of the license of that
33 module.  An independent module is a module which is not derived from
34 or based on this library.  If you modify this library, you may extend
35 this exception to your version of the library, but you are not
36 obligated to do so.  If you do not wish to do so, delete this
37 exception statement from your version. */
38
39
40 package java.text;
41
42 import java.io.InvalidObjectException;
43 import java.util.Calendar;
44 import java.util.Date;
45 import java.util.Locale;
46 import java.util.MissingResourceException;
47 import java.util.ResourceBundle;
48 import java.util.TimeZone;
49
50 /**
51  * @author Per Bothner (bothner@cygnus.com)
52  * @date October 25, 1998.
53  */
54 /* Written using "Java Class Libraries", 2nd edition, plus online
55  * API docs for JDK 1.2 beta from http://www.javasoft.com.
56  * Status:  Mostly complete; search for FIXME to see omissions.
57  */
58
59 public abstract class DateFormat extends Format implements Cloneable
60 {
61   protected Calendar calendar;
62   protected NumberFormat numberFormat;
63
64   // (Values determined using a test program.)
65   public static final int FULL = 0;
66   public static final int LONG = 1;
67   public static final int MEDIUM = 2;
68   public static final int SHORT = 3;
69   public static final int DEFAULT = MEDIUM;
70
71   /* These constants need to have these exact values.  They
72    * correspond to index positions within the localPatternChars
73    * string for a given locale.  Each locale may specify its
74    * own character for a particular field, but the position
75    * of these characters must correspond to an appropriate field
76    * number (as listed below), in order for their meaning to
77    * be determined.  For example, the US locale uses
78    * the string "GyMdkHmsSEDFwWahKzYeugAZ", where 'G' is the character
79    * for era, 'y' for year, and so on down to 'Z' for time zone.
80    */
81   /**
82    * Represents the position of the era
83    * pattern character in the array of
84    * localized pattern characters. 
85    * For example, 'AD' is an era used
86    * in the Gregorian calendar system.
87    * In the U.S. locale, this is 'G'.
88    */  
89   public static final int ERA_FIELD = 0;
90   /**
91    * Represents the position of the year
92    * pattern character in the array of
93    * localized pattern characters.
94    * In the U.S. locale, this is 'y'.
95    */
96   public static final int YEAR_FIELD = 1;
97   /**
98    * Represents the position of the month
99    * pattern character in the array of
100    * localized pattern characters.
101    * In the U.S. locale, this is 'M'.
102    */
103   public static final int MONTH_FIELD = 2;
104   /**
105    * Represents the position of the date
106    * or day of the month pattern character
107    * in the array of localized pattern
108    * characters.  In the U.S. locale,
109    * this is 'd'.
110    */
111   public static final int DATE_FIELD = 3;
112   /**
113    * Represents the position of the 24
114    * hour pattern character in the array of
115    * localized pattern characters.
116    * In the U.S. locale, this is 'k'.
117    * This field numbers hours from 1 to 24.
118    */
119   public static final int HOUR_OF_DAY1_FIELD = 4;
120   /**
121    * Represents the position of the 24
122    * hour pattern character in the array of
123    * localized pattern characters.
124    * In the U.S. locale, this is 'H'.
125    * This field numbers hours from 0 to 23.
126    */
127   public static final int HOUR_OF_DAY0_FIELD = 5;
128   /**
129    * Represents the position of the minute
130    * pattern character in the array of
131    * localized pattern characters.
132    * In the U.S. locale, this is 'm'.
133    */
134   public static final int MINUTE_FIELD = 6;
135   /**
136    * Represents the position of the second
137    * pattern character in the array of
138    * localized pattern characters.
139    * In the U.S. locale, this is 's'.
140    */
141   public static final int SECOND_FIELD = 7;
142   /**
143    * Represents the position of the millisecond
144    * pattern character in the array of
145    * localized pattern characters.
146    * In the U.S. locale, this is 'S'.
147    */
148   public static final int MILLISECOND_FIELD = 8;
149   /**
150    * Represents the position of the day of the
151    * week pattern character in the array of
152    * localized pattern characters.
153    * In the U.S. locale, this is 'E'.
154    */
155   public static final int DAY_OF_WEEK_FIELD = 9;
156   /**
157    * Represents the position of the day of the
158    * year pattern character in the array of
159    * localized pattern characters.
160    * In the U.S. locale, this is 'D'.
161    */
162   public static final int DAY_OF_YEAR_FIELD = 10;
163   /**
164    * Represents the position of the day of the
165    * week in the month pattern character in the
166    * array of localized pattern characters.
167    * In the U.S. locale, this is 'F'.
168    */
169   public static final int DAY_OF_WEEK_IN_MONTH_FIELD = 11;
170   /**
171    * Represents the position of the week of the
172    * year pattern character in the array of
173    * localized pattern characters.
174    * In the U.S. locale, this is 'w'.
175    */
176   public static final int WEEK_OF_YEAR_FIELD = 12;
177   /**
178    * Represents the position of the week of the
179    * month pattern character in the array of
180    * localized pattern characters.
181    * In the U.S. locale, this is 'W'.
182    */
183   public static final int WEEK_OF_MONTH_FIELD = 13;
184   /**
185    * Represents the position of the am/pm
186    * pattern character in the array of
187    * localized pattern characters.
188    * In the U.S. locale, this is 'a'.
189    */
190   public static final int AM_PM_FIELD = 14;
191   /**
192    * Represents the position of the 12 
193    * hour pattern character in the array of
194    * localized pattern characters.
195    * In the U.S. locale, this is 'h'.
196    * This field numbers hours from 1 to 12.
197    */
198   public static final int HOUR1_FIELD = 15;
199   /**
200    * Represents the position of the 12 
201    * hour pattern character in the array of
202    * localized pattern characters.
203    * In the U.S. locale, this is 'K'.
204    * This field numbers hours from 0 to 11.
205    */
206   public static final int HOUR0_FIELD = 16;
207   /**
208    * Represents the position of the generic
209    * timezone pattern character in the array of
210    * localized pattern characters.
211    * In the U.S. locale, this is 'z'.
212    */
213   public static final int TIMEZONE_FIELD = 17;
214   /**
215    * Represents the position of the ISO year
216    * pattern character in the array of
217    * localized pattern characters.
218    * In the U.S. locale, this is 'Y'.
219    * This is a GNU extension in accordance with
220    * the CLDR data used.  This value may
221    * differ from the normal year value.
222    */
223   public static final int ISO_YEAR_FIELD = 18;
224   /**
225    * Represents the position of the localized
226    * day of the week pattern character in the
227    * array of localized pattern characters.
228    * In the U.S. locale, this is 'e'.
229    * This is a GNU extension in accordance with
230    * the CLDR data used.  This value only
231    * differs from the day of the week with
232    * numeric formatting, in which case the
233    * locale's first day of the week is used.
234    */
235   public static final int LOCALIZED_DAY_OF_WEEK_FIELD = 19;
236   /**
237    * Represents the position of the extended year
238    * pattern character in the array of
239    * localized pattern characters.
240    * In the U.S. locale, this is 'u'.
241    * This is a GNU extension in accordance with
242    * the CLDR data used.  This value modifies
243    * the year value, so as to incorporate the era.
244    * For example, in the Gregorian calendar system,
245    * the extended year is negative instead of being
246    * marked as BC.
247    */
248   public static final int EXTENDED_YEAR_FIELD = 20;
249   /**
250    * Represents the position of the modified Julian
251    * day pattern character in the array of
252    * localized pattern characters.
253    * In the U.S. locale, this is 'g'.
254    * This is a GNU extension in accordance with
255    * the CLDR data used.  This value differs
256    * from the standard Julian day in that days
257    * are marked from midnight onwards rather than
258    * noon, and the local time zone affects the value.
259    * In simple terms, it can be thought of as all
260    * the date fields represented as a single number.
261    */
262   public static final int MODIFIED_JULIAN_DAY_FIELD = 21;
263   /**
264    * Represents the position of the millisecond
265    * in the day pattern character in the array of
266    * localized pattern characters.
267    * In the U.S. locale, this is 'A'.
268    * This is a GNU extension in accordance with
269    * the CLDR data used.  This value represents
270    * all the time fields (excluding the time zone)
271    * numerically, giving the number of milliseconds
272    * into the day (e.g. 10 in the morning would
273    * be 10 * 60 * 60 * 1000).  Any daylight savings
274    * offset also affects this value.
275    */
276   public static final int MILLISECOND_IN_DAY_FIELD = 22;
277   /**
278    * Represents the position of the RFC822
279    * timezone pattern character in the array of
280    * localized pattern characters.
281    * In the U.S. locale, this is 'Z'.
282    * This is a GNU extension in accordance with
283    * the CLDR data used.  The value is the offset
284    * of the current time from GMT e.g. -0500 would
285    * be five hours prior to GMT.
286    */
287   public static final int RFC822_TIMEZONE_FIELD = 23;
288
289   public static class Field extends Format.Field
290   {
291     static final long serialVersionUID = 7441350119349544720L;
292     
293     private int calendarField;
294
295     public static final DateFormat.Field ERA
296         = new Field("era", Calendar.ERA);
297     public static final DateFormat.Field YEAR
298         = new Field("year", Calendar.YEAR);
299     public static final DateFormat.Field MONTH
300         = new Field("month", Calendar.MONTH);
301     public static final DateFormat.Field DAY_OF_MONTH
302         = new Field("day of month", Calendar.DAY_OF_MONTH);
303     public static final DateFormat.Field HOUR_OF_DAY1
304         = new Field("hour of day 1", Calendar.HOUR_OF_DAY);
305     public static final DateFormat.Field HOUR_OF_DAY0
306         = new Field("hour of day 0", Calendar.HOUR_OF_DAY);
307     public static final DateFormat.Field MINUTE
308         = new Field("minute", Calendar.MINUTE);
309     public static final DateFormat.Field SECOND
310         = new Field("second", Calendar.SECOND);
311     public static final DateFormat.Field MILLISECOND
312         = new Field("millisecond", Calendar.MILLISECOND);
313     public static final DateFormat.Field DAY_OF_WEEK
314         = new Field("day of week", Calendar.DAY_OF_WEEK);
315     public static final DateFormat.Field DAY_OF_YEAR
316         = new Field("day of year", Calendar.DAY_OF_YEAR);
317     public static final DateFormat.Field DAY_OF_WEEK_IN_MONTH
318         = new Field("day of week in month", Calendar.DAY_OF_WEEK_IN_MONTH);
319     public static final DateFormat.Field WEEK_OF_YEAR
320         = new Field("week of year", Calendar.WEEK_OF_YEAR);
321     public static final DateFormat.Field WEEK_OF_MONTH
322         = new Field("week of month", Calendar.WEEK_OF_MONTH);
323     public static final DateFormat.Field AM_PM
324         = new Field("am/pm", Calendar.AM_PM);
325     public static final DateFormat.Field HOUR1
326         = new Field("hour1", Calendar.HOUR);
327     public static final DateFormat.Field HOUR0
328         = new Field("hour0", Calendar.HOUR);
329     public static final DateFormat.Field TIME_ZONE
330         = new Field("timezone", Calendar.ZONE_OFFSET);
331     public static final DateFormat.Field ISO_YEAR
332         = new Field("iso year", Calendar.YEAR);
333     public static final DateFormat.Field LOCALIZED_DAY_OF_WEEK
334         = new Field("localized day of week", Calendar.DAY_OF_WEEK);
335     public static final DateFormat.Field EXTENDED_YEAR
336       = new Field("extended year", Calendar.YEAR);
337     public static final DateFormat.Field MODIFIED_JULIAN_DAY
338         = new Field("julian day", -1);
339     public static final DateFormat.Field MILLISECOND_IN_DAY
340         = new Field("millisecond in day", -1);
341     public static final DateFormat.Field RFC822_TIME_ZONE
342         = new Field("rfc822 timezone", Calendar.ZONE_OFFSET);
343
344     static final DateFormat.Field[] allFields =
345     {
346       ERA, YEAR, MONTH, DAY_OF_MONTH, HOUR_OF_DAY1,
347       HOUR_OF_DAY0, MINUTE, SECOND, MILLISECOND,
348       DAY_OF_WEEK, DAY_OF_YEAR, DAY_OF_WEEK_IN_MONTH,
349       WEEK_OF_YEAR, WEEK_OF_MONTH, AM_PM, HOUR1, HOUR0,
350       TIME_ZONE, ISO_YEAR, LOCALIZED_DAY_OF_WEEK,
351       EXTENDED_YEAR, MODIFIED_JULIAN_DAY, MILLISECOND_IN_DAY,
352       RFC822_TIME_ZONE
353     };
354
355     // For deserialization
356     private Field()
357     {
358       super("");
359     }
360
361     protected Field(String name, int calendarField)
362     {
363       super(name);
364       this.calendarField = calendarField;
365     }
366     
367     public int getCalendarField()
368     {
369       return calendarField;
370     }
371
372     public static Field ofCalendarField(int calendarField)
373     {
374       if (calendarField >= allFields.length || calendarField < 0)
375         throw new IllegalArgumentException("no such calendar field ("
376                                            + calendarField + ")");
377       
378       return allFields[calendarField];
379     }
380     
381     protected Object readResolve() throws InvalidObjectException
382     {
383       String s = getName();
384
385       for (int i=0;i<allFields.length;i++)
386         if (s.equals(allFields[i].getName()))
387           return allFields[i];
388       
389       throw new InvalidObjectException("no such DateFormat field called " + s);
390     }
391   }
392
393   /**
394    * This method initializes a new instance of <code>DateFormat</code>.
395    */
396   protected DateFormat ()
397   {
398   }
399
400   /**
401    * This method tests this object for equality against the specified object.
402    * The two objects will be considered equal if an only if the specified
403    * object:
404    * <P>
405    * <ul>
406    * <li>Is not <code>null</code>.</li>
407    * <li>Is an instance of <code>DateFormat</code>.</li>
408    * <li>Has equal numberFormat field as this object.</li>
409    * <li>Has equal (Calendar) TimeZone rules as this object.</li>
410    * <li>Has equal (Calendar) isLenient results.</li> 
411    * <li>Has equal Calendar first day of week and minimal days in week
412    * values.</li>
413    * </ul>
414    * Note that not all properties of the Calendar are relevant for a
415    * DateFormat. For formatting only the fact whether or not the
416    * TimeZone has the same rules and whether the calendar is lenient
417    * and has the same week rules is compared for this implementation
418    * of equals. Other properties of the Calendar (such as the time)
419    * are not taken into account.
420    *
421    * @param obj The object to test for equality against.
422    * 
423    * @return <code>true</code> if the specified object is equal to this object,
424    * <code>false</code> otherwise.
425    */
426   public boolean equals (Object obj)
427   {
428     if (!(obj instanceof DateFormat))
429       return false;
430
431     DateFormat d = (DateFormat) obj;
432     TimeZone tz = getTimeZone();
433     TimeZone tzd = d.getTimeZone();
434     if (tz.hasSameRules(tzd))
435       if (isLenient() == d.isLenient())
436         {
437           Calendar c = getCalendar();
438           Calendar cd = d.getCalendar();
439           if ((c == null && cd == null)
440               ||
441               (c.getFirstDayOfWeek() == cd.getFirstDayOfWeek()
442                &&
443                c.getMinimalDaysInFirstWeek()
444                == cd.getMinimalDaysInFirstWeek()))
445             return ((numberFormat == null && d.numberFormat == null)
446                     || numberFormat.equals(d.numberFormat));
447         }
448
449     return false;
450   }
451
452   /**
453    * This method returns a copy of this object.
454    *
455    * @return A copy of this object.
456    */
457   public Object clone ()
458   {
459     // We know the superclass just call's Object's generic cloner.
460     return super.clone ();
461   }
462
463   /**
464    * This method formats the specified <code>Object</code> into a date string
465    * and appends it to the specified <code>StringBuffer</code>.
466    * The specified object must be an instance of <code>Number</code> or
467    * <code>Date</code> or an <code>IllegalArgumentException</code> will be
468    * thrown.
469    *
470    * @param obj The <code>Object</code> to format.
471    * @param buf The <code>StringBuffer</code> to append the resultant
472    * <code>String</code> to.
473    * @param pos Is updated to the start and end index of the
474    * specified field.
475    *
476    * @return The <code>StringBuffer</code> supplied on input, with the
477    * formatted date/time appended.
478    */
479   public final StringBuffer format (Object obj,
480                                     StringBuffer buf, FieldPosition pos)
481   {
482     if (obj instanceof Number)
483       obj = new Date(((Number) obj).longValue());
484     else if (! (obj instanceof Date))
485       throw new IllegalArgumentException
486         ("Cannot format given Object as a Date");
487
488     return format ((Date) obj, buf, pos);
489   }
490
491   /**  
492     * Formats the date argument according to the pattern specified. 
493     *
494     * @param date The formatted date.
495     */
496   public final String format (Date date)
497   {
498     StringBuffer sb = new StringBuffer ();
499     format (date, sb, new FieldPosition (MONTH_FIELD));
500     return sb.toString();
501   }
502
503   /**
504    * This method formats a <code>Date</code> into a string and appends it
505    * to the specified <code>StringBuffer</code>.
506    *
507    * @param date The <code>Date</code> value to format.
508    * @param buf The <code>StringBuffer</code> to append the resultant
509    * <code>String</code> to.
510    * @param pos Is updated to the start and end index of the
511    * specified field.
512    *
513    * @return The <code>StringBuffer</code> supplied on input, with the
514    * formatted date/time appended.
515    */
516   public abstract StringBuffer format (Date date,
517                                        StringBuffer buf, FieldPosition pos);
518
519   /**
520    * This method returns a list of available locales supported by this
521    * class.
522    */
523   public static Locale[] getAvailableLocales()
524   {
525     return Locale.getAvailableLocales();
526   }
527
528   /**
529     * This method returns the <code>Calendar</code> object being used by
530     * this object to parse/format datetimes.
531     *
532     * @return The <code>Calendar</code> being used by this object.
533     *
534     * @see java.util.Calendar
535     */
536   public Calendar getCalendar ()
537   {
538     return calendar;
539   }
540
541   private static DateFormat computeInstance (int style, Locale loc,
542                                              boolean use_date, boolean use_time)
543   {
544     return computeInstance (style, style, loc, use_date, use_time);
545   }
546
547   private static DateFormat computeInstance (int dateStyle, int timeStyle,
548                                              Locale loc, boolean use_date,
549                                              boolean use_time)
550   {
551     ResourceBundle res;
552     try
553       {
554         res = ResourceBundle.getBundle("gnu.java.locale.LocaleInformation",
555                                        loc, ClassLoader.getSystemClassLoader());
556       }
557     catch (MissingResourceException x)
558       {
559         res = null;
560       }
561
562     String pattern = null;
563     if (use_date)
564       {
565         String name, def;
566         switch (dateStyle)
567           {
568           case FULL:
569             name = "fullDateFormat";
570             def = "EEEE MMMM d, yyyy G";
571             break;
572           case LONG:
573             name = "longDateFormat";
574             def = "MMMM d, yyyy";
575             break;
576           case MEDIUM:
577             name = "mediumDateFormat";
578             def = "d-MMM-yy";
579             break;
580           case SHORT:
581             name = "shortDateFormat";
582             def = "M/d/yy";
583             break;
584           default:
585             throw new IllegalArgumentException ();
586           }
587         try
588           {
589             pattern = res == null ? def : res.getString(name);
590           }
591         catch (MissingResourceException x)
592           {
593             pattern = def;
594           }
595       }
596
597     if (use_time)
598       {
599         if (pattern == null)
600           pattern = "";
601         else
602           pattern += " ";
603
604         String name, def;
605         switch (timeStyle)
606           {
607           case FULL:
608             name = "fullTimeFormat";
609             def = "h:mm:ss;S 'o''clock' a z";
610             break;
611           case LONG:
612             name = "longTimeFormat";
613             def = "h:mm:ss a z";
614             break;
615           case MEDIUM:
616             name = "mediumTimeFormat";
617             def = "h:mm:ss a";
618             break;
619           case SHORT:
620             name = "shortTimeFormat";
621             def = "h:mm a";
622             break;
623           default:
624             throw new IllegalArgumentException ();
625           }
626
627         String s;
628         try
629           {
630             s = res == null ? def : res.getString(name);
631           }
632         catch (MissingResourceException x)
633           {
634             s = def;
635           }
636         pattern += s;
637       }
638
639     return new SimpleDateFormat (pattern, loc);
640   }
641
642  /**
643    * This method returns an instance of <code>DateFormat</code> that will
644    * format using the default formatting style for dates.
645    *
646    * @return A new <code>DateFormat</code> instance.
647    */
648   public static final DateFormat getDateInstance ()
649   {
650     return getDateInstance (DEFAULT, Locale.getDefault());
651   }
652
653   /**
654    * This method returns an instance of <code>DateFormat</code> that will
655    * format using the specified formatting style for dates.
656    *
657    * @param style The type of formatting to perform. 
658    * 
659    * @return A new <code>DateFormat</code> instance.
660    */
661   public static final DateFormat getDateInstance (int style)
662   {
663     return getDateInstance (style, Locale.getDefault());
664   }
665
666   /**
667    * This method returns an instance of <code>DateFormat</code> that will
668    * format using the specified formatting style for dates.  The specified
669    * localed will be used in place of the default.
670    *
671    * @param style The type of formatting to perform. 
672    * @param loc The desired locale.
673    * 
674    * @return A new <code>DateFormat</code> instance.
675    */
676   public static final DateFormat getDateInstance (int style, Locale loc)
677   {
678     return computeInstance (style, loc, true, false);
679   }
680
681   /**
682    * This method returns a new instance of <code>DateFormat</code> that
683    * formats both dates and times using the <code>SHORT</code> style.
684    *
685    * @return A new <code>DateFormat</code>instance.
686    */
687   public static final DateFormat getDateTimeInstance ()
688   {
689     return getDateTimeInstance (DEFAULT, DEFAULT, Locale.getDefault());
690   }
691
692   /**
693    * This method returns a new instance of <code>DateFormat</code> that
694    * formats both dates and times using the <code>DEFAULT</code> style.
695    *
696    * @return A new <code>DateFormat</code>instance.
697    */
698   public static final DateFormat getDateTimeInstance (int dateStyle, 
699                                                       int timeStyle)
700   {
701     return getDateTimeInstance (dateStyle, timeStyle, Locale.getDefault());
702   }
703
704   /**
705    * This method returns a new instance of <code>DateFormat</code> that
706    * formats both dates and times using the specified styles.
707    * 
708    * @param dateStyle The desired style for date formatting.
709    * @param timeStyle The desired style for time formatting
710    *
711    * @return A new <code>DateFormat</code>instance.
712    */
713   public static final DateFormat getDateTimeInstance (int dateStyle, 
714                                                       int timeStyle, 
715                                                       Locale loc)
716   {
717     return computeInstance (dateStyle, timeStyle, loc, true, true);
718   }
719
720   /**
721    * This method returns a new instance of <code>DateFormat</code> that
722    * formats both dates and times using the <code>SHORT</code> style.
723    *
724    * @return A new <code>DateFormat</code>instance.
725    */
726   public static final DateFormat getInstance ()
727   {
728     // JCL book says SHORT.
729     return getDateTimeInstance (SHORT, SHORT, Locale.getDefault());
730   }
731
732   /**
733    * This method returns the <code>NumberFormat</code> object being used
734    * by this object to parse/format time values.
735    *
736    * @return The <code>NumberFormat</code> in use by this object.
737    */
738   public NumberFormat getNumberFormat ()
739   {
740     return numberFormat;
741   }
742
743  /**
744    * This method returns an instance of <code>DateFormat</code> that will
745    * format using the default formatting style for times.
746    *
747    * @return A new <code>DateFormat</code> instance.
748    */
749   public static final DateFormat getTimeInstance ()
750   {
751     return getTimeInstance (DEFAULT, Locale.getDefault());
752   }
753
754   /**
755    * This method returns an instance of <code>DateFormat</code> that will
756    * format using the specified formatting style for times.
757    *
758    * @param style The type of formatting to perform. 
759    * 
760    * @return A new <code>DateFormat</code> instance.
761    */
762   public static final DateFormat getTimeInstance (int style)
763   {
764     return getTimeInstance (style, Locale.getDefault());
765   }
766
767   /**
768    * This method returns an instance of <code>DateFormat</code> that will
769    * format using the specified formatting style for times.  The specified
770    * localed will be used in place of the default.
771    *
772    * @param style The type of formatting to perform. 
773    * @param loc The desired locale.
774    * 
775    * @return A new <code>DateFormat</code> instance.
776    */
777   public static final DateFormat getTimeInstance (int style, Locale loc)
778   {
779     return computeInstance (style, loc, false, true);
780   }
781
782   /**
783    * This method returns the <code>TimeZone</code> object being used by
784    * this instance.
785    *
786    * @return The time zone in use.
787    */
788   public TimeZone getTimeZone ()
789   {
790     return calendar.getTimeZone();
791   }
792
793   /**
794    * This method returns a hash value for this object.
795    * 
796    * @return A hash value for this object.
797    */
798   public int hashCode ()
799   {
800     if (numberFormat != null)
801       return numberFormat.hashCode();
802     else
803       return 0;
804   }
805
806   /**
807    * This method indicates whether or not the parsing of date and time
808    * values should be done in a lenient value.
809    *
810    * @return <code>true</code> if date/time parsing is lenient,
811    * <code>false</code> otherwise.
812    */
813   public boolean isLenient ()
814   {
815     return calendar.isLenient();
816   }
817
818   /**
819    * This method parses the specified date/time string.
820    *
821    * @param source The string to parse.
822    * @return The resultant date.
823    *
824    * @exception ParseException If the specified string cannot be parsed.
825    */
826   public Date parse (String source) throws ParseException
827   {
828     ParsePosition pos = new ParsePosition(0);
829     Date result = parse (source, pos);
830     if (result == null)
831       {
832         int index = pos.getErrorIndex();
833         if (index < 0)
834           index = pos.getIndex();
835         throw new ParseException("invalid Date syntax in \""
836                                  + source + '\"', index);
837       }
838     return result;
839   }
840
841   /** 
842    * This method parses the specified <code>String</code> into a 
843    * <code>Date</code>.  The <code>pos</code> argument contains the
844    * starting parse position on method entry and the ending parse
845    * position on method exit.
846    *
847    * @param source The string to parse.
848    * @param pos The starting parse position in entry, the ending parse
849    * position on exit.
850    *
851    * @return The parsed date, or <code>null</code> if the string cannot
852    * be parsed.
853    */
854   public abstract Date parse (String source, ParsePosition pos);
855
856   /**
857    * This method is identical to <code>parse(String, ParsePosition)</code>,
858    * but returns its result as an <code>Object</code> instead of a
859    * <code>Date</code>.
860    * 
861    * @param source The string to parse.
862    * @param pos The starting parse position in entry, the ending parse
863    * position on exit.
864    *
865    * @return The parsed date, or <code>null</code> if the string cannot
866    * be parsed.
867    */
868   public Object parseObject (String source, ParsePosition pos)
869   {
870     return parse(source, pos);
871   }
872
873   /**
874    * This method specified the <code>Calendar</code> that should be used 
875    * by this object to parse/format datetimes.
876    *
877    * @param calendar The new <code>Calendar</code> for this object.
878    *
879    * @see java.util.Calendar
880    */
881   public void setCalendar (Calendar calendar)
882   {
883     this.calendar = calendar;
884   }
885
886   /**
887    * This method specifies whether or not this object should be lenient in 
888    * the syntax it accepts while parsing date/time values.
889    *
890    * @param lenient <code>true</code> if parsing should be lenient,
891    * <code>false</code> otherwise.
892    */
893   public void setLenient (boolean lenient)
894   {
895     calendar.setLenient(lenient);
896   }
897
898   /**
899    * This method specifies the <code>NumberFormat</code> object that should
900    * be used by this object to parse/format times.
901    *
902    * @param numberFormat The <code>NumberFormat</code> in use by this object.
903    */
904   public void setNumberFormat (NumberFormat numberFormat)
905   {
906     this.numberFormat = numberFormat;
907   }
908
909   /**
910    * This method sets the time zone that should be used by this object.
911    *
912    * @param timeZone The new time zone.
913    */
914   public void setTimeZone (TimeZone timeZone)
915   {
916     calendar.setTimeZone(timeZone);
917   }
918 }