OSDN Git Service

* java/text/SimpleDateFormat.java: Re-merged with Classpath.
[pf3gnuchains/gcc-fork.git] / libjava / java / text / DateFormat.java
1 /* DateFormat.java -- Class for formatting/parsing date/times
2    Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
3
4 This file is part of GNU Classpath.
5
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10  
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA.
20
21 As a special exception, if you link this library with other files to
22 produce an executable, this library does not by itself cause the
23 resulting executable to be covered by the GNU General Public License.
24 This exception does not however invalidate any other reasons why the
25 executable file might be covered by the GNU General Public License. */
26
27
28 package java.text;
29
30 import java.util.*;
31
32 /**
33  * @author Per Bothner <bothner@cygnus.com>
34  * @date October 25, 1998.
35  */
36 /* Written using "Java Class Libraries", 2nd edition, plus online
37  * API docs for JDK 1.2 beta from http://www.javasoft.com.
38  * Status:  Mostly complete; search for FIXME to see omissions.
39  */
40
41 public abstract class DateFormat extends Format implements Cloneable
42 {
43   protected Calendar calendar;
44   protected NumberFormat numberFormat;
45
46   // (Values determined using a test program.)
47   public static final int FULL = 0;
48   public static final int LONG = 1;
49   public static final int MEDIUM = 2;
50   public static final int SHORT = 3;
51   public static final int DEFAULT = MEDIUM;
52
53   /* These constants need to have these exact values.  They
54    * correspond to index positions within the localPatternChars
55    * string for a given locale.  For example, the US locale uses
56    * the string "GyMdkHmsSEDFwWahKz", where 'G' is the character
57    * for era, 'y' for year, and so on down to 'z' for time zone.
58    */
59   public static final int ERA_FIELD = 0;
60   public static final int YEAR_FIELD = 1;
61   public static final int MONTH_FIELD = 2;
62   public static final int DATE_FIELD = 3;
63   public static final int HOUR_OF_DAY1_FIELD = 4;
64   public static final int HOUR_OF_DAY0_FIELD = 5;
65   public static final int MINUTE_FIELD = 6;
66   public static final int SECOND_FIELD = 7;
67   public static final int MILLISECOND_FIELD = 8;
68   public static final int DAY_OF_WEEK_FIELD = 9;
69   public static final int DAY_OF_YEAR_FIELD = 10;
70   public static final int DAY_OF_WEEK_IN_MONTH_FIELD = 11;
71   public static final int WEEK_OF_YEAR_FIELD = 12;
72   public static final int WEEK_OF_MONTH_FIELD = 13;
73   public static final int AM_PM_FIELD = 14;
74   public static final int HOUR1_FIELD = 15;
75   public static final int HOUR0_FIELD = 16;
76   public static final int TIMEZONE_FIELD = 17;
77
78   /**
79    * This method initializes a new instance of <code>DateFormat</code>.
80    */
81   protected DateFormat ()
82   {
83   }
84
85   /**
86    * This method tests this object for equality against the specified object.
87    * The two objects will be considered equal if an only if the specified
88    * object:
89    * <P>
90    * <ul>
91    * <li>Is not <code>null</code>.
92    * <li>Is an instance of <code>DateFormat</code>.
93    * <li>Has the same calendar and numberFormat field values as this object.
94    * </ul>
95    *
96    * @param obj The object to test for equality against.
97    * 
98    * @return <code>true</code> if the specified object is equal to this object,
99    * <code>false</code> otherwise.
100    */
101   public boolean equals (Object obj)
102   {
103     if (! (obj instanceof DateFormat))
104       return false;
105     DateFormat d = (DateFormat) obj;
106     return calendar.equals(d.calendar) && numberFormat.equals(d.numberFormat);
107   }
108
109   /**
110    * This method returns a copy of this object.
111    *
112    * @return A copy of this object.
113    */
114   public Object clone ()
115   {
116     // We know the superclass just call's Object's generic cloner.
117     return super.clone ();
118   }
119
120   /**
121    * This method formats the specified <code>Object</code> into a date string
122    * and appends it to the specified <code>StringBuffer</code>.
123    * The specified object must be an instance of <code>Number</code> or
124    * <code>Date</code> or an <code>IllegalArgumentException</code> will be
125    * thrown.
126    *
127    * @param obj The <code>Object</code> to format.
128    * @param toAppendTo The <code>StringBuffer</code> to append the resultant
129    * <code>String</code> to.
130    * @param fieldPosition Is updated to the start and end index of the
131    * specified field.
132    *
133    * @return The <code>StringBuffer</code> supplied on input, with the
134    * formatted date/time appended.
135    */
136   public final StringBuffer format (Object obj,
137                                     StringBuffer buf, FieldPosition pos)
138   {
139     if (obj instanceof Number)
140       obj = new Date(((Number) obj).longValue());
141     return format ((Date) obj, buf, pos);
142   }
143
144   /**  
145     * Formats the date argument according to the pattern specified. 
146     *
147     * @param date The formatted date.
148     */
149   public final String format (Date date)
150   {
151     StringBuffer sb = new StringBuffer ();
152     format (date, sb, new FieldPosition (MONTH_FIELD));
153     return sb.toString();
154   }
155
156   /**
157    * This method formats a <code>Date</code> into a string and appends it
158    * to the specified <code>StringBuffer</code>.
159    *
160    * @param date The <code>Date</code> value to format.
161    * @param toAppendTo The <code>StringBuffer</code> to append the resultant
162    * <code>String</code> to.
163    * @param fieldPosition Is updated to the start and end index of the
164    * specified field.
165    *
166    * @return The <code>StringBuffer</code> supplied on input, with the
167    * formatted date/time appended.
168    */
169   public abstract StringBuffer format (Date date,
170                                        StringBuffer buf, FieldPosition pos);
171
172   /**
173    * This method returns a list of available locales supported by this
174    * class.
175    */
176   public static Locale[] getAvailableLocales ()
177   {
178     // FIXME
179     Locale[] l = new Locale[1];
180     l[0] = Locale.US;
181     return l;
182   }
183
184   /**
185     * This method returns the <code>Calendar</code> object being used by
186     * this object to parse/format datetimes.
187     *
188     * @return The <code>Calendar</code> being used by this object.
189     *
190     * @see java.util.Calendar
191     */
192   public Calendar getCalendar ()
193   {
194     return calendar;
195   }
196
197   private static final DateFormat computeInstance (int style, Locale loc,
198                                                    boolean use_date,
199                                                    boolean use_time)
200   {
201     return computeInstance (style, style, loc, use_date, use_time);
202   }
203
204   private static final DateFormat computeInstance (int dateStyle, 
205                                                    int timeStyle,
206                                                    Locale loc,
207                                                    boolean use_date,
208                                                    boolean use_time)
209   {
210     ResourceBundle res;
211     try
212       {
213         res = ResourceBundle.getBundle("gnu.java.locale.LocaleInformation",
214                                        loc);
215       }
216     catch (MissingResourceException x)
217       {
218         res = null;
219       }
220
221     String pattern = null;
222     if (use_date)
223       {
224         String name, def;
225         switch (dateStyle)
226           {
227           case FULL:
228             name = "fullDateFormat";
229             def = "EEEE MMMM d, yyyy G";
230             break;
231           case LONG:
232             name = "longDateFormat";
233             def = "MMMM d, yyyy";
234             break;
235           case MEDIUM:
236             name = "mediumDateFormat";
237             def = "d-MMM-yy";
238             break;
239           case SHORT:
240             name = "shortDateFormat";
241             def = "M/d/yy";
242             break;
243           default:
244             throw new IllegalArgumentException ();
245           }
246         try
247           {
248             pattern = res == null ? def : res.getString(name);
249           }
250         catch (MissingResourceException x)
251           {
252             pattern = def;
253           }
254       }
255
256     if (use_time)
257       {
258         if (pattern == null)
259           pattern = "";
260         else
261           pattern += " ";
262
263         String name, def;
264         switch (timeStyle)
265           {
266           case FULL:
267             name = "fullTimeFormat";
268             def = "h:mm:ss;S 'o''clock' a z";
269             break;
270           case LONG:
271             name = "longTimeFormat";
272             def = "h:mm:ss a z";
273             break;
274           case MEDIUM:
275             name = "mediumTimeFormat";
276             def = "h:mm:ss a";
277             break;
278           case SHORT:
279             name = "shortTimeFormat";
280             def = "h:mm a";
281             break;
282           default:
283             throw new IllegalArgumentException ();
284           }
285
286         String s;
287         try
288           {
289             s = res == null ? def : res.getString(name);
290           }
291         catch (MissingResourceException x)
292           {
293             s = def;
294           }
295         pattern += s;
296       }
297
298     return new SimpleDateFormat (pattern, loc);
299   }
300
301  /**
302    * This method returns an instance of <code>DateFormat</code> that will
303    * format using the default formatting style for dates.
304    *
305    * @return A new <code>DateFormat</code> instance.
306    */
307   public static final DateFormat getDateInstance ()
308   {
309     return getDateInstance (DEFAULT, Locale.getDefault());
310   }
311
312   /**
313    * This method returns an instance of <code>DateFormat</code> that will
314    * format using the specified formatting style for dates.
315    *
316    * @param style The type of formatting to perform. 
317    * 
318    * @return A new <code>DateFormat</code> instance.
319    */
320   public static final DateFormat getDateInstance (int style)
321   {
322     return getDateInstance (style, Locale.getDefault());
323   }
324
325   /**
326    * This method returns an instance of <code>DateFormat</code> that will
327    * format using the specified formatting style for dates.  The specified
328    * localed will be used in place of the default.
329    *
330    * @param style The type of formatting to perform. 
331    * @param aLocale The desired locale.
332    * 
333    * @return A new <code>DateFormat</code> instance.
334    */
335   public static final DateFormat getDateInstance (int style, Locale loc)
336   {
337     return computeInstance (style, loc, true, false);
338   }
339
340   /**
341    * This method returns a new instance of <code>DateFormat</code> that
342    * formats both dates and times using the <code>SHORT</code> style.
343    *
344    * @return A new <code>DateFormat</code>instance.
345    */
346   public static final DateFormat getDateTimeInstance ()
347   {
348     return getDateTimeInstance (DEFAULT, DEFAULT, Locale.getDefault());
349   }
350
351   /**
352    * This method returns a new instance of <code>DateFormat</code> that
353    * formats both dates and times using the <code>DEFAULT</code> style.
354    *
355    * @return A new <code>DateFormat</code>instance.
356    */
357   public static final DateFormat getDateTimeInstance (int dateStyle, 
358                                                       int timeStyle)
359   {
360     return getDateTimeInstance (dateStyle, timeStyle, Locale.getDefault());
361   }
362
363   /**
364    * This method returns a new instance of <code>DateFormat</code> that
365    * formats both dates and times using the specified styles.
366    * 
367    * @param dateStyle The desired style for date formatting.
368    * @param timeStyle The desired style for time formatting
369    *
370    * @return A new <code>DateFormat</code>instance.
371    */
372   public static final DateFormat getDateTimeInstance (int dateStyle, 
373                                                       int timeStyle, 
374                                                       Locale loc)
375   {
376     return computeInstance (dateStyle, timeStyle, loc, true, true);
377   }
378
379   /**
380    * This method returns a new instance of <code>DateFormat</code> that
381    * formats both dates and times using the <code>SHORT</code> style.
382    *
383    * @return A new <code>DateFormat</code>instance.
384    */
385   public static final DateFormat getInstance ()
386   {
387     // JCL book says SHORT.
388     return getDateTimeInstance (SHORT, SHORT, Locale.getDefault());
389   }
390
391   /**
392    * This method returns the <code>NumberFormat</code> object being used
393    * by this object to parse/format time values.
394    *
395    * @return The <code>NumberFormat</code> in use by this object.
396    */
397   public NumberFormat getNumberFormat ()
398   {
399     return numberFormat;
400   }
401
402  /**
403    * This method returns an instance of <code>DateFormat</code> that will
404    * format using the default formatting style for times.
405    *
406    * @return A new <code>DateFormat</code> instance.
407    */
408   public static final DateFormat getTimeInstance ()
409   {
410     return getTimeInstance (DEFAULT, Locale.getDefault());
411   }
412
413   /**
414    * This method returns an instance of <code>DateFormat</code> that will
415    * format using the specified formatting style for times.
416    *
417    * @param style The type of formatting to perform. 
418    * 
419    * @return A new <code>DateFormat</code> instance.
420    */
421   public static final DateFormat getTimeInstance (int style)
422   {
423     return getTimeInstance (style, Locale.getDefault());
424   }
425
426   /**
427    * This method returns an instance of <code>DateFormat</code> that will
428    * format using the specified formatting style for times.  The specified
429    * localed will be used in place of the default.
430    *
431    * @param style The type of formatting to perform. 
432    * @param aLocale The desired locale.
433    * 
434    * @return A new <code>DateFormat</code> instance.
435    */
436   public static final DateFormat getTimeInstance (int style, Locale loc)
437   {
438     return computeInstance (style, loc, false, true);
439   }
440
441   /**
442    * This method returns the <code>TimeZone</code> object being used by
443    * this instance.
444    *
445    * @return The time zone in use.
446    */
447   public TimeZone getTimeZone ()
448   {
449     return calendar.getTimeZone();
450   }
451
452   /**
453    * This method returns a hash value for this object.
454    * 
455    * @return A hash value for this object.
456    */
457   public int hashCode ()
458   {
459     int hash = calendar.hashCode();
460     if (numberFormat != null)
461       hash ^= numberFormat.hashCode();
462     return hash;
463   }
464
465   /**
466    * This method indicates whether or not the parsing of date and time
467    * values should be done in a lenient value.
468    *
469    * @return <code>true</code> if date/time parsing is lenient,
470    * <code>false</code> otherwise.
471    */
472   public boolean isLenient ()
473   {
474     return calendar.isLenient();
475   }
476
477   /**
478    * This method parses the specified date/time string.
479    *
480    * @return The resultant date.
481    *
482    * @exception ParseException If the specified string cannot be parsed.
483    */
484   public Date parse (String source) throws ParseException
485   {
486     ParsePosition pos = new ParsePosition(0);
487     Date result = parse (source, pos);
488     if (result == null)
489       {
490         int index = pos.getErrorIndex();
491         if (index < 0)
492           index = pos.getIndex();
493         throw new ParseException("invalid Date syntax", index);
494       }
495     return result;
496   }
497
498   /** 
499    * This method parses the specified <code>String</code> into a 
500    * <code>Date</code>.  The <code>pos</code> argument contains the
501    * starting parse position on method entry and the ending parse
502    * position on method exit.
503    *
504    * @param text The string to parse.
505    * @param pos The starting parse position in entry, the ending parse
506    * position on exit.
507    *
508    * @return The parsed date, or <code>null</code> if the string cannot
509    * be parsed.
510    */
511   public abstract Date parse (String source, ParsePosition pos);
512
513   /**
514    * This method is identical to <code>parse(String, ParsePosition)</code>,
515    * but returns its result as an <code>Object</code> instead of a
516    * <code>Date</code>.
517    * 
518    * @param source The string to parse.
519    * @param pos The starting parse position in entry, the ending parse
520    * position on exit.
521    *
522    * @return The parsed date, or <code>null</code> if the string cannot
523    * be parsed.
524    */
525   public Object parseObject (String source, ParsePosition pos)
526   {
527     return parse(source, pos);
528   }
529
530   /**
531    * This method specified the <code>Calendar</code> that should be used 
532    * by this object to parse/format datetimes.
533    *
534    * @param The new <code>Calendar</code> for this object.
535    *
536    * @see java.util.Calendar
537    */
538   public void setCalendar (Calendar calendar)
539   {
540     this.calendar = calendar;
541   }
542
543   /**
544    * This method specifies whether or not this object should be lenient in 
545    * the syntax it accepts while parsing date/time values.
546    *
547    * @param lenient <code>true</code> if parsing should be lenient,
548    * <code>false</code> otherwise.
549    */
550   public void setLenient (boolean lenient)
551   {
552     calendar.setLenient(lenient);
553   }
554
555   /**
556    * This method specifies the <code>NumberFormat</code> object that should
557    * be used by this object to parse/format times.
558    *
559    * @param The <code>NumberFormat</code> in use by this object.
560    */
561   public void setNumberFormat (NumberFormat numberFormat)
562   {
563     this.numberFormat = numberFormat;
564   }
565
566   /**
567    * This method sets the time zone that should be used by this object.
568    *
569    * @param The new time zone.
570    */
571   public void setTimeZone (TimeZone timeZone)
572   {
573     calendar.setTimeZone(timeZone);
574   }
575 }