source: trunk/src/gcc/libjava/java/util/Calendar.java@ 2

Last change on this file since 2 was 2, checked in by bird, 23 years ago

Initial revision

  • Property cvs2svn:cvs-rev set to 1.1
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 29.1 KB
Line 
1/* java.util.Calendar
2 Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
3
4This file is part of GNU Classpath.
5
6GNU Classpath is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU Classpath is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Classpath; see the file COPYING. If not, write to the
18Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
1902111-1307 USA.
20
21Linking this library statically or dynamically with other modules is
22making a combined work based on this library. Thus, the terms and
23conditions of the GNU General Public License cover the whole
24combination.
25
26As a special exception, the copyright holders of this library give you
27permission to link this library with independent modules to produce an
28executable, regardless of the license terms of these independent
29modules, and to copy and distribute the resulting executable under
30terms of your choice, provided that you also meet, for each linked
31independent module, the terms and conditions of the license of that
32module. An independent module is a module which is not derived from
33or based on this library. If you modify this library, you may extend
34this exception to your version of the library, but you are not
35obligated to do so. If you do not wish to do so, delete this
36exception statement from your version. */
37
38
39package java.util;
40import java.lang.reflect.InvocationTargetException;
41import java.io.*;
42
43/**
44 * This class is an abstract base class for Calendars, which can be
45 * used to convert between <code>Date</code> objects and a set of
46 * integer fields which represent <code>YEAR</code>,
47 * <code>MONTH</code>, <code>DAY</code>, etc. The <code>Date</code>
48 * object represents a time in milliseconds since the Epoch. <br>
49 *
50 * This class is locale sensitive. To get the Object matching the
51 * current locale you can use <code>getInstance</code>. You can even provide
52 * a locale or a timezone. <code>getInstance</code> returns currently
53 * a <code>GregorianCalendar</code> for the current date. <br>
54 *
55 * If you want to convert a date from the Year, Month, Day, DayOfWeek,
56 * etc. Representation to a <code>Date</code>-Object, you can create
57 * a new Calendar with <code>getInstance()</code>,
58 * <code>clear()</code> all fields, <code>set(int,int)</code> the
59 * fields you need and convert it with <code>getTime()</code>. <br>
60 *
61 * If you want to convert a <code>Date</code>-object to the Calendar
62 * representation, create a new Calendar, assign the
63 * <code>Date</code>-Object with <code>setTime()</code>, and read the
64 * fields with <code>get(int)</code>. <br>
65 *
66 * When computing the date from time fields, it may happen, that there
67 * are either two few fields set, or some fields are inconsistent. This
68 * cases will handled in a calendar specific way. Missing fields are
69 * replaced by the fields of the epoch: 1970 January 1 00:00. <br>
70 *
71 * To understand, how the day of year is computed out of the fields
72 * look at the following table. It is traversed from top to bottom,
73 * and for the first line all fields are set, that line is used to
74 * compute the day. <br>
75 *
76 * <pre>
77 * month + day_of_month
78 * month + week_of_month + day_of_week
79 * month + day_of_week_of_month + day_of_week
80 * day_of_year
81 * day_of_week + week_of_year
82 * </pre>
83 *
84 * The hour_of_day-field takes precedence over the ampm and
85 * hour_of_ampm fields. <br>
86 *
87 * <STRONG>Note:</STRONG> This can differ for non-Gregorian calendar. <br>
88 *
89 * To convert a calendar to a human readable form and vice versa, use
90 * the <code>java.text.DateFormat</code> class. <br>
91 *
92 * Other useful things you can do with an calendar, is
93 * <code>roll</code>ing fields (that means increase/decrease a
94 * specific field by one, propagating overflows), or
95 * <code>add</code>ing/substracting a fixed amount to a field.
96 *
97 * @see Date
98 * @see GregorianCalendar
99 * @see TimeZone
100 * @see java.text.DateFormat
101 */
102public abstract class Calendar implements Serializable, Cloneable
103{
104 /**
105 * Constant representing the era time field.
106 */
107 public static final int ERA = 0;
108 /**
109 * Constant representing the year time field.
110 */
111 public static final int YEAR = 1;
112 /**
113 * Constant representing the month time field. This field
114 * should contain one of the JANUARY,...,DECEMBER constants below.
115 */
116 public static final int MONTH = 2;
117 /**
118 * Constant representing the week of the year field.
119 * @see #setFirstDayOfWeek(int)
120 */
121 public static final int WEEK_OF_YEAR = 3;
122 /**
123 * Constant representing the week of the month time field.
124 * @see #setFirstDayOfWeek(int)
125 */
126 public static final int WEEK_OF_MONTH = 4;
127 /**
128 * Constant representing the day time field, synonym for DAY_OF_MONTH.
129 */
130 public static final int DATE = 5;
131 /**
132 * Constant representing the day time field.
133 */
134 public static final int DAY_OF_MONTH = 5;
135 /**
136 * Constant representing the day of year time field. This is
137 * 1 for the first day in month.
138 */
139 public static final int DAY_OF_YEAR = 6;
140 /**
141 * Constant representing the day of week time field. This field
142 * should contain one of the SUNDAY,...,SATURDAY constants below.
143 */
144 public static final int DAY_OF_WEEK = 7;
145 /**
146 * Constant representing the day-of-week-in-month field. For
147 * instance this field contains 2 for the second thursday in a
148 * month. If you give a negative number here, the day will count
149 * from the end of the month.
150 */
151 public static final int DAY_OF_WEEK_IN_MONTH = 8;
152 /**
153 * Constant representing the part of the day for 12-hour clock. This
154 * should be one of AM or PM.
155 */
156 public static final int AM_PM = 9;
157 /**
158 * Constant representing the hour time field for 12-hour clock.
159 */
160 public static final int HOUR = 10;
161 /**
162 * Constant representing the hour of day time field for 24-hour clock.
163 */
164 public static final int HOUR_OF_DAY = 11;
165 /**
166 * Constant representing the minute of hour time field.
167 */
168 public static final int MINUTE = 12;
169 /**
170 * Constant representing the second time field.
171 */
172 public static final int SECOND = 13;
173 /**
174 * Constant representing the millisecond time field.
175 */
176 public static final int MILLISECOND = 14;
177 /**
178 * Constant representing the time zone offset time field for the
179 * time given in the other fields. It is measured in
180 * milliseconds. The default is the offset of the time zone.
181 */
182 public static final int ZONE_OFFSET = 15;
183 /**
184 * Constant representing the daylight saving time offset in
185 * milliseconds. The default is the value given by the time zone.
186 */
187 public static final int DST_OFFSET = 16;
188 /**
189 * Number of time fields.
190 */
191 public static final int FIELD_COUNT = 17;
192
193 /**
194 * Constant representing Sunday.
195 */
196 public static final int SUNDAY = 1;
197 /**
198 * Constant representing Monday.
199 */
200 public static final int MONDAY = 2;
201 /**
202 * Constant representing Tuesday.
203 */
204 public static final int TUESDAY = 3;
205 /**
206 * Constant representing Wednesday.
207 */
208 public static final int WEDNESDAY = 4;
209 /**
210 * Constant representing Thursday.
211 */
212 public static final int THURSDAY = 5;
213 /**
214 * Constant representing Friday.
215 */
216 public static final int FRIDAY = 6;
217 /**
218 * Constant representing Saturday.
219 */
220 public static final int SATURDAY = 7;
221
222 /**
223 * Constant representing January.
224 */
225 public static final int JANUARY = 0;
226 /**
227 * Constant representing February.
228 */
229 public static final int FEBRUARY = 1;
230 /**
231 * Constant representing March.
232 */
233 public static final int MARCH = 2;
234 /**
235 * Constant representing April.
236 */
237 public static final int APRIL = 3;
238 /**
239 * Constant representing May.
240 */
241 public static final int MAY = 4;
242 /**
243 * Constant representing June.
244 */
245 public static final int JUNE = 5;
246 /**
247 * Constant representing July.
248 */
249 public static final int JULY = 6;
250 /**
251 * Constant representing August.
252 */
253 public static final int AUGUST = 7;
254 /**
255 * Constant representing September.
256 */
257 public static final int SEPTEMBER = 8;
258 /**
259 * Constant representing October.
260 */
261 public static final int OCTOBER = 9;
262 /**
263 * Constant representing November.
264 */
265 public static final int NOVEMBER = 10;
266 /**
267 * Constant representing December.
268 */
269 public static final int DECEMBER = 11;
270 /**
271 * Constant representing Undecimber. This is an artificial name useful
272 * for lunar calendars.
273 */
274 public static final int UNDECIMBER = 12;
275
276 /**
277 * Useful constant for 12-hour clock.
278 */
279 public static final int AM = 0;
280 /**
281 * Useful constant for 12-hour clock.
282 */
283 public static final int PM = 1;
284
285 /**
286 * The time fields. The array is indexed by the constants YEAR to
287 * DST_OFFSET.
288 * @serial
289 */
290 protected int[] fields = new int[FIELD_COUNT];
291 /**
292 * The flags which tell if the fields above have a value.
293 * @serial
294 */
295 protected boolean[] isSet = new boolean[FIELD_COUNT];
296 /**
297 * The time in milliseconds since the epoch.
298 * @serial
299 */
300 protected long time;
301 /**
302 * Tells if the above field has a valid value.
303 * @serial
304 */
305 protected boolean isTimeSet;
306 /**
307 * Tells if the fields have a valid value. This superseeds the isSet
308 * array.
309 * @serial
310 */
311 protected boolean areFieldsSet;
312
313 /**
314 * The time zone of this calendar. Used by sub classes to do UTC / local
315 * time conversion. Sub classes can access this field with getTimeZone().
316 * @serial
317 */
318 private TimeZone zone;
319
320 /**
321 * Specifies if the date/time interpretation should be lenient.
322 * If the flag is set, a date such as "February 30, 1996" will be
323 * treated as the 29th day after the February 1. If this flag
324 * is false, such dates will cause an exception.
325 * @serial
326 */
327 private boolean lenient;
328
329 /**
330 * Sets what the first day of week is. This is used for
331 * WEEK_OF_MONTH and WEEK_OF_YEAR fields.
332 * @serial
333 */
334 private int firstDayOfWeek;
335
336 /**
337 * Sets how many days are required in the first week of the year.
338 * If the first day of the year should be the first week you should
339 * set this value to 1. If the first week must be a full week, set
340 * it to 7.
341 * @serial
342 */
343 private int minimalDaysInFirstWeek;
344
345 /**
346 * The version of the serialized data on the stream.
347 * <dl><dt>0 or not present</dt>
348 * <dd> JDK 1.1.5 or later.</dd>
349 * <dl><dt>1</dt>
350 * <dd>JDK 1.1.6 or later. This always writes a correct `time' value
351 * on the stream, as well as the other fields, to be compatible with
352 * earlier versions</dd>
353 * @since JDK1.1.6
354 * @serial
355 */
356 private int serialVersionOnStream = 1;
357
358 /**
359 * XXX - I have not checked the compatibility. The documentation of
360 * the serialized-form is quite hairy...
361 */
362 static final long serialVersionUID = -1807547505821590642L;
363
364 /**
365 * The name of the resource bundle.
366 */
367 private static final String bundleName = "gnu.java.locale.Calendar";
368
369 /**
370 * Constructs a new Calendar with the default time zone and the default
371 * locale.
372 */
373 protected Calendar()
374 {
375 this(TimeZone.getDefault(), Locale.getDefault());
376 }
377
378 /**
379 * Constructs a new Calendar with the given time zone and the given
380 * locale.
381 * @param zone a time zone.
382 * @param locale a locale.
383 */
384 protected Calendar(TimeZone zone, Locale locale)
385 {
386 this.zone = zone;
387 lenient = true;
388
389 ResourceBundle rb = ResourceBundle.getBundle(bundleName, locale);
390
391 firstDayOfWeek = ((Integer) rb.getObject("firstDayOfWeek")).intValue();
392 minimalDaysInFirstWeek =
393 ((Integer) rb.getObject("minimalDaysInFirstWeek")).intValue();
394 }
395
396 /**
397 * Creates a calendar representing the actual time, using the default
398 * time zone and locale.
399 */
400 public static synchronized Calendar getInstance()
401 {
402 return getInstance(TimeZone.getDefault(), Locale.getDefault());
403 }
404
405 /**
406 * Creates a calendar representing the actual time, using the given
407 * time zone and the default locale.
408 * @param zone a time zone.
409 */
410 public static synchronized Calendar getInstance(TimeZone zone)
411 {
412 return getInstance(zone, Locale.getDefault());
413 }
414
415 /**
416 * Creates a calendar representing the actual time, using the default
417 * time zone and the given locale.
418 * @param locale a locale.
419 */
420 public static synchronized Calendar getInstance(Locale locale)
421 {
422 return getInstance(TimeZone.getDefault(), locale);
423 }
424
425 /**
426 * Creates a calendar representing the actual time, using the given
427 * time zone and locale.
428 * @param zone a time zone.
429 * @param locale a locale.
430 */
431 public static synchronized Calendar getInstance(TimeZone zone, Locale locale)
432 {
433 String calendarClassName = null;
434 ResourceBundle rb = ResourceBundle.getBundle(bundleName, locale);
435 calendarClassName = rb.getString("calendarClass");
436 if (calendarClassName != null)
437 {
438 try
439 {
440 Class calendarClass = Class.forName(calendarClassName);
441 if (Calendar.class.isAssignableFrom(calendarClass))
442 {
443 return (Calendar) calendarClass.getConstructor(
444 new Class[] { TimeZone.class, Locale.class}
445 ).newInstance(new Object[] {zone, locale} );
446 }
447 }
448 catch (ClassNotFoundException ex) {}
449 catch (IllegalAccessException ex) {}
450 catch (NoSuchMethodException ex) {}
451 catch (InstantiationException ex) {}
452 catch (InvocationTargetException ex) {}
453 // XXX should we ignore these errors or throw an exception ?
454 }
455 return new GregorianCalendar(zone, locale);
456 }
457
458 /**
459 * Gets the set of locales for which a Calendar is available.
460 * @exception MissingResourceException if locale data couldn't be found.
461 * @return the set of locales.
462 */
463 public static synchronized Locale[] getAvailableLocales()
464 {
465 ResourceBundle rb = ResourceBundle.getBundle(bundleName,
466 new Locale("", ""));
467 return (Locale[]) rb.getObject("availableLocales");
468 }
469
470 /**
471 * Converts the time field values (<code>fields</code>) to
472 * milliseconds since the epoch UTC (<code>time</code>). Override
473 * this method if you write your own Calendar. */
474 protected abstract void computeTime();
475
476 /**
477 * Converts the milliseconds since the epoch UTC
478 * (<code>time</code>) to time fields
479 * (<code>fields</code>). Override this method if you write your
480 * own Calendar.
481 */
482 protected abstract void computeFields();
483
484 /**
485 * Converts the time represented by this object to a
486 * <code>Date</code>-Object.
487 * @return the Date.
488 */
489 public final Date getTime()
490 {
491 if (!isTimeSet)
492 computeTime();
493 return new Date(time);
494 }
495
496 /**
497 * Sets this Calendar's time to the given Date. All time fields
498 * are invalidated by this method.
499 */
500 public final void setTime(Date date)
501 {
502 setTimeInMillis(date.getTime());
503 }
504
505 /**
506 * Returns the time represented by this Calendar.
507 * @return the time in milliseconds since the epoch.
508 */
509 protected long getTimeInMillis()
510 {
511 if (!isTimeSet)
512 computeTime();
513 return time;
514 }
515
516 /**
517 * Sets this Calendar's time to the given Time. All time fields
518 * are invalidated by this method.
519 * @param time the time in milliseconds since the epoch
520 */
521 protected void setTimeInMillis(long time)
522 {
523 this.time = time;
524 isTimeSet = true;
525 computeFields();
526 }
527
528 /**
529 * Gets the value of the specified field. They are recomputed
530 * if they are invalid.
531 * @param field the time field. One of the time field constants.
532 * @return the value of the specified field
533 */
534 public final int get(int field)
535 {
536 // If the requested field is invalid, force all fields to be recomputed.
537 if (!isSet[field])
538 areFieldsSet = false;
539 complete();
540 return fields[field];
541 }
542
543 /**
544 * Gets the value of the specified field. This method doesn't
545 * recompute the fields, if they are invalid.
546 * @param field the time field. One of the time field constants.
547 * @return the value of the specified field, undefined if
548 * <code>areFieldsSet</code> or <code>isSet[field]</code> is false.
549 */
550 protected final int internalGet(int field)
551 {
552 return fields[field];
553 }
554
555 /**
556 * Sets the time field with the given value. This does invalidate
557 * the time in milliseconds.
558 * @param field the time field. One of the time field constants
559 * @param value the value to be set.
560 */
561 public final void set(int field, int value)
562 {
563 isTimeSet = false;
564 fields[field] = value;
565 isSet[field] = true;
566 switch (field)
567 {
568 case YEAR:
569 case MONTH:
570 case DATE:
571 isSet[WEEK_OF_YEAR] = false;
572 isSet[DAY_OF_YEAR] = false;
573 isSet[WEEK_OF_MONTH] = false;
574 isSet[DAY_OF_WEEK] = false;
575 isSet[DAY_OF_WEEK_IN_MONTH] = false;
576 break;
577 case AM_PM:
578 isSet[HOUR_OF_DAY] = false;
579 break;
580 case HOUR_OF_DAY:
581 isSet[AM_PM] = false;
582 isSet[HOUR] = false;
583 break;
584 case HOUR:
585 isSet[HOUR_OF_DAY] = false;
586 break;
587 }
588 }
589
590 /**
591 * Sets the fields for year, month, and date
592 * @param year the year.
593 * @param month the month, one of the constants JANUARY..UNDICEMBER.
594 * @param date the day of the month
595 */
596 public final void set(int year, int month, int date)
597 {
598 isTimeSet = false;
599 fields[YEAR] = year;
600 fields[MONTH] = month;
601 fields[DATE] = date;
602 isSet[YEAR] = isSet[MONTH] = isSet[DATE] = true;
603 isSet[WEEK_OF_YEAR] = false;
604 isSet[DAY_OF_YEAR] = false;
605 isSet[WEEK_OF_MONTH] = false;
606 isSet[DAY_OF_WEEK] = false;
607 isSet[DAY_OF_WEEK_IN_MONTH] = false;
608 }
609
610 /**
611 * Sets the fields for year, month, date, hour, and minute
612 * @param year the year.
613 * @param month the month, one of the constants JANUARY..UNDICEMBER.
614 * @param date the day of the month
615 * @param hour the hour of day.
616 * @param minute the minute.
617 */
618 public final void set(int year, int month, int date, int hour, int minute)
619 {
620 set(year, month, date);
621 fields[HOUR_OF_DAY] = hour;
622 fields[MINUTE] = minute;
623 isSet[HOUR_OF_DAY] = isSet[MINUTE] = true;
624 isSet[AM_PM] = false;
625 isSet[HOUR] = false;
626 }
627
628 /**
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.
635 * @param second the second.
636 */
637 public final void set(int year, int month, int date,
638 int hour, int minute, int second)
639 {
640 set(year, month, date, hour, minute);
641 fields[SECOND] = second;
642 isSet[SECOND] = true;
643 }
644
645 /**
646 * Clears the values of all the time fields.
647 */
648 public final void clear()
649 {
650 isTimeSet = false;
651 areFieldsSet = false;
652 for (int i = 0; i < FIELD_COUNT; i++)
653 {
654 isSet[i] = false;
655 fields[i] = 0;
656 }
657 }
658
659 /**
660 * Clears the values of the specified time field.
661 * @param field the time field. One of the time field constants.
662 */
663 public final void clear(int field)
664 {
665 isTimeSet = false;
666 areFieldsSet = false;
667 isSet[field] = false;
668 fields[field] = 0;
669 }
670
671 /**
672 * Determines if the specified field has a valid value.
673 * @return true if the specified field has a value.
674 */
675 public final boolean isSet(int field)
676 {
677 return isSet[field];
678 }
679
680 /**
681 * Fills any unset fields in the time field list
682 * @return true if the specified field has a value.
683 */
684 protected void complete()
685 {
686 if (!isTimeSet)
687 computeTime();
688 if (!areFieldsSet)
689 computeFields();
690 }
691
692 /**
693 * Compares the given calendar with this.
694 * @param o the object to that we should compare.
695 * @return true, if the given object is a calendar, that represents
696 * the same time (but doesn't necessary have the same fields).
697 */
698 public boolean equals(Object o)
699 {
700 return (o instanceof Calendar)
701 && getTimeInMillis() == ((Calendar) o).getTimeInMillis();
702 }
703
704 /**
705 * Returns a hash code for this calendar.
706 * @return a hash code, which fullfits the general contract of
707 * <code>hashCode()</code>
708 */
709 public int hashCode()
710 {
711 long time = getTimeInMillis();
712 return (int) ((time & 0xffffffffL) ^ (time >> 32));
713 }
714
715 /**
716 * Compares the given calendar with this.
717 * @param o the object to that we should compare.
718 * @return true, if the given object is a calendar, and this calendar
719 * represents a smaller time than the calendar o.
720 * @exception ClassCastException if o is not an calendar.
721 * @since JDK1.2 you don't need to override this method
722 */
723 public boolean before(Object o)
724 {
725 return getTimeInMillis() < ((Calendar) o).getTimeInMillis();
726 }
727
728 /**
729 * Compares the given calendar with this.
730 * @param o the object to that we should compare.
731 * @return true, if the given object is a calendar, and this calendar
732 * represents a bigger time than the calendar o.
733 * @exception ClassCastException if o is not an calendar.
734 * @since JDK1.2 you don't need to override this method
735 */
736 public boolean after(Object o)
737 {
738 return getTimeInMillis() > ((Calendar) o).getTimeInMillis();
739 }
740
741 /**
742 * Adds the specified amount of time to the given time field. The
743 * amount may be negative to subtract the time. If the field overflows
744 * it does what you expect: Jan, 25 + 10 Days is Feb, 4.
745 * @param field the time field. One of the time field constants.
746 * @param amount the amount of time.
747 */
748 public abstract void add(int field, int amount);
749
750 /**
751 * Rolls the specified time field up or down. This means add one
752 * to the specified field, but don't change the other fields. If
753 * the maximum for this field is reached, start over with the
754 * minimum value. <br>
755 *
756 * <strong>Note:</strong> There may be situation, where the other
757 * fields must be changed, e.g rolling the month on May, 31.
758 * The date June, 31 is automatically converted to July, 1.
759 * @param field the time field. One of the time field constants.
760 * @param up the direction, true for up, false for down.
761 */
762 public abstract void roll(int field, boolean up);
763
764 /**
765 * Rolls up or down the specified time field by the given amount.
766 * A negative amount rolls down. The default implementation is
767 * call <code>roll(int, boolean)</code> for the specified amount.
768 *
769 * Subclasses should override this method to do more intuitiv things.
770 *
771 * @param field the time field. One of the time field constants.
772 * @param amount the amount to roll by, positive for rolling up,
773 * negative for rolling down.
774 * @since JDK1.2
775 */
776 public void roll(int field, int amount)
777 {
778 while (amount > 0)
779 {
780 roll(field, true);
781 amount--;
782 }
783 while (amount < 0)
784 {
785 roll(field, false);
786 amount++;
787 }
788 }
789
790
791 /**
792 * Sets the time zone to the specified value.
793 * @param zone the new time zone
794 */
795 public void setTimeZone(TimeZone zone)
796 {
797 this.zone = zone;
798 }
799
800 /**
801 * Gets the time zone of this calendar
802 * @return the current time zone.
803 */
804 public TimeZone getTimeZone()
805 {
806 return zone;
807 }
808
809 /**
810 * Specifies if the date/time interpretation should be lenient.
811 * If the flag is set, a date such as "February 30, 1996" will be
812 * treated as the 29th day after the February 1. If this flag
813 * is false, such dates will cause an exception.
814 * @param lenient true, if the date should be interpreted linient,
815 * false if it should be interpreted strict.
816 */
817 public void setLenient(boolean lenient)
818 {
819 this.lenient = lenient;
820 }
821
822 /**
823 * Tells if the date/time interpretation is lenient.
824 * @return true, if the date should be interpreted linient,
825 * false if it should be interpreted strict.
826 */
827 public boolean isLenient()
828 {
829 return lenient;
830 }
831
832 /**
833 * Sets what the first day of week is. This is used for
834 * WEEK_OF_MONTH and WEEK_OF_YEAR fields.
835 * @param value the first day of week. One of SUNDAY to SATURDAY.
836 */
837 public void setFirstDayOfWeek(int value)
838 {
839 firstDayOfWeek = value;
840 }
841
842 /**
843 * Gets what the first day of week is. This is used for
844 * WEEK_OF_MONTH and WEEK_OF_YEAR fields.
845 * @return the first day of week. One of SUNDAY to SATURDAY.
846 */
847 public int getFirstDayOfWeek()
848 {
849 return firstDayOfWeek;
850 }
851
852 /**
853 * Sets how many days are required in the first week of the year.
854 * If the first day of the year should be the first week you should
855 * set this value to 1. If the first week must be a full week, set
856 * it to 7.
857 * @param value the minimal days required in the first week.
858 */
859 public void setMinimalDaysInFirstWeek(int value)
860 {
861 minimalDaysInFirstWeek = value;
862 }
863
864 /**
865 * Gets how many days are required in the first week of the year.
866 * @return the minimal days required in the first week.
867 * @see #setMinimalDaysInFirstWeek
868 */
869 public int getMinimalDaysInFirstWeek()
870 {
871 return minimalDaysInFirstWeek;
872 }
873
874 /**
875 * Gets the smallest value that is allowed for the specified field.
876 * @param field the time field. One of the time field constants.
877 * @return the smallest value.
878 */
879 public abstract int getMinimum(int field);
880
881 /**
882 * Gets the biggest value that is allowed for the specified field.
883 * @param field the time field. One of the time field constants.
884 * @return the biggest value.
885 */
886 public abstract int getMaximum(int field);
887
888
889 /**
890 * Gets the greatest minimum value that is allowed for the specified field.
891 * @param field the time field. One of the time field constants.
892 * @return the greatest minimum value.
893 */
894 public abstract int getGreatestMinimum(int field);
895
896 /**
897 * Gets the smallest maximum value that is allowed for the
898 * specified field. For example this is 28 for DAY_OF_MONTH.
899 * @param field the time field. One of the time field constants.
900 * @return the least maximum value.
901 */
902 public abstract int getLeastMaximum(int field);
903
904 /**
905 * Gets the actual minimum value that is allowed for the specified field.
906 * This value is dependent on the values of the other fields.
907 * @param field the time field. One of the time field constants.
908 * @return the actual minimum value.
909 * @since jdk1.2
910 */
911 // FIXME: XXX: Not abstract in JDK 1.2.
912 public abstract int getActualMinimum(int field);
913
914 /**
915 * Gets the actual maximum value that is allowed for the specified field.
916 * This value is dependent on the values of the other fields.
917 * @param field the time field. One of the time field constants.
918 * @return the actual maximum value.
919 * @since jdk1.2
920 */
921 // FIXME: XXX: Not abstract in JDK 1.2.
922 public abstract int getActualMaximum(int field);
923
924 /**
925 * Return a clone of this object.
926 */
927 public Object clone()
928 {
929 try
930 {
931 Calendar cal = (Calendar) super.clone();
932 cal.fields = (int[]) fields.clone();
933 cal.isSet = (boolean[])isSet.clone();
934 return cal;
935 }
936 catch (CloneNotSupportedException ex)
937 {
938 return null;
939 }
940 }
941
942 private final static String[] fieldNames = {
943 ",ERA=", ",YEAR=", ",MONTH=",
944 ",WEEK_OF_YEAR=", ",WEEK_OF_MONTH=",
945 ",DAY_OF_MONTH=", ",DAY_OF_YEAR=", ",DAY_OF_WEEK=",
946 ",DAY_OF_WEEK_IN_MONTH=",
947 ",AM_PM=", ",HOUR=", ",HOUR_OF_DAY=",
948 ",MINUTE=", ",SECOND=", ",MILLISECOND=",
949 ",ZONE_OFFSET=", ",DST_OFFSET="
950 };
951
952
953 /**
954 * Returns a string representation of this object. It is mainly
955 * for debugging purposes and its content is implementation
956 * specific.
957 */
958 public String toString()
959 {
960 StringBuffer sb = new StringBuffer();
961 sb.append(getClass().getName()).append('[');
962 sb.append("time=");
963 if (isTimeSet)
964 sb.append(time);
965 else
966 sb.append("?");
967 sb.append(",zone=" + zone);
968 sb.append(",areFieldsSet=" + areFieldsSet);
969 for (int i = 0; i < FIELD_COUNT; i++)
970 {
971 sb.append(fieldNames[i]);
972 if (isSet[i])
973 sb.append(fields[i]);
974 else
975 sb.append("?");
976 }
977 sb.append(",lenient=").append(lenient);
978 sb.append(",firstDayOfWeek=").append(firstDayOfWeek);
979 sb.append(",minimalDaysInFirstWeek=").append(minimalDaysInFirstWeek);
980 sb.append("]");
981 return sb.toString();
982 }
983
984 /**
985 * Saves the state of the object to the stream. Ideally we would
986 * only write the time field, but we need to be compatible with
987 * earlier versions. <br>
988 *
989 * This doesn't write the JDK1.1 field nextStamp to the stream, as
990 * I don't know what it is good for, and because the documentation
991 * says, that it could be omitted. */
992 private void writeObject(ObjectOutputStream stream) throws IOException
993 {
994 if (!isTimeSet)
995 computeTime();
996 stream.defaultWriteObject();
997 }
998
999 /**
1000 * Reads the object back from stream (deserialization).
1001 */
1002 private void readObject(ObjectInputStream stream)
1003 throws IOException, ClassNotFoundException
1004 {
1005 stream.defaultReadObject();
1006 if (!isTimeSet)
1007 computeTime();
1008
1009 if (serialVersionOnStream > 1)
1010 {
1011 // This is my interpretation of the serial number:
1012 // Sun wants to remove all fields from the stream someday
1013 // and will then increase the serialVersion number again.
1014 // We prepare to be compatible.
1015
1016 fields = new int[FIELD_COUNT];
1017 isSet = new boolean[FIELD_COUNT];
1018 areFieldsSet = false;
1019 }
1020 }
1021}
Note: See TracBrowser for help on using the repository browser.