1 /* Copyright (C) 1998, 1999, 2000 Free Software Foundation
3 This file is part of libgcj.
5 This software is copyrighted work licensed under the terms of the
6 Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
12 * @author Per Bothner <bothner@cygnus.com>
13 * @date October 24, 1998.
16 /* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3,
17 * and "The Java Language Specification", ISBN 0-201-63451-1.
18 * Status: "leniency" is not handled, and neither is roll-over in
19 * add and roll. This is partly because of unclear specification.
20 * hashCode has no spec.
23 public class GregorianCalendar extends Calendar {
24 public static final int BC = 0;
25 public static final int AD = 1;
27 // The fields are as specified in Sun's "Serialized Form"
28 // in the JDK 1.2 beta 4 API specification.
29 // Value from a simple test program (getGregorianChange.getTime()).
30 long gregorianCutover = -12219292800000L;
32 private final static int[] mins = {
37 0 /* WEEK_OF_MONTH */,
41 -1 /* DAY_OF_WEEK_IN_MONTH */,
48 -43200000 /* ZONE_OFFSET */,
52 private final static int[] maxs = {
56 54 /* WEEK_OF_YEAR */,
57 6 /* WEEK_OF_MONTH */,
59 366 /* DAY_OF_YEAR */,
61 6 /* DAY_OF_WEEK_IN_MONTH */,
67 999 /* MILLISECOND */,
68 43200000 /* ZONE_OFFSET */,
69 3600000 /* DST_OFFSET */
72 private final static int[] leastMaximums = {
76 53 /* WEEK_OF_YEAR */,
77 6 /* WEEK_OF_MONTH */,
79 365 /* DAY_OF_YEAR */,
81 4 /* DAY_OF_WEEK_IN_MONTH */,
87 999 /* MILLISECOND */,
88 43200000 /* ZONE_OFFSET */,
89 3600000 /* DST_OFFSET */
92 private static final long serialVersionUID = -8125100834729963327L;
94 public GregorianCalendar ()
96 this(TimeZone.getDefault (), Locale.getDefault ());
99 public GregorianCalendar (TimeZone zone)
101 this (zone, Locale.getDefault ());
104 public GregorianCalendar (Locale locale)
106 this (TimeZone.getDefault (), locale);
109 public GregorianCalendar (TimeZone zone, Locale locale)
111 super (zone, locale);
115 public GregorianCalendar (int year, int month, int date)
119 set (year, month, date);
122 public GregorianCalendar (int year, int month, int date,
123 int hour, int minute)
127 set (year, month, date, hour, minute);
130 public GregorianCalendar (int year, int month, int date,
131 int hour, int minute, int second)
135 set (year, month, date, hour, minute, second);
138 private final void setDefaultTime ()
140 setTimeInMillis (System.currentTimeMillis());
143 public int getMinimum(int calfield) { return mins[calfield]; }
144 public int getGreatestMinimum(int calfield) { return mins[calfield]; }
145 public int getMaximum(int calfield) { return maxs[calfield]; }
146 public int getLeastMaximum(int calfield) { return leastMaximums[calfield]; }
148 protected native void computeFields();
150 protected native void computeTime();
152 public void add (int fld, int amount)
154 if (fld >= ZONE_OFFSET)
155 throw new IllegalArgumentException("bad field to add");
156 fields[fld] += amount;
160 public void roll (int fld, boolean up)
162 if (fld >= ZONE_OFFSET)
163 throw new IllegalArgumentException("bad field to roll");
165 int old = fields[fld];
168 fields[fld] = old == getMaximum(fld) ? getMinimum(fld)
173 fields[fld] = old == getMinimum(fld) ? getMaximum(fld)
178 private void adjust (int fld)
180 int value = fields[fld];
181 int radix = maxs[fld] + 1;
189 int next = value / radix;
190 fields[fld] = value - radix * next;
191 fields[fld - 1] += next;
194 else if (value < 0) // min[fld]
196 int next = (value - radix - 1) / radix;
197 fields[fld] = value - radix * next;
198 fields[fld - 1] += next;
205 public final Date getGregorianChange() { return new Date(gregorianCutover); }
206 public void setGregorianChange (Date date)
207 { gregorianCutover = date.getTime(); }
209 public boolean isLeapYear(int year)
213 if ((year % 100) != 0 || (year % 400) == 0)
215 // year divisible by 100 but not 400.
216 GregorianCalendar date = new GregorianCalendar(year, FEBRUARY, 28);
217 return gregorianCutover < date.getTimeInMillis();
220 public boolean after (Object cal)
222 return cal instanceof Calendar
223 && getTimeInMillis() > ((Calendar) cal).getTimeInMillis();
226 public boolean before (Object cal)
228 return cal instanceof Calendar
229 && getTimeInMillis() < ((Calendar) cal).getTimeInMillis();
232 public boolean equals (Object obj)
234 if (obj == null || ! (obj instanceof GregorianCalendar))
236 GregorianCalendar other = (GregorianCalendar) obj;
238 for (int i = FIELD_COUNT; --i >= 0; )
240 boolean set = isSet[i];
241 if (set != other.isSet[i]
242 || (set && fields[i] != other.fields[i]))
245 if (areFieldsSet != other.areFieldsSet
246 || isTimeSet != other.isTimeSet
247 || (isTimeSet && time != other.time)
248 || getFirstDayOfWeek() != other.getFirstDayOfWeek()
249 || getMinimalDaysInFirstWeek() != other.getMinimalDaysInFirstWeek()
250 || isLenient() != other.isLenient()
251 || ! getTimeZone().equals(other.getTimeZone()))
256 public int hashCode ()
259 for (int i = FIELD_COUNT; --i >= 0; )
262 hashcode += 37 * fields[i];
265 hashcode += 89 * time;