gcc/
[official-gcc.git] / libjava / java / text / DateFormat.java
blob6fe4461b0301952c2674725052307602b8a541da
1 /* DateFormat.java -- Class for formatting/parsing date/times
2 Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004
3 Free Software Foundation, Inc.
5 This file is part of GNU Classpath.
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.
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.
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., 59 Temple Place, Suite 330, Boston, MA
20 02111-1307 USA.
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.
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. */
40 package java.text;
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;
50 /**
51 * @author Per Bothner <bothner@cygnus.com>
52 * @date October 25, 1998.
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.
59 public abstract class DateFormat extends Format implements Cloneable
61 protected Calendar calendar;
62 protected NumberFormat numberFormat;
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;
71 /* These constants need to have these exact values. They
72 * correspond to index positions within the localPatternChars
73 * string for a given locale. For example, the US locale uses
74 * the string "GyMdkHmsSEDFwWahKz", where 'G' is the character
75 * for era, 'y' for year, and so on down to 'z' for time zone.
77 public static final int ERA_FIELD = 0;
78 public static final int YEAR_FIELD = 1;
79 public static final int MONTH_FIELD = 2;
80 public static final int DATE_FIELD = 3;
81 public static final int HOUR_OF_DAY1_FIELD = 4;
82 public static final int HOUR_OF_DAY0_FIELD = 5;
83 public static final int MINUTE_FIELD = 6;
84 public static final int SECOND_FIELD = 7;
85 public static final int MILLISECOND_FIELD = 8;
86 public static final int DAY_OF_WEEK_FIELD = 9;
87 public static final int DAY_OF_YEAR_FIELD = 10;
88 public static final int DAY_OF_WEEK_IN_MONTH_FIELD = 11;
89 public static final int WEEK_OF_YEAR_FIELD = 12;
90 public static final int WEEK_OF_MONTH_FIELD = 13;
91 public static final int AM_PM_FIELD = 14;
92 public static final int HOUR1_FIELD = 15;
93 public static final int HOUR0_FIELD = 16;
94 public static final int TIMEZONE_FIELD = 17;
97 public static class Field extends Format.Field
99 static final long serialVersionUID = 7441350119349544720L;
101 private int calendarField;
103 public static final DateFormat.Field ERA
104 = new Field("era", Calendar.ERA);
105 public static final DateFormat.Field YEAR
106 = new Field("year", Calendar.YEAR);
107 public static final DateFormat.Field MONTH
108 = new Field("month", Calendar.MONTH);
109 public static final DateFormat.Field DAY_OF_MONTH
110 = new Field("day of month", Calendar.DAY_OF_MONTH);
111 public static final DateFormat.Field HOUR_OF_DAY1
112 = new Field("hour of day 1", Calendar.HOUR_OF_DAY);
113 public static final DateFormat.Field HOUR_OF_DAY0
114 = new Field("hour of day 0", Calendar.HOUR_OF_DAY);
115 public static final DateFormat.Field MINUTE
116 = new Field("minute", Calendar.MINUTE);
117 public static final DateFormat.Field SECOND
118 = new Field("second", Calendar.SECOND);
119 public static final DateFormat.Field MILLISECOND
120 = new Field("millisecond", Calendar.MILLISECOND);
121 public static final DateFormat.Field DAY_OF_WEEK
122 = new Field("day of week", Calendar.DAY_OF_WEEK);
123 public static final DateFormat.Field DAY_OF_YEAR
124 = new Field("day of year", Calendar.DAY_OF_YEAR);
125 public static final DateFormat.Field DAY_OF_WEEK_IN_MONTH
126 = new Field("day of week in month", Calendar.DAY_OF_WEEK_IN_MONTH);
127 public static final DateFormat.Field WEEK_OF_YEAR
128 = new Field("week of year", Calendar.WEEK_OF_YEAR);
129 public static final DateFormat.Field WEEK_OF_MONTH
130 = new Field("week of month", Calendar.WEEK_OF_MONTH);
131 public static final DateFormat.Field AM_PM
132 = new Field("am/pm", Calendar.AM_PM);
133 public static final DateFormat.Field HOUR1
134 = new Field("hour1", Calendar.HOUR);
135 public static final DateFormat.Field HOUR0
136 = new Field("hour0", Calendar.HOUR);
137 public static final DateFormat.Field TIME_ZONE
138 = new Field("timezone", Calendar.ZONE_OFFSET);
140 static final DateFormat.Field[] allFields =
142 ERA, YEAR, MONTH, DAY_OF_MONTH, HOUR_OF_DAY1,
143 HOUR_OF_DAY0, MINUTE, SECOND, MILLISECOND,
144 DAY_OF_WEEK, DAY_OF_YEAR, DAY_OF_WEEK_IN_MONTH,
145 WEEK_OF_YEAR, WEEK_OF_MONTH, AM_PM, HOUR1, HOUR0,
146 TIME_ZONE
149 // For deserialization
150 private Field()
152 super("");
155 protected Field(String name, int calendarField)
157 super(name);
158 this.calendarField = calendarField;
161 public int getCalendarField()
163 return calendarField;
166 public static Field ofCalendarField(int calendarField)
168 if (calendarField >= allFields.length || calendarField < 0)
169 throw new IllegalArgumentException("no such calendar field ("
170 + calendarField + ")");
172 return allFields[calendarField];
175 protected Object readResolve() throws InvalidObjectException
177 String s = getName();
179 for (int i=0;i<allFields.length;i++)
180 if (s.equals(allFields[i].getName()))
181 return allFields[i];
183 throw new InvalidObjectException("no such DateFormat field called " + s);
188 * This method initializes a new instance of <code>DateFormat</code>.
190 protected DateFormat ()
195 * This method tests this object for equality against the specified object.
196 * The two objects will be considered equal if an only if the specified
197 * object:
198 * <P>
199 * <ul>
200 * <li>Is not <code>null</code>.</li>
201 * <li>Is an instance of <code>DateFormat</code>.</li>
202 * <li>Has the same numberFormat field value as this object.</li>
203 * </ul>
205 * @param obj The object to test for equality against.
207 * @return <code>true</code> if the specified object is equal to this object,
208 * <code>false</code> otherwise.
210 public boolean equals (Object obj)
212 if (!(obj instanceof DateFormat))
213 return false;
215 DateFormat d = (DateFormat) obj;
217 return numberFormat.equals(d.numberFormat);
221 * This method returns a copy of this object.
223 * @return A copy of this object.
225 public Object clone ()
227 // We know the superclass just call's Object's generic cloner.
228 return super.clone ();
232 * This method formats the specified <code>Object</code> into a date string
233 * and appends it to the specified <code>StringBuffer</code>.
234 * The specified object must be an instance of <code>Number</code> or
235 * <code>Date</code> or an <code>IllegalArgumentException</code> will be
236 * thrown.
238 * @param obj The <code>Object</code> to format.
239 * @param toAppendTo The <code>StringBuffer</code> to append the resultant
240 * <code>String</code> to.
241 * @param fieldPosition Is updated to the start and end index of the
242 * specified field.
244 * @return The <code>StringBuffer</code> supplied on input, with the
245 * formatted date/time appended.
247 public final StringBuffer format (Object obj,
248 StringBuffer buf, FieldPosition pos)
250 if (obj instanceof Number)
251 obj = new Date(((Number) obj).longValue());
252 else if (! (obj instanceof Date))
253 throw new IllegalArgumentException
254 ("Cannot format given Object as a Date");
256 return format ((Date) obj, buf, pos);
259 /**
260 * Formats the date argument according to the pattern specified.
262 * @param date The formatted date.
264 public final String format (Date date)
266 StringBuffer sb = new StringBuffer ();
267 format (date, sb, new FieldPosition (MONTH_FIELD));
268 return sb.toString();
272 * This method formats a <code>Date</code> into a string and appends it
273 * to the specified <code>StringBuffer</code>.
275 * @param date The <code>Date</code> value to format.
276 * @param toAppendTo The <code>StringBuffer</code> to append the resultant
277 * <code>String</code> to.
278 * @param fieldPosition Is updated to the start and end index of the
279 * specified field.
281 * @return The <code>StringBuffer</code> supplied on input, with the
282 * formatted date/time appended.
284 public abstract StringBuffer format (Date date,
285 StringBuffer buf, FieldPosition pos);
288 * This method returns a list of available locales supported by this
289 * class.
291 public static Locale[] getAvailableLocales ()
293 // FIXME
294 Locale[] l = new Locale[1];
295 l[0] = Locale.US;
296 return l;
300 * This method returns the <code>Calendar</code> object being used by
301 * this object to parse/format datetimes.
303 * @return The <code>Calendar</code> being used by this object.
305 * @see java.util.Calendar
307 public Calendar getCalendar ()
309 return calendar;
312 private static DateFormat computeInstance (int style, Locale loc,
313 boolean use_date, boolean use_time)
315 return computeInstance (style, style, loc, use_date, use_time);
318 private static DateFormat computeInstance (int dateStyle, int timeStyle,
319 Locale loc, boolean use_date,
320 boolean use_time)
322 ResourceBundle res;
325 res = ResourceBundle.getBundle("gnu.java.locale.LocaleInformation",
326 loc, ClassLoader.getSystemClassLoader());
328 catch (MissingResourceException x)
330 res = null;
333 String pattern = null;
334 if (use_date)
336 String name, def;
337 switch (dateStyle)
339 case FULL:
340 name = "fullDateFormat";
341 def = "EEEE MMMM d, yyyy G";
342 break;
343 case LONG:
344 name = "longDateFormat";
345 def = "MMMM d, yyyy";
346 break;
347 case MEDIUM:
348 name = "mediumDateFormat";
349 def = "d-MMM-yy";
350 break;
351 case SHORT:
352 name = "shortDateFormat";
353 def = "M/d/yy";
354 break;
355 default:
356 throw new IllegalArgumentException ();
360 pattern = res == null ? def : res.getString(name);
362 catch (MissingResourceException x)
364 pattern = def;
368 if (use_time)
370 if (pattern == null)
371 pattern = "";
372 else
373 pattern += " ";
375 String name, def;
376 switch (timeStyle)
378 case FULL:
379 name = "fullTimeFormat";
380 def = "h:mm:ss;S 'o''clock' a z";
381 break;
382 case LONG:
383 name = "longTimeFormat";
384 def = "h:mm:ss a z";
385 break;
386 case MEDIUM:
387 name = "mediumTimeFormat";
388 def = "h:mm:ss a";
389 break;
390 case SHORT:
391 name = "shortTimeFormat";
392 def = "h:mm a";
393 break;
394 default:
395 throw new IllegalArgumentException ();
398 String s;
401 s = res == null ? def : res.getString(name);
403 catch (MissingResourceException x)
405 s = def;
407 pattern += s;
410 return new SimpleDateFormat (pattern, loc);
414 * This method returns an instance of <code>DateFormat</code> that will
415 * format using the default formatting style for dates.
417 * @return A new <code>DateFormat</code> instance.
419 public static final DateFormat getDateInstance ()
421 return getDateInstance (DEFAULT, Locale.getDefault());
425 * This method returns an instance of <code>DateFormat</code> that will
426 * format using the specified formatting style for dates.
428 * @param style The type of formatting to perform.
430 * @return A new <code>DateFormat</code> instance.
432 public static final DateFormat getDateInstance (int style)
434 return getDateInstance (style, Locale.getDefault());
438 * This method returns an instance of <code>DateFormat</code> that will
439 * format using the specified formatting style for dates. The specified
440 * localed will be used in place of the default.
442 * @param style The type of formatting to perform.
443 * @param aLocale The desired locale.
445 * @return A new <code>DateFormat</code> instance.
447 public static final DateFormat getDateInstance (int style, Locale loc)
449 return computeInstance (style, loc, true, false);
453 * This method returns a new instance of <code>DateFormat</code> that
454 * formats both dates and times using the <code>SHORT</code> style.
456 * @return A new <code>DateFormat</code>instance.
458 public static final DateFormat getDateTimeInstance ()
460 return getDateTimeInstance (DEFAULT, DEFAULT, Locale.getDefault());
464 * This method returns a new instance of <code>DateFormat</code> that
465 * formats both dates and times using the <code>DEFAULT</code> style.
467 * @return A new <code>DateFormat</code>instance.
469 public static final DateFormat getDateTimeInstance (int dateStyle,
470 int timeStyle)
472 return getDateTimeInstance (dateStyle, timeStyle, Locale.getDefault());
476 * This method returns a new instance of <code>DateFormat</code> that
477 * formats both dates and times using the specified styles.
479 * @param dateStyle The desired style for date formatting.
480 * @param timeStyle The desired style for time formatting
482 * @return A new <code>DateFormat</code>instance.
484 public static final DateFormat getDateTimeInstance (int dateStyle,
485 int timeStyle,
486 Locale loc)
488 return computeInstance (dateStyle, timeStyle, loc, true, true);
492 * This method returns a new instance of <code>DateFormat</code> that
493 * formats both dates and times using the <code>SHORT</code> style.
495 * @return A new <code>DateFormat</code>instance.
497 public static final DateFormat getInstance ()
499 // JCL book says SHORT.
500 return getDateTimeInstance (SHORT, SHORT, Locale.getDefault());
504 * This method returns the <code>NumberFormat</code> object being used
505 * by this object to parse/format time values.
507 * @return The <code>NumberFormat</code> in use by this object.
509 public NumberFormat getNumberFormat ()
511 return numberFormat;
515 * This method returns an instance of <code>DateFormat</code> that will
516 * format using the default formatting style for times.
518 * @return A new <code>DateFormat</code> instance.
520 public static final DateFormat getTimeInstance ()
522 return getTimeInstance (DEFAULT, Locale.getDefault());
526 * This method returns an instance of <code>DateFormat</code> that will
527 * format using the specified formatting style for times.
529 * @param style The type of formatting to perform.
531 * @return A new <code>DateFormat</code> instance.
533 public static final DateFormat getTimeInstance (int style)
535 return getTimeInstance (style, Locale.getDefault());
539 * This method returns an instance of <code>DateFormat</code> that will
540 * format using the specified formatting style for times. The specified
541 * localed will be used in place of the default.
543 * @param style The type of formatting to perform.
544 * @param aLocale The desired locale.
546 * @return A new <code>DateFormat</code> instance.
548 public static final DateFormat getTimeInstance (int style, Locale loc)
550 return computeInstance (style, loc, false, true);
554 * This method returns the <code>TimeZone</code> object being used by
555 * this instance.
557 * @return The time zone in use.
559 public TimeZone getTimeZone ()
561 return calendar.getTimeZone();
565 * This method returns a hash value for this object.
567 * @return A hash value for this object.
569 public int hashCode ()
571 if (numberFormat != null)
572 return numberFormat.hashCode();
573 else
574 return 0;
578 * This method indicates whether or not the parsing of date and time
579 * values should be done in a lenient value.
581 * @return <code>true</code> if date/time parsing is lenient,
582 * <code>false</code> otherwise.
584 public boolean isLenient ()
586 return calendar.isLenient();
590 * This method parses the specified date/time string.
592 * @param source The string to parse.
593 * @return The resultant date.
595 * @exception ParseException If the specified string cannot be parsed.
597 public Date parse (String source) throws ParseException
599 ParsePosition pos = new ParsePosition(0);
600 Date result = parse (source, pos);
601 if (result == null)
603 int index = pos.getErrorIndex();
604 if (index < 0)
605 index = pos.getIndex();
606 throw new ParseException("invalid Date syntax in \""
607 + source + '\"', 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);