2003-12-26 Guilhem Lavaux <guilhem@kaffe.org>
[official-gcc.git] / libjava / java / util / Calendar.java
blob48624beb614635a975e5bdcd3b5669951a5c66ec
1 /* java.util.Calendar
2 Copyright (C) 1998, 1999, 2000, 2001, 2002 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.util;
41 import java.lang.reflect.InvocationTargetException;
42 import java.io.IOException;
43 import java.io.ObjectInputStream;
44 import java.io.ObjectOutputStream;
45 import java.io.Serializable;
47 /**
48 * This class is an abstract base class for Calendars, which can be
49 * used to convert between <code>Date</code> objects and a set of
50 * integer fields which represent <code>YEAR</code>,
51 * <code>MONTH</code>, <code>DAY</code>, etc. The <code>Date</code>
52 * object represents a time in milliseconds since the Epoch. <br>
54 * This class is locale sensitive. To get the Object matching the
55 * current locale you can use <code>getInstance</code>. You can even provide
56 * a locale or a timezone. <code>getInstance</code> returns currently
57 * a <code>GregorianCalendar</code> for the current date. <br>
59 * If you want to convert a date from the Year, Month, Day, DayOfWeek,
60 * etc. Representation to a <code>Date</code>-Object, you can create
61 * a new Calendar with <code>getInstance()</code>,
62 * <code>clear()</code> all fields, <code>set(int,int)</code> the
63 * fields you need and convert it with <code>getTime()</code>. <br>
65 * If you want to convert a <code>Date</code>-object to the Calendar
66 * representation, create a new Calendar, assign the
67 * <code>Date</code>-Object with <code>setTime()</code>, and read the
68 * fields with <code>get(int)</code>. <br>
70 * When computing the date from time fields, it may happen, that there
71 * are either two few fields set, or some fields are inconsistent. This
72 * cases will handled in a calendar specific way. Missing fields are
73 * replaced by the fields of the epoch: 1970 January 1 00:00. <br>
75 * To understand, how the day of year is computed out of the fields
76 * look at the following table. It is traversed from top to bottom,
77 * and for the first line all fields are set, that line is used to
78 * compute the day. <br>
81 <pre>month + day_of_month
82 month + week_of_month + day_of_week
83 month + day_of_week_of_month + day_of_week
84 day_of_year
85 day_of_week + week_of_year</pre>
87 * The hour_of_day-field takes precedence over the ampm and
88 * hour_of_ampm fields. <br>
90 * <STRONG>Note:</STRONG> This can differ for non-Gregorian calendar. <br>
92 * To convert a calendar to a human readable form and vice versa, use
93 * the <code>java.text.DateFormat</code> class. <br>
95 * Other useful things you can do with an calendar, is
96 * <code>roll</code>ing fields (that means increase/decrease a
97 * specific field by one, propagating overflows), or
98 * <code>add</code>ing/substracting a fixed amount to a field.
100 * @see Date
101 * @see GregorianCalendar
102 * @see TimeZone
103 * @see java.text.DateFormat
105 public abstract class Calendar implements Serializable, Cloneable
108 * Constant representing the era time field.
110 public static final int ERA = 0;
112 * Constant representing the year time field.
114 public static final int YEAR = 1;
116 * Constant representing the month time field. This field
117 * should contain one of the JANUARY,...,DECEMBER constants below.
119 public static final int MONTH = 2;
121 * Constant representing the week of the year field.
122 * @see #setFirstDayOfWeek(int)
124 public static final int WEEK_OF_YEAR = 3;
126 * Constant representing the week of the month time field.
127 * @see #setFirstDayOfWeek(int)
129 public static final int WEEK_OF_MONTH = 4;
131 * Constant representing the day time field, synonym for DAY_OF_MONTH.
133 public static final int DATE = 5;
135 * Constant representing the day time field.
137 public static final int DAY_OF_MONTH = 5;
139 * Constant representing the day of year time field. This is
140 * 1 for the first day in month.
142 public static final int DAY_OF_YEAR = 6;
144 * Constant representing the day of week time field. This field
145 * should contain one of the SUNDAY,...,SATURDAY constants below.
147 public static final int DAY_OF_WEEK = 7;
149 * Constant representing the day-of-week-in-month field. For
150 * instance this field contains 2 for the second thursday in a
151 * month. If you give a negative number here, the day will count
152 * from the end of the month.
154 public static final int DAY_OF_WEEK_IN_MONTH = 8;
156 * Constant representing the part of the day for 12-hour clock. This
157 * should be one of AM or PM.
159 public static final int AM_PM = 9;
161 * Constant representing the hour time field for 12-hour clock.
163 public static final int HOUR = 10;
165 * Constant representing the hour of day time field for 24-hour clock.
167 public static final int HOUR_OF_DAY = 11;
169 * Constant representing the minute of hour time field.
171 public static final int MINUTE = 12;
173 * Constant representing the second time field.
175 public static final int SECOND = 13;
177 * Constant representing the millisecond time field.
179 public static final int MILLISECOND = 14;
181 * Constant representing the time zone offset time field for the
182 * time given in the other fields. It is measured in
183 * milliseconds. The default is the offset of the time zone.
185 public static final int ZONE_OFFSET = 15;
187 * Constant representing the daylight saving time offset in
188 * milliseconds. The default is the value given by the time zone.
190 public static final int DST_OFFSET = 16;
192 * Number of time fields.
194 public static final int FIELD_COUNT = 17;
197 * Constant representing Sunday.
199 public static final int SUNDAY = 1;
201 * Constant representing Monday.
203 public static final int MONDAY = 2;
205 * Constant representing Tuesday.
207 public static final int TUESDAY = 3;
209 * Constant representing Wednesday.
211 public static final int WEDNESDAY = 4;
213 * Constant representing Thursday.
215 public static final int THURSDAY = 5;
217 * Constant representing Friday.
219 public static final int FRIDAY = 6;
221 * Constant representing Saturday.
223 public static final int SATURDAY = 7;
226 * Constant representing January.
228 public static final int JANUARY = 0;
230 * Constant representing February.
232 public static final int FEBRUARY = 1;
234 * Constant representing March.
236 public static final int MARCH = 2;
238 * Constant representing April.
240 public static final int APRIL = 3;
242 * Constant representing May.
244 public static final int MAY = 4;
246 * Constant representing June.
248 public static final int JUNE = 5;
250 * Constant representing July.
252 public static final int JULY = 6;
254 * Constant representing August.
256 public static final int AUGUST = 7;
258 * Constant representing September.
260 public static final int SEPTEMBER = 8;
262 * Constant representing October.
264 public static final int OCTOBER = 9;
266 * Constant representing November.
268 public static final int NOVEMBER = 10;
270 * Constant representing December.
272 public static final int DECEMBER = 11;
274 * Constant representing Undecimber. This is an artificial name useful
275 * for lunar calendars.
277 public static final int UNDECIMBER = 12;
280 * Useful constant for 12-hour clock.
282 public static final int AM = 0;
284 * Useful constant for 12-hour clock.
286 public static final int PM = 1;
289 * The time fields. The array is indexed by the constants YEAR to
290 * DST_OFFSET.
291 * @serial
293 protected int[] fields = new int[FIELD_COUNT];
295 * The flags which tell if the fields above have a value.
296 * @serial
298 protected boolean[] isSet = new boolean[FIELD_COUNT];
300 * The time in milliseconds since the epoch.
301 * @serial
303 protected long time;
305 * Tells if the above field has a valid value.
306 * @serial
308 protected boolean isTimeSet;
310 * Tells if the fields have a valid value. This superseeds the isSet
311 * array.
312 * @serial
314 protected boolean areFieldsSet;
317 * The time zone of this calendar. Used by sub classes to do UTC / local
318 * time conversion. Sub classes can access this field with getTimeZone().
319 * @serial
321 private TimeZone zone;
324 * Specifies if the date/time interpretation should be lenient.
325 * If the flag is set, a date such as "February 30, 1996" will be
326 * treated as the 29th day after the February 1. If this flag
327 * is false, such dates will cause an exception.
328 * @serial
330 private boolean lenient;
333 * Sets what the first day of week is. This is used for
334 * WEEK_OF_MONTH and WEEK_OF_YEAR fields.
335 * @serial
337 private int firstDayOfWeek;
340 * Sets how many days are required in the first week of the year.
341 * If the first day of the year should be the first week you should
342 * set this value to 1. If the first week must be a full week, set
343 * it to 7.
344 * @serial
346 private int minimalDaysInFirstWeek;
349 * The version of the serialized data on the stream.
350 * <dl><dt>0 or not present</dt>
351 * <dd> JDK 1.1.5 or later.</dd>
352 * <dl><dt>1</dt>
353 * <dd>JDK 1.1.6 or later. This always writes a correct `time' value
354 * on the stream, as well as the other fields, to be compatible with
355 * earlier versions</dd>
356 * @since JDK1.1.6
357 * @serial
359 private int serialVersionOnStream = 1;
362 * XXX - I have not checked the compatibility. The documentation of
363 * the serialized-form is quite hairy...
365 static final long serialVersionUID = -1807547505821590642L;
368 * The name of the resource bundle. Used only by getBundle()
370 private static final String bundleName = "gnu.java.locale.Calendar";
373 * get resource bundle:
374 * The resources should be loaded via this method only. Iff an application
375 * uses this method, the resourcebundle is required.
377 private static ResourceBundle getBundle(Locale locale)
379 return ResourceBundle.getBundle(bundleName, locale);
383 * Constructs a new Calendar with the default time zone and the default
384 * locale.
386 protected Calendar()
388 this(TimeZone.getDefault(), Locale.getDefault());
392 * Constructs a new Calendar with the given time zone and the given
393 * locale.
394 * @param zone a time zone.
395 * @param locale a locale.
397 protected Calendar(TimeZone zone, Locale locale)
399 this.zone = zone;
400 lenient = true;
402 ResourceBundle rb = getBundle(locale);
404 firstDayOfWeek = ((Integer) rb.getObject("firstDayOfWeek")).intValue();
405 minimalDaysInFirstWeek =
406 ((Integer) rb.getObject("minimalDaysInFirstWeek")).intValue();
410 * Creates a calendar representing the actual time, using the default
411 * time zone and locale.
413 public static synchronized Calendar getInstance()
415 return getInstance(TimeZone.getDefault(), Locale.getDefault());
419 * Creates a calendar representing the actual time, using the given
420 * time zone and the default locale.
421 * @param zone a time zone.
423 public static synchronized Calendar getInstance(TimeZone zone)
425 return getInstance(zone, Locale.getDefault());
429 * Creates a calendar representing the actual time, using the default
430 * time zone and the given locale.
431 * @param locale a locale.
433 public static synchronized Calendar getInstance(Locale locale)
435 return getInstance(TimeZone.getDefault(), locale);
439 * Creates a calendar representing the actual time, using the given
440 * time zone and locale.
441 * @param zone a time zone.
442 * @param locale a locale.
444 public static synchronized Calendar getInstance(TimeZone zone, Locale locale)
446 String calendarClassName = null;
447 ResourceBundle rb = getBundle(locale);
448 calendarClassName = rb.getString("calendarClass");
449 if (calendarClassName != null)
453 Class calendarClass = Class.forName(calendarClassName);
454 if (Calendar.class.isAssignableFrom(calendarClass))
456 return (Calendar) calendarClass.getConstructor(
457 new Class[] { TimeZone.class, Locale.class}
458 ).newInstance(new Object[] {zone, locale} );
461 catch (ClassNotFoundException ex) {}
462 catch (IllegalAccessException ex) {}
463 catch (NoSuchMethodException ex) {}
464 catch (InstantiationException ex) {}
465 catch (InvocationTargetException ex) {}
466 // XXX should we ignore these errors or throw an exception ?
468 return new GregorianCalendar(zone, locale);
472 * Gets the set of locales for which a Calendar is available.
473 * @exception MissingResourceException if locale data couldn't be found.
474 * @return the set of locales.
476 public static synchronized Locale[] getAvailableLocales()
478 ResourceBundle rb = getBundle(new Locale("", ""));
479 return (Locale[]) rb.getObject("availableLocales");
483 * Converts the time field values (<code>fields</code>) to
484 * milliseconds since the epoch UTC (<code>time</code>). Override
485 * this method if you write your own Calendar. */
486 protected abstract void computeTime();
489 * Converts the milliseconds since the epoch UTC
490 * (<code>time</code>) to time fields
491 * (<code>fields</code>). Override this method if you write your
492 * own Calendar.
494 protected abstract void computeFields();
497 * Converts the time represented by this object to a
498 * <code>Date</code>-Object.
499 * @return the Date.
501 public final Date getTime()
503 if (!isTimeSet)
504 computeTime();
505 return new Date(time);
509 * Sets this Calendar's time to the given Date. All time fields
510 * are invalidated by this method.
512 public final void setTime(Date date)
514 setTimeInMillis(date.getTime());
518 * Returns the time represented by this Calendar.
519 * @return the time in milliseconds since the epoch.
520 * @specnote This was made public in 1.4.
522 public long getTimeInMillis()
524 if (!isTimeSet)
525 computeTime();
526 return time;
530 * Sets this Calendar's time to the given Time. All time fields
531 * are invalidated by this method.
532 * @param time the time in milliseconds since the epoch
533 * @specnote This was made public in 1.4.
535 public void setTimeInMillis(long time)
537 this.time = time;
538 isTimeSet = true;
539 computeFields();
543 * Gets the value of the specified field. They are recomputed
544 * if they are invalid.
545 * @param field the time field. One of the time field constants.
546 * @return the value of the specified field
548 * @specnote Not final since JDK 1.4
550 public int get(int field)
552 // If the requested field is invalid, force all fields to be recomputed.
553 if (!isSet[field])
554 areFieldsSet = false;
555 complete();
556 return fields[field];
560 * Gets the value of the specified field. This method doesn't
561 * recompute the fields, if they are invalid.
562 * @param field the time field. One of the time field constants.
563 * @return the value of the specified field, undefined if
564 * <code>areFieldsSet</code> or <code>isSet[field]</code> is false.
566 protected final int internalGet(int field)
568 return fields[field];
572 * Sets the time field with the given value. This does invalidate
573 * the time in milliseconds.
574 * @param field the time field. One of the time field constants
575 * @param value the value to be set.
577 * @specnote Not final since JDK 1.4
579 public void set(int field, int value)
581 isTimeSet = false;
582 fields[field] = value;
583 isSet[field] = true;
584 switch (field)
586 case YEAR:
587 case MONTH:
588 case DATE:
589 isSet[WEEK_OF_YEAR] = false;
590 isSet[DAY_OF_YEAR] = false;
591 isSet[WEEK_OF_MONTH] = false;
592 isSet[DAY_OF_WEEK] = false;
593 isSet[DAY_OF_WEEK_IN_MONTH] = false;
594 break;
595 case AM_PM:
596 isSet[HOUR_OF_DAY] = false;
597 break;
598 case HOUR_OF_DAY:
599 isSet[AM_PM] = false;
600 isSet[HOUR] = false;
601 break;
602 case HOUR:
603 isSet[HOUR_OF_DAY] = false;
604 break;
609 * Sets the fields for year, month, and date
610 * @param year the year.
611 * @param month the month, one of the constants JANUARY..UNDICEMBER.
612 * @param date the day of the month
614 public final void set(int year, int month, int date)
616 isTimeSet = false;
617 fields[YEAR] = year;
618 fields[MONTH] = month;
619 fields[DATE] = date;
620 isSet[YEAR] = isSet[MONTH] = isSet[DATE] = true;
621 isSet[WEEK_OF_YEAR] = false;
622 isSet[DAY_OF_YEAR] = false;
623 isSet[WEEK_OF_MONTH] = false;
624 isSet[DAY_OF_WEEK] = false;
625 isSet[DAY_OF_WEEK_IN_MONTH] = false;
629 * Sets the fields for year, month, date, hour, and minute
630 * @param year the year.
631 * @param month the month, one of the constants JANUARY..UNDICEMBER.
632 * @param date the day of the month
633 * @param hour the hour of day.
634 * @param minute the minute.
636 public final void set(int year, int month, int date, int hour, int minute)
638 set(year, month, date);
639 fields[HOUR_OF_DAY] = hour;
640 fields[MINUTE] = minute;
641 isSet[HOUR_OF_DAY] = isSet[MINUTE] = true;
642 isSet[AM_PM] = false;
643 isSet[HOUR] = false;
647 * Sets the fields for year, month, date, hour, and minute
648 * @param year the year.
649 * @param month the month, one of the constants JANUARY..UNDICEMBER.
650 * @param date the day of the month
651 * @param hour the hour of day.
652 * @param minute the minute.
653 * @param second the second.
655 public final void set(int year, int month, int date,
656 int hour, int minute, int second)
658 set(year, month, date, hour, minute);
659 fields[SECOND] = second;
660 isSet[SECOND] = true;
664 * Clears the values of all the time fields.
666 public final void clear()
668 isTimeSet = false;
669 areFieldsSet = false;
670 for (int i = 0; i < FIELD_COUNT; i++)
672 isSet[i] = false;
673 fields[i] = 0;
678 * Clears the values of the specified time field.
679 * @param field the time field. One of the time field constants.
681 public final void clear(int field)
683 isTimeSet = false;
684 areFieldsSet = false;
685 isSet[field] = false;
686 fields[field] = 0;
690 * Determines if the specified field has a valid value.
691 * @return true if the specified field has a value.
693 public final boolean isSet(int field)
695 return isSet[field];
699 * Fills any unset fields in the time field list
700 * @return true if the specified field has a value.
702 protected void complete()
704 if (!isTimeSet)
705 computeTime();
706 if (!areFieldsSet)
707 computeFields();
711 * Compares the given calendar with this.
712 * @param o the object to that we should compare.
713 * @return true, if the given object is a calendar, that represents
714 * the same time (but doesn't necessary have the same fields).
716 public boolean equals(Object o)
718 return (o instanceof Calendar)
719 && getTimeInMillis() == ((Calendar) o).getTimeInMillis();
723 * Returns a hash code for this calendar.
724 * @return a hash code, which fullfits the general contract of
725 * <code>hashCode()</code>
727 public int hashCode()
729 long time = getTimeInMillis();
730 return (int) ((time & 0xffffffffL) ^ (time >> 32));
734 * Compares the given calendar with this.
735 * @param o the object to that we should compare.
736 * @return true, if the given object is a calendar, and this calendar
737 * represents a smaller time than the calendar o.
738 * @exception ClassCastException if o is not an calendar.
739 * @since JDK1.2 you don't need to override this method
741 public boolean before(Object o)
743 return getTimeInMillis() < ((Calendar) o).getTimeInMillis();
747 * Compares the given calendar with this.
748 * @param o the object to that we should compare.
749 * @return true, if the given object is a calendar, and this calendar
750 * represents a bigger time than the calendar o.
751 * @exception ClassCastException if o is not an calendar.
752 * @since JDK1.2 you don't need to override this method
754 public boolean after(Object o)
756 return getTimeInMillis() > ((Calendar) o).getTimeInMillis();
760 * Adds the specified amount of time to the given time field. The
761 * amount may be negative to subtract the time. If the field overflows
762 * it does what you expect: Jan, 25 + 10 Days is Feb, 4.
763 * @param field the time field. One of the time field constants.
764 * @param amount the amount of time.
766 public abstract void add(int field, int amount);
769 * Rolls the specified time field up or down. This means add one
770 * to the specified field, but don't change the other fields. If
771 * the maximum for this field is reached, start over with the
772 * minimum value. <br>
774 * <strong>Note:</strong> There may be situation, where the other
775 * fields must be changed, e.g rolling the month on May, 31.
776 * The date June, 31 is automatically converted to July, 1.
777 * @param field the time field. One of the time field constants.
778 * @param up the direction, true for up, false for down.
780 public abstract void roll(int field, boolean up);
783 * Rolls up or down the specified time field by the given amount.
784 * A negative amount rolls down. The default implementation is
785 * call <code>roll(int, boolean)</code> for the specified amount.
787 * Subclasses should override this method to do more intuitiv things.
789 * @param field the time field. One of the time field constants.
790 * @param amount the amount to roll by, positive for rolling up,
791 * negative for rolling down.
792 * @since JDK1.2
794 public void roll(int field, int amount)
796 while (amount > 0)
798 roll(field, true);
799 amount--;
801 while (amount < 0)
803 roll(field, false);
804 amount++;
810 * Sets the time zone to the specified value.
811 * @param zone the new time zone
813 public void setTimeZone(TimeZone zone)
815 this.zone = zone;
819 * Gets the time zone of this calendar
820 * @return the current time zone.
822 public TimeZone getTimeZone()
824 return zone;
828 * Specifies if the date/time interpretation should be lenient.
829 * If the flag is set, a date such as "February 30, 1996" will be
830 * treated as the 29th day after the February 1. If this flag
831 * is false, such dates will cause an exception.
832 * @param lenient true, if the date should be interpreted linient,
833 * false if it should be interpreted strict.
835 public void setLenient(boolean lenient)
837 this.lenient = lenient;
841 * Tells if the date/time interpretation is lenient.
842 * @return true, if the date should be interpreted linient,
843 * false if it should be interpreted strict.
845 public boolean isLenient()
847 return lenient;
851 * Sets what the first day of week is. This is used for
852 * WEEK_OF_MONTH and WEEK_OF_YEAR fields.
853 * @param value the first day of week. One of SUNDAY to SATURDAY.
855 public void setFirstDayOfWeek(int value)
857 firstDayOfWeek = value;
861 * Gets what the first day of week is. This is used for
862 * WEEK_OF_MONTH and WEEK_OF_YEAR fields.
863 * @return the first day of week. One of SUNDAY to SATURDAY.
865 public int getFirstDayOfWeek()
867 return firstDayOfWeek;
871 * Sets how many days are required in the first week of the year.
872 * If the first day of the year should be the first week you should
873 * set this value to 1. If the first week must be a full week, set
874 * it to 7.
875 * @param value the minimal days required in the first week.
877 public void setMinimalDaysInFirstWeek(int value)
879 minimalDaysInFirstWeek = value;
883 * Gets how many days are required in the first week of the year.
884 * @return the minimal days required in the first week.
885 * @see #setMinimalDaysInFirstWeek
887 public int getMinimalDaysInFirstWeek()
889 return minimalDaysInFirstWeek;
893 * Gets the smallest value that is allowed for the specified field.
894 * @param field the time field. One of the time field constants.
895 * @return the smallest value.
897 public abstract int getMinimum(int field);
900 * Gets the biggest value that is allowed for the specified field.
901 * @param field the time field. One of the time field constants.
902 * @return the biggest value.
904 public abstract int getMaximum(int field);
908 * Gets the greatest minimum value that is allowed for the specified field.
909 * @param field the time field. One of the time field constants.
910 * @return the greatest minimum value.
912 public abstract int getGreatestMinimum(int field);
915 * Gets the smallest maximum value that is allowed for the
916 * specified field. For example this is 28 for DAY_OF_MONTH.
917 * @param field the time field. One of the time field constants.
918 * @return the least maximum value.
920 public abstract int getLeastMaximum(int field);
923 * Gets the actual minimum value that is allowed for the specified field.
924 * This value is dependent on the values of the other fields.
925 * @param field the time field. One of the time field constants.
926 * @return the actual minimum value.
927 * @since jdk1.2
929 // FIXME: XXX: Not abstract in JDK 1.2.
930 public abstract int getActualMinimum(int field);
933 * Gets the actual maximum value that is allowed for the specified field.
934 * This value is dependent on the values of the other fields.
935 * @param field the time field. One of the time field constants.
936 * @return the actual maximum value.
937 * @since jdk1.2
939 // FIXME: XXX: Not abstract in JDK 1.2.
940 public abstract int getActualMaximum(int field);
943 * Return a clone of this object.
945 public Object clone()
949 Calendar cal = (Calendar) super.clone();
950 cal.fields = (int[]) fields.clone();
951 cal.isSet = (boolean[])isSet.clone();
952 return cal;
954 catch (CloneNotSupportedException ex)
956 return null;
960 private final static String[] fieldNames = {
961 ",ERA=", ",YEAR=", ",MONTH=",
962 ",WEEK_OF_YEAR=", ",WEEK_OF_MONTH=",
963 ",DAY_OF_MONTH=", ",DAY_OF_YEAR=", ",DAY_OF_WEEK=",
964 ",DAY_OF_WEEK_IN_MONTH=",
965 ",AM_PM=", ",HOUR=", ",HOUR_OF_DAY=",
966 ",MINUTE=", ",SECOND=", ",MILLISECOND=",
967 ",ZONE_OFFSET=", ",DST_OFFSET="
972 * Returns a string representation of this object. It is mainly
973 * for debugging purposes and its content is implementation
974 * specific.
976 public String toString()
978 StringBuffer sb = new StringBuffer();
979 sb.append(getClass().getName()).append('[');
980 sb.append("time=");
981 if (isTimeSet)
982 sb.append(time);
983 else
984 sb.append("?");
985 sb.append(",zone=" + zone);
986 sb.append(",areFieldsSet=" + areFieldsSet);
987 for (int i = 0; i < FIELD_COUNT; i++)
989 sb.append(fieldNames[i]);
990 if (isSet[i])
991 sb.append(fields[i]);
992 else
993 sb.append("?");
995 sb.append(",lenient=").append(lenient);
996 sb.append(",firstDayOfWeek=").append(firstDayOfWeek);
997 sb.append(",minimalDaysInFirstWeek=").append(minimalDaysInFirstWeek);
998 sb.append("]");
999 return sb.toString();
1003 * Saves the state of the object to the stream. Ideally we would
1004 * only write the time field, but we need to be compatible with
1005 * earlier versions. <br>
1007 * This doesn't write the JDK1.1 field nextStamp to the stream, as
1008 * I don't know what it is good for, and because the documentation
1009 * says, that it could be omitted. */
1010 private void writeObject(ObjectOutputStream stream) throws IOException
1012 if (!isTimeSet)
1013 computeTime();
1014 stream.defaultWriteObject();
1018 * Reads the object back from stream (deserialization).
1020 private void readObject(ObjectInputStream stream)
1021 throws IOException, ClassNotFoundException
1023 stream.defaultReadObject();
1024 if (!isTimeSet)
1025 computeTime();
1027 if (serialVersionOnStream > 1)
1029 // This is my interpretation of the serial number:
1030 // Sun wants to remove all fields from the stream someday
1031 // and will then increase the serialVersion number again.
1032 // We prepare to be compatible.
1034 fields = new int[FIELD_COUNT];
1035 isSet = new boolean[FIELD_COUNT];
1036 areFieldsSet = false;