OSDN Git Service

* java/util/GregorianCalendar.java (GregorianCalendar): Constructors
[pf3gnuchains/gcc-fork.git] / libjava / java / util / GregorianCalendar.java
1 /* Copyright (C) 1998, 1999, 2000  Free Software Foundation
2
3    This file is part of libgcj.
4
5 This software is copyrighted work licensed under the terms of the
6 Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
7 details.  */
8
9 package java.util;
10
11 /**
12  * @author Per Bothner <bothner@cygnus.com>
13  * @date October 24, 1998.
14  */
15
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.
21  */
22
23 public class GregorianCalendar extends Calendar {
24   public static final int BC = 0;
25   public static final int AD = 1;
26
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;
31
32   private final static int[] mins = {
33     0 /* ERA */,
34     1 /* YEAR */,
35     0 /* MONTH */,
36     0 /* WEEK_OF_YEAR */,
37     0 /* WEEK_OF_MONTH */,
38     1 /* DATE */,
39     1 /* DAY_OF_YEAR */,
40     1 /* DAY_OF_WEEK */,
41     -1 /* DAY_OF_WEEK_IN_MONTH */,
42     0 /* AM_PM */,
43     0 /* HOUR */,
44     0 /* HOUR_OF_DAY */,
45     0 /* MINUTE */,
46     0 /* SECOND */,
47     0 /* MILLISECOND */,
48     -43200000 /* ZONE_OFFSET */,
49     0 /* DST_OFFSET */
50   };
51
52   private final static int[] maxs = {
53     1 /* ERA */,
54     5000000 /* YEAR */,
55     11 /* MONTH */,
56     54 /* WEEK_OF_YEAR */,
57     6 /* WEEK_OF_MONTH */,
58     31 /* DATE */,
59     366 /* DAY_OF_YEAR */,
60     7 /* DAY_OF_WEEK */,
61     6 /* DAY_OF_WEEK_IN_MONTH */,
62     1 /* AM_PM */,
63     12 /* HOUR */,
64     23 /* HOUR_OF_DAY */,
65     59 /* MINUTE */,
66     59 /* SECOND */,
67     999 /* MILLISECOND */,
68     43200000 /* ZONE_OFFSET */,
69     3600000 /* DST_OFFSET */
70   };
71
72   private final static int[] leastMaximums = {
73     1 /* ERA */,
74     5000000 /* YEAR */,
75     11 /* MONTH */,
76     53 /* WEEK_OF_YEAR */,
77     6 /* WEEK_OF_MONTH */,
78     28 /* DATE */,
79     365 /* DAY_OF_YEAR */,
80     7 /* DAY_OF_WEEK */,
81     4 /* DAY_OF_WEEK_IN_MONTH */,
82     1 /* AM_PM */,
83     11 /* HOUR */,
84     23 /* HOUR_OF_DAY */,
85     59 /* MINUTE */,
86     59 /* SECOND */,
87     999 /* MILLISECOND */,
88     43200000 /* ZONE_OFFSET */,
89     3600000 /* DST_OFFSET */
90   };
91
92   private static final long serialVersionUID = -8125100834729963327L;
93
94   public GregorianCalendar ()
95   {
96     this(TimeZone.getDefault (), Locale.getDefault ());
97   }
98
99   public GregorianCalendar (TimeZone zone)
100   {
101     this (zone, Locale.getDefault ());
102   }
103
104   public GregorianCalendar (Locale locale)
105   {
106     this (TimeZone.getDefault (), locale);
107   }
108
109   public GregorianCalendar (TimeZone zone, Locale locale)
110   {
111     super (zone, locale);
112     setDefaultTime ();
113   }
114
115   public GregorianCalendar (int year, int month, int date)
116   {
117     this();
118     setDefaultTime ();
119     set (year, month, date);
120   }
121
122   public GregorianCalendar (int year, int month, int date,
123                             int hour, int minute)
124   {
125     this();
126     setDefaultTime ();
127     set (year, month, date, hour, minute);
128   }
129
130   public GregorianCalendar (int year, int month, int date,
131                             int hour, int minute, int second)
132   {
133     this();
134     setDefaultTime ();
135     set (year, month, date, hour, minute, second);
136   }
137
138   private final void setDefaultTime ()
139   {
140     setTimeInMillis (System.currentTimeMillis());
141   }
142
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]; }
147
148   protected native void computeFields();
149
150   protected native void computeTime();
151
152   public void add (int fld, int amount)
153   {
154     if (fld >= ZONE_OFFSET)
155       throw new IllegalArgumentException("bad field to add");
156     fields[fld] += amount;
157     adjust(fld);
158   }
159
160   public void roll (int fld, boolean up)
161   {
162     if (fld >= ZONE_OFFSET)
163       throw new IllegalArgumentException("bad field to roll");
164
165     int old = fields[fld];
166     if (up)
167       {
168         fields[fld] = old == getMaximum(fld) ? getMinimum(fld)
169           : old + 1;
170       }
171     else
172       {
173         fields[fld] = old == getMinimum(fld) ? getMaximum(fld)
174           : old - 1;
175       }
176   }
177
178   private void adjust (int fld)
179   {
180     int value = fields[fld];
181     int radix = maxs[fld] + 1;
182     switch (fld)
183       {
184       case MONTH:
185       case SECOND:
186       case MILLISECOND:
187         if (value >= radix)
188           {
189             int next = value / radix;
190             fields[fld] = value - radix * next;
191             fields[fld - 1] += next;
192             adjust(fld - 1);
193           }
194         else if (value < 0) // min[fld]
195           {
196             int next = (value - radix - 1) / radix;
197             fields[fld] = value - radix * next;
198             fields[fld - 1] += next;
199             adjust(fld - 1);
200           }
201         break;
202       }
203   }
204
205   public final Date getGregorianChange() { return new Date(gregorianCutover); }
206   public void setGregorianChange (Date date)
207   { gregorianCutover = date.getTime(); }
208
209   public boolean isLeapYear(int year)
210   {
211     if ((year % 4) != 0)
212       return false;
213     if ((year % 100) != 0 || (year % 400) == 0)
214       return true;
215     // year divisible by 100 but not 400.
216     GregorianCalendar date = new GregorianCalendar(year, FEBRUARY, 28);
217     return gregorianCutover < date.getTimeInMillis();
218   }
219
220   public boolean after (Object cal)
221   {
222     return cal instanceof Calendar
223       && getTimeInMillis() > ((Calendar) cal).getTimeInMillis();
224   }
225
226   public boolean before (Object cal)
227   {
228     return cal instanceof Calendar
229       && getTimeInMillis() < ((Calendar) cal).getTimeInMillis();
230   }
231
232   public boolean equals (Object obj)
233   {
234     if (obj == null || ! (obj instanceof GregorianCalendar))
235       return false;
236     GregorianCalendar other = (GregorianCalendar) obj;
237
238     for (int i = FIELD_COUNT;  --i >= 0; )
239       {
240         boolean set = isSet[i];
241         if (set != other.isSet[i]
242             || (set && fields[i] != other.fields[i]))
243           return false;
244       }
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()))
252       return false;
253     return true;
254   }
255
256   public int hashCode ()
257   {
258     int hashcode = 0;
259     for (int i = FIELD_COUNT;  --i >= 0; )
260       {
261         if (isSet[i])
262           hashcode += 37 * fields[i];
263       }
264     if (isTimeSet)
265       hashcode += 89 * time;
266     return hashcode;
267   }
268 }