1 /* Copyright (C) 1998, 1999 Cygnus Solutions
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 public GregorianCalendar ()
97 public GregorianCalendar (TimeZone zone
)
102 public GregorianCalendar (Locale locale
)
107 public GregorianCalendar (TimeZone zone
, Locale locale
)
109 super (zone
, locale
);
112 public GregorianCalendar (int year
, int month
, int date
)
114 this((TimeZone
) null);
115 set (year
, month
, date
);
118 public GregorianCalendar (int year
, int month
, int date
,
119 int hour
, int minute
)
121 this((TimeZone
) null);
122 set (year
, month
, date
, hour
, minute
);
125 public GregorianCalendar (int year
, int month
, int date
,
126 int hour
, int minute
, int second
)
128 this((TimeZone
) null);
129 set (year
, month
, date
, hour
, minute
, second
);
132 public int getMinimum(int calfield
) { return mins
[calfield
]; }
133 public int getGreatestMinimum(int calfield
) { return mins
[calfield
]; }
134 public int getMaximum(int calfield
) { return maxs
[calfield
]; }
135 public int getLeastMaximum(int calfield
) { return leastMaximums
[calfield
]; }
137 protected native void computeFields();
139 protected native void computeTime();
141 public void add (int fld
, int amount
)
143 if (fld
>= ZONE_OFFSET
)
144 throw new IllegalArgumentException("bad field to add");
145 fields
[fld
] += amount
;
149 public void roll (int fld
, boolean up
)
151 if (fld
>= ZONE_OFFSET
)
152 throw new IllegalArgumentException("bad field to roll");
154 int old
= fields
[fld
];
157 fields
[fld
] = old
== getMaximum(fld
) ?
getMinimum(fld
)
162 fields
[fld
] = old
== getMinimum(fld
) ?
getMaximum(fld
)
167 private void adjust (int fld
)
169 int value
= fields
[fld
];
170 int radix
= maxs
[fld
] + 1;
178 int next
= value
/ radix
;
179 fields
[fld
] = value
- radix
* next
;
180 fields
[fld
- 1] += next
;
183 else if (value
< 0) // min[fld]
185 int next
= (value
- radix
- 1) / radix
;
186 fields
[fld
] = value
- radix
* next
;
187 fields
[fld
- 1] += next
;
194 public final Date
getGregorianChange() { return new Date(gregorianCutover
); }
195 public void setGregorianChange (Date date
)
196 { gregorianCutover
= date
.getTime(); }
198 public boolean isLeapYear(int year
)
202 if ((year
% 100) != 0 || (year
% 400) == 0)
204 // year divisible by 100 but not 400.
205 GregorianCalendar date
= new GregorianCalendar(year
, FEBRUARY
, 28);
206 return gregorianCutover
< date
.getTimeInMillis();
209 public boolean after (Object cal
)
211 return cal
instanceof Calendar
212 && getTimeInMillis() > ((Calendar
) cal
).getTimeInMillis();
215 public boolean before (Object cal
)
217 return cal
instanceof Calendar
218 && getTimeInMillis() < ((Calendar
) cal
).getTimeInMillis();
221 public boolean equals (Object obj
)
223 if (obj
== null || ! (obj
instanceof GregorianCalendar
))
225 GregorianCalendar other
= (GregorianCalendar
) obj
;
227 for (int i
= FIELD_COUNT
; --i
>= 0; )
229 boolean set
= isSet
[i
];
230 if (set
!= other
.isSet
[i
]
231 || (set
&& fields
[i
] != other
.fields
[i
]))
234 if (areFieldsSet
!= other
.areFieldsSet
235 || isTimeSet
!= other
.isTimeSet
236 || (isTimeSet
&& time
!= other
.time
)
237 || getFirstDayOfWeek() != other
.getFirstDayOfWeek()
238 || getMinimalDaysInFirstWeek() != other
.getMinimalDaysInFirstWeek()
239 || isLenient() != other
.isLenient()
240 || ! getTimeZone().equals(other
.getTimeZone()))
245 public int hashCode ()
248 for (int i
= FIELD_COUNT
; --i
>= 0; )
251 hashcode
+= 37 * fields
[i
];
254 hashcode
+= 89 * time
;