2003-12-26 Guilhem Lavaux <guilhem@kaffe.org>
[official-gcc.git] / libjava / java / text / DateFormat.java
blob745a16b3ec284bab7862af0bdb61568747291354
1 /* DateFormat.java -- Class for formatting/parsing date/times
2 Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
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.
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.
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.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
39 package java.text;
41 import java.io.InvalidObjectException;
42 import java.util.Calendar;
43 import java.util.Date;
44 import java.util.Locale;
45 import java.util.MissingResourceException;
46 import java.util.ResourceBundle;
47 import java.util.TimeZone;
49 /**
50 * @author Per Bothner <bothner@cygnus.com>
51 * @date October 25, 1998.
53 /* Written using "Java Class Libraries", 2nd edition, plus online
54 * API docs for JDK 1.2 beta from http://www.javasoft.com.
55 * Status: Mostly complete; search for FIXME to see omissions.
58 public abstract class DateFormat extends Format implements Cloneable
60 protected Calendar calendar;
61 protected NumberFormat numberFormat;
63 // (Values determined using a test program.)
64 public static final int FULL = 0;
65 public static final int LONG = 1;
66 public static final int MEDIUM = 2;
67 public static final int SHORT = 3;
68 public static final int DEFAULT = MEDIUM;
70 /* These constants need to have these exact values. They
71 * correspond to index positions within the localPatternChars
72 * string for a given locale. For example, the US locale uses
73 * the string "GyMdkHmsSEDFwWahKz", where 'G' is the character
74 * for era, 'y' for year, and so on down to 'z' for time zone.
76 public static final int ERA_FIELD = 0;
77 public static final int YEAR_FIELD = 1;
78 public static final int MONTH_FIELD = 2;
79 public static final int DATE_FIELD = 3;
80 public static final int HOUR_OF_DAY1_FIELD = 4;
81 public static final int HOUR_OF_DAY0_FIELD = 5;
82 public static final int MINUTE_FIELD = 6;
83 public static final int SECOND_FIELD = 7;
84 public static final int MILLISECOND_FIELD = 8;
85 public static final int DAY_OF_WEEK_FIELD = 9;
86 public static final int DAY_OF_YEAR_FIELD = 10;
87 public static final int DAY_OF_WEEK_IN_MONTH_FIELD = 11;
88 public static final int WEEK_OF_YEAR_FIELD = 12;
89 public static final int WEEK_OF_MONTH_FIELD = 13;
90 public static final int AM_PM_FIELD = 14;
91 public static final int HOUR1_FIELD = 15;
92 public static final int HOUR0_FIELD = 16;
93 public static final int TIMEZONE_FIELD = 17;
96 public static class Field extends Format.Field
98 static final long serialVersionUID = 7441350119349544720L;
100 private int calendarField;
102 public static final DateFormat.Field ERA
103 = new Field("era", Calendar.ERA);
104 public static final DateFormat.Field YEAR
105 = new Field("year", Calendar.YEAR);
106 public static final DateFormat.Field MONTH
107 = new Field("month", Calendar.MONTH);
108 public static final DateFormat.Field DAY_OF_MONTH
109 = new Field("day of month", Calendar.DAY_OF_MONTH);
110 public static final DateFormat.Field HOUR_OF_DAY1
111 = new Field("hour of day 1", Calendar.HOUR_OF_DAY);
112 public static final DateFormat.Field HOUR_OF_DAY0
113 = new Field("hour of day 0", Calendar.HOUR_OF_DAY);
114 public static final DateFormat.Field MINUTE
115 = new Field("minute", Calendar.MINUTE);
116 public static final DateFormat.Field SECOND
117 = new Field("second", Calendar.SECOND);
118 public static final DateFormat.Field MILLISECOND
119 = new Field("millisecond", Calendar.MILLISECOND);
120 public static final DateFormat.Field DAY_OF_WEEK
121 = new Field("day of week", Calendar.DAY_OF_WEEK);
122 public static final DateFormat.Field DAY_OF_YEAR
123 = new Field("day of year", Calendar.DAY_OF_YEAR);
124 public static final DateFormat.Field DAY_OF_WEEK_IN_MONTH
125 = new Field("day of week in month", Calendar.DAY_OF_WEEK_IN_MONTH);
126 public static final DateFormat.Field WEEK_OF_YEAR
127 = new Field("week of year", Calendar.WEEK_OF_YEAR);
128 public static final DateFormat.Field WEEK_OF_MONTH
129 = new Field("week of month", Calendar.WEEK_OF_MONTH);
130 public static final DateFormat.Field AM_PM
131 = new Field("am/pm", Calendar.AM_PM);
132 public static final DateFormat.Field HOUR1
133 = new Field("hour1", Calendar.HOUR);
134 public static final DateFormat.Field HOUR0
135 = new Field("hour0", Calendar.HOUR);
136 public static final DateFormat.Field TIME_ZONE
137 = new Field("timezone", Calendar.ZONE_OFFSET);
139 public static final DateFormat.Field[] allFields =
141 ERA, YEAR, MONTH, DAY_OF_MONTH, HOUR_OF_DAY1,
142 HOUR_OF_DAY0, MINUTE, SECOND, MILLISECOND,
143 DAY_OF_WEEK, DAY_OF_YEAR, DAY_OF_WEEK_IN_MONTH,
144 WEEK_OF_YEAR, WEEK_OF_MONTH, AM_PM, HOUR1, HOUR0,
145 TIME_ZONE
148 // For deserialization
149 private Field()
151 super("");
154 protected Field(String name, int calendarField)
156 super(name);
157 this.calendarField = calendarField;
160 public int getCalendarField()
162 return calendarField;
165 public static Field ofCalendarField(int calendarField)
167 if (calendarField >= allFields.length || calendarField < 0)
168 throw new IllegalArgumentException("no such calendar field ("
169 + calendarField + ")");
171 return allFields[calendarField];
174 protected Object readResolve() throws InvalidObjectException
176 String s = getName();
178 for (int i=0;i<allFields.length;i++)
179 if (s.equals(allFields[i].getName()))
180 return allFields[i];
182 throw new InvalidObjectException("no such DateFormat field called " + s);
187 * This method initializes a new instance of <code>DateFormat</code>.
189 protected DateFormat ()
194 * This method tests this object for equality against the specified object.
195 * The two objects will be considered equal if an only if the specified
196 * object:
197 * <P>
198 * <ul>
199 * <li>Is not <code>null</code>.
200 * <li>Is an instance of <code>DateFormat</code>.
201 * <li>Has the same numberFormat field value as this object.
202 * </ul>
204 * @param obj The object to test for equality against.
206 * @return <code>true</code> if the specified object is equal to this object,
207 * <code>false</code> otherwise.
209 public boolean equals (Object obj)
211 if (!(obj instanceof DateFormat))
212 return false;
214 DateFormat d = (DateFormat) obj;
216 return numberFormat.equals(d.numberFormat);
220 * This method returns a copy of this object.
222 * @return A copy of this object.
224 public Object clone ()
226 // We know the superclass just call's Object's generic cloner.
227 return super.clone ();
231 * This method formats the specified <code>Object</code> into a date string
232 * and appends it to the specified <code>StringBuffer</code>.
233 * The specified object must be an instance of <code>Number</code> or
234 * <code>Date</code> or an <code>IllegalArgumentException</code> will be
235 * thrown.
237 * @param obj The <code>Object</code> to format.
238 * @param toAppendTo The <code>StringBuffer</code> to append the resultant
239 * <code>String</code> to.
240 * @param fieldPosition Is updated to the start and end index of the
241 * specified field.
243 * @return The <code>StringBuffer</code> supplied on input, with the
244 * formatted date/time appended.
246 public final StringBuffer format (Object obj,
247 StringBuffer buf, FieldPosition pos)
249 if (obj instanceof Number)
250 obj = new Date(((Number) obj).longValue());
251 else if (! (obj instanceof Date))
252 throw new IllegalArgumentException
253 ("Cannot format given Object as a Date");
255 return format ((Date) obj, buf, pos);
258 /**
259 * Formats the date argument according to the pattern specified.
261 * @param date The formatted date.
263 public final String format (Date date)
265 StringBuffer sb = new StringBuffer ();
266 format (date, sb, new FieldPosition (MONTH_FIELD));
267 return sb.toString();
271 * This method formats a <code>Date</code> into a string and appends it
272 * to the specified <code>StringBuffer</code>.
274 * @param date The <code>Date</code> value to format.
275 * @param toAppendTo The <code>StringBuffer</code> to append the resultant
276 * <code>String</code> to.
277 * @param fieldPosition Is updated to the start and end index of the
278 * specified field.
280 * @return The <code>StringBuffer</code> supplied on input, with the
281 * formatted date/time appended.
283 public abstract StringBuffer format (Date date,
284 StringBuffer buf, FieldPosition pos);
287 * This method returns a list of available locales supported by this
288 * class.
290 public static Locale[] getAvailableLocales ()
292 // FIXME
293 Locale[] l = new Locale[1];
294 l[0] = Locale.US;
295 return l;
299 * This method returns the <code>Calendar</code> object being used by
300 * this object to parse/format datetimes.
302 * @return The <code>Calendar</code> being used by this object.
304 * @see java.util.Calendar
306 public Calendar getCalendar ()
308 return calendar;
311 private static final DateFormat computeInstance (int style, Locale loc,
312 boolean use_date,
313 boolean use_time)
315 return computeInstance (style, style, loc, use_date, use_time);
318 private static final DateFormat computeInstance (int dateStyle,
319 int timeStyle,
320 Locale loc,
321 boolean use_date,
322 boolean use_time)
324 ResourceBundle res;
327 res = ResourceBundle.getBundle("gnu.java.locale.LocaleInformation",
328 loc);
330 catch (MissingResourceException x)
332 res = null;
335 String pattern = null;
336 if (use_date)
338 String name, def;
339 switch (dateStyle)
341 case FULL:
342 name = "fullDateFormat";
343 def = "EEEE MMMM d, yyyy G";
344 break;
345 case LONG:
346 name = "longDateFormat";
347 def = "MMMM d, yyyy";
348 break;
349 case MEDIUM:
350 name = "mediumDateFormat";
351 def = "d-MMM-yy";
352 break;
353 case SHORT:
354 name = "shortDateFormat";
355 def = "M/d/yy";
356 break;
357 default:
358 throw new IllegalArgumentException ();
362 pattern = res == null ? def : res.getString(name);
364 catch (MissingResourceException x)
366 pattern = def;
370 if (use_time)
372 if (pattern == null)
373 pattern = "";
374 else
375 pattern += " ";
377 String name, def;
378 switch (timeStyle)
380 case FULL:
381 name = "fullTimeFormat";
382 def = "h:mm:ss;S 'o''clock' a z";
383 break;
384 case LONG:
385 name = "longTimeFormat";
386 def = "h:mm:ss a z";
387 break;
388 case MEDIUM:
389 name = "mediumTimeFormat";
390 def = "h:mm:ss a";
391 break;
392 case SHORT:
393 name = "shortTimeFormat";
394 def = "h:mm a";
395 break;
396 default:
397 throw new IllegalArgumentException ();
400 String s;
403 s = res == null ? def : res.getString(name);
405 catch (MissingResourceException x)
407 s = def;
409 pattern += s;
412 return new SimpleDateFormat (pattern, loc);
416 * This method returns an instance of <code>DateFormat</code> that will
417 * format using the default formatting style for dates.
419 * @return A new <code>DateFormat</code> instance.
421 public static final DateFormat getDateInstance ()
423 return getDateInstance (DEFAULT, Locale.getDefault());
427 * This method returns an instance of <code>DateFormat</code> that will
428 * format using the specified formatting style for dates.
430 * @param style The type of formatting to perform.
432 * @return A new <code>DateFormat</code> instance.
434 public static final DateFormat getDateInstance (int style)
436 return getDateInstance (style, Locale.getDefault());
440 * This method returns an instance of <code>DateFormat</code> that will
441 * format using the specified formatting style for dates. The specified
442 * localed will be used in place of the default.
444 * @param style The type of formatting to perform.
445 * @param aLocale The desired locale.
447 * @return A new <code>DateFormat</code> instance.
449 public static final DateFormat getDateInstance (int style, Locale loc)
451 return computeInstance (style, loc, true, false);
455 * This method returns a new instance of <code>DateFormat</code> that
456 * formats both dates and times using the <code>SHORT</code> style.
458 * @return A new <code>DateFormat</code>instance.
460 public static final DateFormat getDateTimeInstance ()
462 return getDateTimeInstance (DEFAULT, DEFAULT, Locale.getDefault());
466 * This method returns a new instance of <code>DateFormat</code> that
467 * formats both dates and times using the <code>DEFAULT</code> style.
469 * @return A new <code>DateFormat</code>instance.
471 public static final DateFormat getDateTimeInstance (int dateStyle,
472 int timeStyle)
474 return getDateTimeInstance (dateStyle, timeStyle, Locale.getDefault());
478 * This method returns a new instance of <code>DateFormat</code> that
479 * formats both dates and times using the specified styles.
481 * @param dateStyle The desired style for date formatting.
482 * @param timeStyle The desired style for time formatting
484 * @return A new <code>DateFormat</code>instance.
486 public static final DateFormat getDateTimeInstance (int dateStyle,
487 int timeStyle,
488 Locale loc)
490 return computeInstance (dateStyle, timeStyle, loc, true, true);
494 * This method returns a new instance of <code>DateFormat</code> that
495 * formats both dates and times using the <code>SHORT</code> style.
497 * @return A new <code>DateFormat</code>instance.
499 public static final DateFormat getInstance ()
501 // JCL book says SHORT.
502 return getDateTimeInstance (SHORT, SHORT, Locale.getDefault());
506 * This method returns the <code>NumberFormat</code> object being used
507 * by this object to parse/format time values.
509 * @return The <code>NumberFormat</code> in use by this object.
511 public NumberFormat getNumberFormat ()
513 return numberFormat;
517 * This method returns an instance of <code>DateFormat</code> that will
518 * format using the default formatting style for times.
520 * @return A new <code>DateFormat</code> instance.
522 public static final DateFormat getTimeInstance ()
524 return getTimeInstance (DEFAULT, Locale.getDefault());
528 * This method returns an instance of <code>DateFormat</code> that will
529 * format using the specified formatting style for times.
531 * @param style The type of formatting to perform.
533 * @return A new <code>DateFormat</code> instance.
535 public static final DateFormat getTimeInstance (int style)
537 return getTimeInstance (style, Locale.getDefault());
541 * This method returns an instance of <code>DateFormat</code> that will
542 * format using the specified formatting style for times. The specified
543 * localed will be used in place of the default.
545 * @param style The type of formatting to perform.
546 * @param aLocale The desired locale.
548 * @return A new <code>DateFormat</code> instance.
550 public static final DateFormat getTimeInstance (int style, Locale loc)
552 return computeInstance (style, loc, false, true);
556 * This method returns the <code>TimeZone</code> object being used by
557 * this instance.
559 * @return The time zone in use.
561 public TimeZone getTimeZone ()
563 return calendar.getTimeZone();
567 * This method returns a hash value for this object.
569 * @return A hash value for this object.
571 public int hashCode ()
573 if (numberFormat != null)
574 return numberFormat.hashCode();
575 else
576 return 0;
580 * This method indicates whether or not the parsing of date and time
581 * values should be done in a lenient value.
583 * @return <code>true</code> if date/time parsing is lenient,
584 * <code>false</code> otherwise.
586 public boolean isLenient ()
588 return calendar.isLenient();
592 * This method parses the specified date/time string.
594 * @return The resultant date.
596 * @exception ParseException If the specified string cannot be parsed.
598 public Date parse (String source) throws ParseException
600 ParsePosition pos = new ParsePosition(0);
601 Date result = parse (source, pos);
602 if (result == null)
604 int index = pos.getErrorIndex();
605 if (index < 0)
606 index = pos.getIndex();
607 throw new ParseException("invalid Date syntax", index);
609 return result;
612 /**
613 * This method parses the specified <code>String</code> into a
614 * <code>Date</code>. The <code>pos</code> argument contains the
615 * starting parse position on method entry and the ending parse
616 * position on method exit.
618 * @param text The string to parse.
619 * @param pos The starting parse position in entry, the ending parse
620 * position on exit.
622 * @return The parsed date, or <code>null</code> if the string cannot
623 * be parsed.
625 public abstract Date parse (String source, ParsePosition pos);
628 * This method is identical to <code>parse(String, ParsePosition)</code>,
629 * but returns its result as an <code>Object</code> instead of a
630 * <code>Date</code>.
632 * @param source The string to parse.
633 * @param pos The starting parse position in entry, the ending parse
634 * position on exit.
636 * @return The parsed date, or <code>null</code> if the string cannot
637 * be parsed.
639 public Object parseObject (String source, ParsePosition pos)
641 return parse(source, pos);
645 * This method specified the <code>Calendar</code> that should be used
646 * by this object to parse/format datetimes.
648 * @param The new <code>Calendar</code> for this object.
650 * @see java.util.Calendar
652 public void setCalendar (Calendar calendar)
654 this.calendar = calendar;
658 * This method specifies whether or not this object should be lenient in
659 * the syntax it accepts while parsing date/time values.
661 * @param lenient <code>true</code> if parsing should be lenient,
662 * <code>false</code> otherwise.
664 public void setLenient (boolean lenient)
666 calendar.setLenient(lenient);
670 * This method specifies the <code>NumberFormat</code> object that should
671 * be used by this object to parse/format times.
673 * @param The <code>NumberFormat</code> in use by this object.
675 public void setNumberFormat (NumberFormat numberFormat)
677 this.numberFormat = numberFormat;
681 * This method sets the time zone that should be used by this object.
683 * @param The new time zone.
685 public void setTimeZone (TimeZone timeZone)
687 calendar.setTimeZone(timeZone);