1 /*
2  * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
3  * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
4  *
5  *
6  *
7  *
8  *
9  *
10  *
11  *
12  *
13  *
14  *
15  *
16  *
17  *
18  *
19  *
20  *
21  *
22  *
23  *
24  */

25
26 package java.util;
27
28 import java.text.DateFormat;
29 import java.time.LocalDate;
30 import java.io.IOException;
31 import java.io.ObjectOutputStream;
32 import java.io.ObjectInputStream;
33 import java.lang.ref.SoftReference;
34 import java.time.Instant;
35 import sun.util.calendar.BaseCalendar;
36 import sun.util.calendar.CalendarDate;
37 import sun.util.calendar.CalendarSystem;
38 import sun.util.calendar.CalendarUtils;
39 import sun.util.calendar.Era;
40 import sun.util.calendar.Gregorian;
41 import sun.util.calendar.ZoneInfo;
42
43 /**
44  * The class <code>Date</code> represents a specific instant
45  * in time, with millisecond precision.
46  * <p>
47  * Prior to JDK&nbsp;1.1, the class <code>Date</code> had two additional
48  * functions.  It allowed the interpretation of dates as year, month, day, hour,
49  * minute, and second values.  It also allowed the formatting and parsing
50  * of date strings.  Unfortunately, the API for these functions was not
51  * amenable to internationalization.  As of JDK&nbsp;1.1, the
52  * <code>Calendar</code> class should be used to convert between dates and time
53  * fields and the <code>DateFormat</code> class should be used to format and
54  * parse date strings.
55  * The corresponding methods in <code>Date</code> are deprecated.
56  * <p>
57  * Although the <code>Date</code> class is intended to reflect
58  * coordinated universal time (UTC), it may not do so exactly,
59  * depending on the host environment of the Java Virtual Machine.
60  * Nearly all modern operating systems assume that 1&nbsp;day&nbsp;=
61  * 24&nbsp;&times;&nbsp;60&nbsp;&times;&nbsp;60&nbsp;= 86400 seconds
62  * in all cases. In UTC, however, about once every year or two there
63  * is an extra second, called a "leap second." The leap
64  * second is always added as the last second of the day, and always
65  * on December 31 or June 30. For example, the last minute of the
66  * year 1995 was 61 seconds long, thanks to an added leap second.
67  * Most computer clocks are not accurate enough to be able to reflect
68  * the leap-second distinction.
69  * <p>
70  * Some computer standards are defined in terms of Greenwich mean
71  * time (GMT), which is equivalent to universal time (UT).  GMT is
72  * the "civil" name for the standard; UT is the
73  * "scientific" name for the same standard. The
74  * distinction between UTC and UT is that UTC is based on an atomic
75  * clock and UT is based on astronomical observations, which for all
76  * practical purposes is an invisibly fine hair to split. Because the
77  * earth's rotation is not uniform (it slows down and speeds up
78  * in complicated ways), UT does not always flow uniformly. Leap
79  * seconds are introduced as needed into UTC so as to keep UTC within
80  * 0.9 seconds of UT1, which is a version of UT with certain
81  * corrections applied. There are other time and date systems as
82  * well; for example, the time scale used by the satellite-based
83  * global positioning system (GPS) is synchronized to UTC but is
84  * <i>not</i> adjusted for leap seconds. An interesting source of
85  * further information is the U.S. Naval Observatory, particularly
86  * the Directorate of Time at:
87  * <blockquote><pre>
88  *     <a href=http://tycho.usno.navy.mil>http://tycho.usno.navy.mil</a>
89  * </pre></blockquote>
90  * <p>
91  * and their definitions of "Systems of Time" at:
92  * <blockquote><pre>
93  *     <a href=http://tycho.usno.navy.mil/systime.html>http://tycho.usno.navy.mil/systime.html</a>
94  * </pre></blockquote>
95  * <p>
96  * In all methods of class <code>Date</code> that accept or return
97  * year, month, date, hours, minutes, and seconds values, the
98  * following representations are used:
99  * <ul>
100  * <li>A year <i>y</i> is represented by the integer
101  *     <i>y</i>&nbsp;<code>-&nbsp;1900</code>.
102  * <li>A month is represented by an integer from 0 to 11; 0 is January,
103  *     1 is February, and so forth; thus 11 is December.
104  * <li>A date (day of month) is represented by an integer from 1 to 31
105  *     in the usual manner.
106  * <li>An hour is represented by an integer from 0 to 23. Thus, the hour
107  *     from midnight to 1 a.m. is hour 0, and the hour from noon to 1
108  *     p.m. is hour 12.
109  * <li>A minute is represented by an integer from 0 to 59 in the usual manner.
110  * <li>A second is represented by an integer from 0 to 61; the values 60 and
111  *     61 occur only for leap seconds and even then only in Java
112  *     implementations that actually track leap seconds correctly. Because
113  *     of the manner in which leap seconds are currently introduced, it is
114  *     extremely unlikely that two leap seconds will occur in the same
115  *     minute, but this specification follows the date and time conventions
116  *     for ISO C.
117  * </ul>
118  * <p>
119  * In all cases, arguments given to methods for these purposes need
120  * not fall within the indicated ranges; for example, a date may be
121  * specified as January 32 and is interpreted as meaning February 1.
122  *
123  * @author  James Gosling
124  * @author  Arthur van Hoff
125  * @author  Alan Liu
126  * @see     java.text.DateFormat
127  * @see     java.util.Calendar
128  * @see     java.util.TimeZone
129  * @since   JDK1.0
130  */

131 public class Date
132     implements java.io.Serializable, Cloneable, Comparable<Date>
133 {
134     private static final BaseCalendar gcal =
135                                 CalendarSystem.getGregorianCalendar();
136     private static BaseCalendar jcal;
137
138     private transient long fastTime;
139
140     /*
141      * If cdate is null, then fastTime indicates the time in millis.
142      * If cdate.isNormalized() is true, then fastTime and cdate are in
143      * synch. Otherwise, fastTime is ignored, and cdate indicates the
144      * time.
145      */

146     private transient BaseCalendar.Date cdate;
147
148     // Initialized just before the value is used. See parse().
149     private static int defaultCenturyStart;
150
151     /* use serialVersionUID from modified java.util.Date for
152      * interoperability with JDK1.1. The Date was modified to write
153      * and read only the UTC time.
154      */

155     private static final long serialVersionUID = 7523967970034938905L;
156
157     /**
158      * Allocates a <code>Date</code> object and initializes it so that
159      * it represents the time at which it was allocated, measured to the
160      * nearest millisecond.
161      *
162      * @see     java.lang.System#currentTimeMillis()
163      */

164     public Date() {
165         this(System.currentTimeMillis());
166     }
167
168     /**
169      * Allocates a <code>Date</code> object and initializes it to
170      * represent the specified number of milliseconds since the
171      * standard base time known as "the epoch", namely January 1,
172      * 1970, 00:00:00 GMT.
173      *
174      * @param   date   the milliseconds since January 1, 1970, 00:00:00 GMT.
175      * @see     java.lang.System#currentTimeMillis()
176      */

177     public Date(long date) {
178         fastTime = date;
179     }
180
181     /**
182      * Allocates a <code>Date</code> object and initializes it so that
183      * it represents midnight, local time, at the beginning of the day
184      * specified by the <code>year</code>, <code>month</code>, and
185      * <code>date</code> arguments.
186      *
187      * @param   year    the year minus 1900.
188      * @param   month   the month between 0-11.
189      * @param   date    the day of the month between 1-31.
190      * @see     java.util.Calendar
191      * @deprecated As of JDK version 1.1,
192      * replaced by <code>Calendar.set(year + 1900, month, date)</code>
193      * or <code>GregorianCalendar(year + 1900, month, date)</code>.
194      */

195     @Deprecated
196     public Date(int year, int month, int date) {
197         this(year, month, date, 0, 0, 0);
198     }
199
200     /**
201      * Allocates a <code>Date</code> object and initializes it so that
202      * it represents the instant at the start of the minute specified by
203      * the <code>year</code>, <code>month</code>, <code>date</code>,
204      * <code>hrs</code>, and <code>min</code> arguments, in the local
205      * time zone.
206      *
207      * @param   year    the year minus 1900.
208      * @param   month   the month between 0-11.
209      * @param   date    the day of the month between 1-31.
210      * @param   hrs     the hours between 0-23.
211      * @param   min     the minutes between 0-59.
212      * @see     java.util.Calendar
213      * @deprecated As of JDK version 1.1,
214      * replaced by <code>Calendar.set(year + 1900, month, date,
215      * hrs, min)</code> or <code>GregorianCalendar(year + 1900,
216      * month, date, hrs, min)</code>.
217      */

218     @Deprecated
219     public Date(int year, int month, int date, int hrs, int min) {
220         this(year, month, date, hrs, min, 0);
221     }
222
223     /**
224      * Allocates a <code>Date</code> object and initializes it so that
225      * it represents the instant at the start of the second specified
226      * by the <code>year</code>, <code>month</code>, <code>date</code>,
227      * <code>hrs</code>, <code>min</code>, and <code>sec</code> arguments,
228      * in the local time zone.
229      *
230      * @param   year    the year minus 1900.
231      * @param   month   the month between 0-11.
232      * @param   date    the day of the month between 1-31.
233      * @param   hrs     the hours between 0-23.
234      * @param   min     the minutes between 0-59.
235      * @param   sec     the seconds between 0-59.
236      * @see     java.util.Calendar
237      * @deprecated As of JDK version 1.1,
238      * replaced by <code>Calendar.set(year + 1900, month, date,
239      * hrs, min, sec)</code> or <code>GregorianCalendar(year + 1900,
240      * month, date, hrs, min, sec)</code>.
241      */

242     @Deprecated
243     public Date(int year, int month, int date, int hrs, int min, int sec) {
244         int y = year + 1900;
245         // month is 0-based. So we have to normalize month to support Long.MAX_VALUE.
246         if (month >= 12) {
247             y += month / 12;
248             month %= 12;
249         } else if (month < 0) {
250             y += CalendarUtils.floorDivide(month, 12);
251             month = CalendarUtils.mod(month, 12);
252         }
253         BaseCalendar cal = getCalendarSystem(y);
254         cdate = (BaseCalendar.Date) cal.newCalendarDate(TimeZone.getDefaultRef());
255         cdate.setNormalizedDate(y, month + 1, date).setTimeOfDay(hrs, min, sec, 0);
256         getTimeImpl();
257         cdate = null;
258     }
259
260     /**
261      * Allocates a <code>Date</code> object and initializes it so that
262      * it represents the date and time indicated by the string
263      * <code>s</code>, which is interpreted as if by the
264      * {@link Date#parse} method.
265      *
266      * @param   s   a string representation of the date.
267      * @see     java.text.DateFormat
268      * @see     java.util.Date#parse(java.lang.String)
269      * @deprecated As of JDK version 1.1,
270      * replaced by <code>DateFormat.parse(String s)</code>.
271      */

272     @Deprecated
273     public Date(String s) {
274         this(parse(s));
275     }
276
277     /**
278      * Return a copy of this object.
279      */

280     public Object clone() {
281         Date d = null;
282         try {
283             d = (Date)super.clone();
284             if (cdate != null) {
285                 d.cdate = (BaseCalendar.Date) cdate.clone();
286             }
287         } catch (CloneNotSupportedException e) {} // Won't happen
288         return d;
289     }
290
291     /**
292      * Determines the date and time based on the arguments. The
293      * arguments are interpreted as a year, month, day of the month,
294      * hour of the day, minute within the hour, and second within the
295      * minute, exactly as for the <tt>Date</tt> constructor with six
296      * arguments, except that the arguments are interpreted relative
297      * to UTC rather than to the local time zone. The time indicated is
298      * returned represented as the distance, measured in milliseconds,
299      * of that time from the epoch (00:00:00 GMT on January 1, 1970).
300      *
301      * @param   year    the year minus 1900.
302      * @param   month   the month between 0-11.
303      * @param   date    the day of the month between 1-31.
304      * @param   hrs     the hours between 0-23.
305      * @param   min     the minutes between 0-59.
306      * @param   sec     the seconds between 0-59.
307      * @return  the number of milliseconds since January 1, 1970, 00:00:00 GMT for
308      *          the date and time specified by the arguments.
309      * @see     java.util.Calendar
310      * @deprecated As of JDK version 1.1,
311      * replaced by <code>Calendar.set(year + 1900, month, date,
312      * hrs, min, sec)</code> or <code>GregorianCalendar(year + 1900,
313      * month, date, hrs, min, sec)</code>, using a UTC
314      * <code>TimeZone</code>, followed by <code>Calendar.getTime().getTime()</code>.
315      */

316     @Deprecated
317     public static long UTC(int year, int month, int date,
318                            int hrs, int min, int sec) {
319         int y = year + 1900;
320         // month is 0-based. So we have to normalize month to support Long.MAX_VALUE.
321         if (month >= 12) {
322             y += month / 12;
323             month %= 12;
324         } else if (month < 0) {
325             y += CalendarUtils.floorDivide(month, 12);
326             month = CalendarUtils.mod(month, 12);
327         }
328         int m = month + 1;
329         BaseCalendar cal = getCalendarSystem(y);
330         BaseCalendar.Date udate = (BaseCalendar.Date) cal.newCalendarDate(null);
331         udate.setNormalizedDate(y, m, date).setTimeOfDay(hrs, min, sec, 0);
332
333         // Use a Date instance to perform normalization. Its fastTime
334         // is the UTC value after the normalization.
335         Date d = new Date(0);
336         d.normalize(udate);
337         return d.fastTime;
338     }
339
340     /**
341      * Attempts to interpret the string <tt>s</tt> as a representation
342      * of a date and time. If the attempt is successful, the time
343      * indicated is returned represented as the distance, measured in
344      * milliseconds, of that time from the epoch (00:00:00 GMT on
345      * January 1, 1970). If the attempt fails, an
346      * <tt>IllegalArgumentException</tt> is thrown.
347      * <p>
348      * It accepts many syntaxes; in particular, it recognizes the IETF
349      * standard date syntax: "Sat, 12 Aug 1995 13:30:00 GMT". It also
350      * understands the continental U.S. time-zone abbreviations, but for
351      * general use, a time-zone offset should be used: "Sat, 12 Aug 1995
352      * 13:30:00 GMT+0430" (4 hours, 30 minutes west of the Greenwich
353      * meridian). If no time zone is specified, the local time zone is
354      * assumed. GMT and UTC are considered equivalent.
355      * <p>
356      * The string <tt>s</tt> is processed from left to right, looking for
357      * data of interest. Any material in <tt>s</tt> that is within the
358      * ASCII parenthesis characters <tt>(</tt> and <tt>)</tt> is ignored.
359      * Parentheses may be nested. Otherwise, the only characters permitted
360      * within <tt>s</tt> are these ASCII characters:
361      * <blockquote><pre>
362      * abcdefghijklmnopqrstuvwxyz
363      * ABCDEFGHIJKLMNOPQRSTUVWXYZ
364      * 0123456789,+-:/</pre></blockquote>
365      * and whitespace characters.<p>
366      * A consecutive sequence of decimal digits is treated as a decimal
367      * number:<ul>
368      * <li>If a number is preceded by <tt>+</tt> or <tt>-</tt> and a year
369      *     has already been recognized, then the number is a time-zone
370      *     offset. If the number is less than 24, it is an offset measured
371      *     in hours. Otherwise, it is regarded as an offset in minutes,
372      *     expressed in 24-hour time format without punctuation. A
373      *     preceding <tt>-</tt> means a westward offset. Time zone offsets
374      *     are always relative to UTC (Greenwich). Thus, for example,
375      *     <tt>-5</tt> occurring in the string would mean "five hours west
376      *     of Greenwich" and <tt>+0430</tt> would mean "four hours and
377      *     thirty minutes east of Greenwich." It is permitted for the
378      *     string to specify <tt>GMT</tt>, <tt>UT</tt>, or <tt>UTC</tt>
379      *     redundantly-for example, <tt>GMT-5</tt> or <tt>utc+0430</tt>.
380      * <li>The number is regarded as a year number if one of the
381      *     following conditions is true:
382      * <ul>
383      *     <li>The number is equal to or greater than 70 and followed by a
384      *         space, comma, slash, or end of string
385      *     <li>The number is less than 70, and both a month and a day of
386      *         the month have already been recognized</li>
387      * </ul>
388      *     If the recognized year number is less than 100, it is
389      *     interpreted as an abbreviated year relative to a century of
390      *     which dates are within 80 years before and 19 years after
391      *     the time when the Date class is initialized.
392      *     After adjusting the year number, 1900 is subtracted from
393      *     it. For example, if the current year is 1999 then years in
394      *     the range 19 to 99 are assumed to mean 1919 to 1999, while
395      *     years from 0 to 18 are assumed to mean 2000 to 2018.  Note
396      *     that this is slightly different from the interpretation of
397      *     years less than 100 that is used in {@link java.text.SimpleDateFormat}.
398      * <li>If the number is followed by a colon, it is regarded as an hour,
399      *     unless an hour has already been recognized, in which case it is
400      *     regarded as a minute.
401      * <li>If the number is followed by a slash, it is regarded as a month
402      *     (it is decreased by 1 to produce a number in the range <tt>0</tt>
403      *     to <tt>11</tt>), unless a month has already been recognized, in
404      *     which case it is regarded as a day of the month.
405      * <li>If the number is followed by whitespace, a comma, a hyphen, or
406      *     end of string, then if an hour has been recognized but not a
407      *     minute, it is regarded as a minute; otherwise, if a minute has
408      *     been recognized but not a second, it is regarded as a second;
409      *     otherwise, it is regarded as a day of the month. </ul><p>
410      * A consecutive sequence of letters is regarded as a word and treated
411      * as follows:<ul>
412      * <li>A word that matches <tt>AM</tt>, ignoring case, is ignored (but
413      *     the parse fails if an hour has not been recognized or is less
414      *     than <tt>1</tt> or greater than <tt>12</tt>).
415      * <li>A word that matches <tt>PM</tt>, ignoring case, adds <tt>12</tt>
416      *     to the hour (but the parse fails if an hour has not been
417      *     recognized or is less than <tt>1</tt> or greater than <tt>12</tt>).
418      * <li>Any word that matches any prefix of <tt>SUNDAY, MONDAY, TUESDAY,
419      *     WEDNESDAY, THURSDAY, FRIDAY</tt>, or <tt>SATURDAY</tt>, ignoring
420      *     case, is ignored. For example, <tt>sat, Friday, TUE</tt>, and
421      *     <tt>Thurs</tt> are ignored.
422      * <li>Otherwise, any word that matches any prefix of <tt>JANUARY,
423      *     FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, AUGUST, SEPTEMBER,
424      *     OCTOBER, NOVEMBER</tt>, or <tt>DECEMBER</tt>, ignoring case, and
425      *     considering them in the order given here, is recognized as
426      *     specifying a month and is converted to a number (<tt>0</tt> to
427      *     <tt>11</tt>). For example, <tt>aug, Sept, april</tt>, and
428      *     <tt>NOV</tt> are recognized as months. So is <tt>Ma</tt>, which
429      *     is recognized as <tt>MARCH</tt>, not <tt>MAY</tt>.
430      * <li>Any word that matches <tt>GMT, UT</tt>, or <tt>UTC</tt>, ignoring
431      *     case, is treated as referring to UTC.
432      * <li>Any word that matches <tt>EST, CST, MST</tt>, or <tt>PST</tt>,
433      *     ignoring case, is recognized as referring to the time zone in
434      *     North America that is five, six, seven, or eight hours west of
435      *     Greenwich, respectively. Any word that matches <tt>EDT, CDT,
436      *     MDT</tt>, or <tt>PDT</tt>, ignoring case, is recognized as
437      *     referring to the same time zone, respectively, during daylight
438      *     saving time.</ul><p>
439      * Once the entire string s has been scanned, it is converted to a time
440      * result in one of two ways. If a time zone or time-zone offset has been
441      * recognized, then the year, month, day of month, hour, minute, and
442      * second are interpreted in UTC and then the time-zone offset is
443      * applied. Otherwise, the year, month, day of month, hour, minute, and
444      * second are interpreted in the local time zone.
445      *
446      * @param   s   a string to be parsed as a date.
447      * @return  the number of milliseconds since January 1, 1970, 00:00:00 GMT
448      *          represented by the string argument.
449      * @see     java.text.DateFormat
450      * @deprecated As of JDK version 1.1,
451      * replaced by <code>DateFormat.parse(String s)</code>.
452      */

453     @Deprecated
454     public static long parse(String s) {
455         int year = Integer.MIN_VALUE;
456         int mon = -1;
457         int mday = -1;
458         int hour = -1;
459         int min = -1;
460         int sec = -1;
461         int millis = -1;
462         int c = -1;
463         int i = 0;
464         int n = -1;
465         int wst = -1;
466         int tzoffset = -1;
467         int prevc = 0;
468     syntax:
469         {
470             if (s == null)
471                 break syntax;
472             int limit = s.length();
473             while (i < limit) {
474                 c = s.charAt(i);
475                 i++;
476                 if (c <= ' ' || c == ',')
477                     continue;
478                 if (c == '(') { // skip comments
479                     int depth = 1;
480                     while (i < limit) {
481                         c = s.charAt(i);
482                         i++;
483                         if (c == '(') depth++;
484                         else if (c == ')')
485                             if (--depth <= 0)
486                                 break;
487                     }
488                     continue;
489                 }
490                 if ('0' <= c && c <= '9') {
491                     n = c - '0';
492                     while (i < limit && '0' <= (c = s.charAt(i)) && c <= '9') {
493                         n = n * 10 + c - '0';
494                         i++;
495                     }
496                     if (prevc == '+' || prevc == '-' && year != Integer.MIN_VALUE) {
497                         // timezone offset
498                         if (n < 24)
499                             n = n * 60; // EG. "GMT-3"
500                         else
501                             n = n % 100 + n / 100 * 60; // eg "GMT-0430"
502                         if (prevc == '+')   // plus means east of GMT
503                             n = -n;
504                         if (tzoffset != 0 && tzoffset != -1)
505                             break syntax;
506                         tzoffset = n;
507                     } else if (n >= 70)
508                         if (year != Integer.MIN_VALUE)
509                             break syntax;
510                         else if (c <= ' ' || c == ',' || c == '/' || i >= limit)
511                             // year = n < 1900 ? n : n - 1900;
512                             year = n;
513                         else
514                             break syntax;
515                     else if (c == ':')
516                         if (hour < 0)
517                             hour = (byte) n;
518                         else if (min < 0)
519                             min = (byte) n;
520                         else
521                             break syntax;
522                     else if (c == '/')
523                         if (mon < 0)
524                             mon = (byte) (n - 1);
525                         else if (mday < 0)
526                             mday = (byte) n;
527                         else
528                             break syntax;
529                     else if (i < limit && c != ',' && c > ' ' && c != '-')
530                         break syntax;
531                     else if (hour >= 0 && min < 0)
532                         min = (byte) n;
533                     else if (min >= 0 && sec < 0)
534                         sec = (byte) n;
535                     else if (mday < 0)
536                         mday = (byte) n;
537                     // Handle two-digit years < 70 (70-99 handled above).
538                     else if (year == Integer.MIN_VALUE && mon >= 0 && mday >= 0)
539                         year = n;
540                     else
541                         break syntax;
542                     prevc = 0;
543                 } else if (c == '/' || c == ':' || c == '+' || c == '-')
544                     prevc = c;
545                 else {
546                     int st = i - 1;
547                     while (i < limit) {
548                         c = s.charAt(i);
549                         if (!('A' <= c && c <= 'Z' || 'a' <= c && c <= 'z'))
550                             break;
551                         i++;
552                     }
553                     if (i <= st + 1)
554                         break syntax;
555                     int k;
556                     for (k = wtb.length; --k >= 0;)
557                         if (wtb[k].regionMatches(true, 0, s, st, i - st)) {
558                             int action = ttb[k];
559                             if (action != 0) {
560                                 if (action == 1) {  // pm
561                                     if (hour > 12 || hour < 1)
562                                         break syntax;
563                                     else if (hour < 12)
564                                         hour += 12;
565                                 } else if (action == 14) {  // am
566                                     if (hour > 12 || hour < 1)
567                                         break syntax;
568                                     else if (hour == 12)
569                                         hour = 0;
570                                 } else if (action <= 13) {  // month!
571                                     if (mon < 0)
572                                         mon = (byte) (action - 2);
573                                     else
574                                         break syntax;
575                                 } else {
576                                     tzoffset = action - 10000;
577                                 }
578                             }
579                             break;
580                         }
581                     if (k < 0)
582                         break syntax;
583                     prevc = 0;
584                 }
585             }
586             if (year == Integer.MIN_VALUE || mon < 0 || mday < 0)
587                 break syntax;
588             // Parse 2-digit years within the correct default century.
589             if (year < 100) {
590                 synchronized (Date.class) {
591                     if (defaultCenturyStart == 0) {
592                         defaultCenturyStart = gcal.getCalendarDate().getYear() - 80;
593                     }
594                 }
595                 year += (defaultCenturyStart / 100) * 100;
596                 if (year < defaultCenturyStart) year += 100;
597             }
598             if (sec < 0)
599                 sec = 0;
600             if (min < 0)
601                 min = 0;
602             if (hour < 0)
603                 hour = 0;
604             BaseCalendar cal = getCalendarSystem(year);
605             if (tzoffset == -1)  { // no time zone specified, have to use local
606                 BaseCalendar.Date ldate = (BaseCalendar.Date) cal.newCalendarDate(TimeZone.getDefaultRef());
607                 ldate.setDate(year, mon + 1, mday);
608                 ldate.setTimeOfDay(hour, min, sec, 0);
609                 return cal.getTime(ldate);
610             }
611             BaseCalendar.Date udate = (BaseCalendar.Date) cal.newCalendarDate(null); // no time zone
612             udate.setDate(year, mon + 1, mday);
613             udate.setTimeOfDay(hour, min, sec, 0);
614             return cal.getTime(udate) + tzoffset * (60 * 1000);
615         }
616         // syntax error
617         throw new IllegalArgumentException();
618     }
619     private final static String wtb[] = {
620         "am""pm",
621         "monday""tuesday""wednesday""thursday""friday",
622         "saturday""sunday",
623         "january""february""march""april""may""june",
624         "july""august""september""october""november""december",
625         "gmt""ut""utc""est""edt""cst""cdt",
626         "mst""mdt""pst""pdt"
627     };
628     private final static int ttb[] = {
629         14, 1, 0, 0, 0, 0, 0, 0, 0,
630         2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
631         10000 + 0, 10000 + 0, 10000 + 0,    // GMT/UT/UTC
632         10000 + 5 * 60, 10000 + 4 * 60,     // EST/EDT
633         10000 + 6 * 60, 10000 + 5 * 60,     // CST/CDT
634         10000 + 7 * 60, 10000 + 6 * 60,     // MST/MDT
635         10000 + 8 * 60, 10000 + 7 * 60      // PST/PDT
636     };
637
638     /**
639      * Returns a value that is the result of subtracting 1900 from the
640      * year that contains or begins with the instant in time represented
641      * by this <code>Date</code> object, as interpreted in the local
642      * time zone.
643      *
644      * @return  the year represented by this date, minus 1900.
645      * @see     java.util.Calendar
646      * @deprecated As of JDK version 1.1,
647      * replaced by <code>Calendar.get(Calendar.YEAR) - 1900</code>.
648      */

649     @Deprecated
650     public int getYear() {
651         return normalize().getYear() - 1900;
652     }
653
654     /**
655      * Sets the year of this <tt>Date</tt> object to be the specified
656      * value plus 1900. This <code>Date</code> object is modified so
657      * that it represents a point in time within the specified year,
658      * with the month, date, hour, minute, and second the same as
659      * before, as interpreted in the local time zone. (Of course, if
660      * the date was February 29, for example, and the year is set to a
661      * non-leap year, then the new date will be treated as if it were
662      * on March 1.)
663      *
664      * @param   year    the year value.
665      * @see     java.util.Calendar
666      * @deprecated As of JDK version 1.1,
667      * replaced by <code>Calendar.set(Calendar.YEAR, year + 1900)</code>.
668      */

669     @Deprecated
670     public void setYear(int year) {
671         getCalendarDate().setNormalizedYear(year + 1900);
672     }
673
674     /**
675      * Returns a number representing the month that contains or begins
676      * with the instant in time represented by this <tt>Date</tt> object.
677      * The value returned is between <code>0</code> and <code>11</code>,
678      * with the value <code>0</code> representing January.
679      *
680      * @return  the month represented by this date.
681      * @see     java.util.Calendar
682      * @deprecated As of JDK version 1.1,
683      * replaced by <code>Calendar.get(Calendar.MONTH)</code>.
684      */

685     @Deprecated
686     public int getMonth() {
687         return normalize().getMonth() - 1; // adjust 1-based to 0-based
688     }
689
690     /**
691      * Sets the month of this date to the specified value. This
692      * <tt>Date</tt> object is modified so that it represents a point
693      * in time within the specified month, with the year, date, hour,
694      * minute, and second the same as before, as interpreted in the
695      * local time zone. If the date was October 31, for example, and
696      * the month is set to June, then the new date will be treated as
697      * if it were on July 1, because June has only 30 days.
698      *
699      * @param   month   the month value between 0-11.
700      * @see     java.util.Calendar
701      * @deprecated As of JDK version 1.1,
702      * replaced by <code>Calendar.set(Calendar.MONTH, int month)</code>.
703      */

704     @Deprecated
705     public void setMonth(int month) {
706         int y = 0;
707         if (month >= 12) {
708             y = month / 12;
709             month %= 12;
710         } else if (month < 0) {
711             y = CalendarUtils.floorDivide(month, 12);
712             month = CalendarUtils.mod(month, 12);
713         }
714         BaseCalendar.Date d = getCalendarDate();
715         if (y != 0) {
716             d.setNormalizedYear(d.getNormalizedYear() + y);
717         }
718         d.setMonth(month + 1); // adjust 0-based to 1-based month numbering
719     }
720
721     /**
722      * Returns the day of the month represented by this <tt>Date</tt> object.
723      * The value returned is between <code>1</code> and <code>31</code>
724      * representing the day of the month that contains or begins with the
725      * instant in time represented by this <tt>Date</tt> object, as
726      * interpreted in the local time zone.
727      *
728      * @return  the day of the month represented by this date.
729      * @see     java.util.Calendar
730      * @deprecated As of JDK version 1.1,
731      * replaced by <code>Calendar.get(Calendar.DAY_OF_MONTH)</code>.
732      * @deprecated
733      */

734     @Deprecated
735     public int getDate() {
736         return normalize().getDayOfMonth();
737     }
738
739     /**
740      * Sets the day of the month of this <tt>Date</tt> object to the
741      * specified value. This <tt>Date</tt> object is modified so that
742      * it represents a point in time within the specified day of the
743      * month, with the year, month, hour, minute, and second the same
744      * as before, as interpreted in the local time zone. If the date
745      * was April 30, for example, and the date is set to 31, then it
746      * will be treated as if it were on May 1, because April has only
747      * 30 days.
748      *
749      * @param   date   the day of the month value between 1-31.
750      * @see     java.util.Calendar
751      * @deprecated As of JDK version 1.1,
752      * replaced by <code>Calendar.set(Calendar.DAY_OF_MONTH, int date)</code>.
753      */

754     @Deprecated
755     public void setDate(int date) {
756         getCalendarDate().setDayOfMonth(date);
757     }
758
759     /**
760      * Returns the day of the week represented by this date. The
761      * returned value (<tt>0</tt> = Sunday, <tt>1</tt> = Monday,
762      * <tt>2</tt> = Tuesday, <tt>3</tt> = Wednesday, <tt>4</tt> =
763      * Thursday, <tt>5</tt> = Friday, <tt>6</tt> = Saturday)
764      * represents the day of the week that contains or begins with
765      * the instant in time represented by this <tt>Date</tt> object,
766      * as interpreted in the local time zone.
767      *
768      * @return  the day of the week represented by this date.
769      * @see     java.util.Calendar
770      * @deprecated As of JDK version 1.1,
771      * replaced by <code>Calendar.get(Calendar.DAY_OF_WEEK)</code>.
772      */

773     @Deprecated
774     public int getDay() {
775         return normalize().getDayOfWeek() - BaseCalendar.SUNDAY;
776     }
777
778     /**
779      * Returns the hour represented by this <tt>Date</tt> object. The
780      * returned value is a number (<tt>0</tt> through <tt>23</tt>)
781      * representing the hour within the day that contains or begins
782      * with the instant in time represented by this <tt>Date</tt>
783      * object, as interpreted in the local time zone.
784      *
785      * @return  the hour represented by this date.
786      * @see     java.util.Calendar
787      * @deprecated As of JDK version 1.1,
788      * replaced by <code>Calendar.get(Calendar.HOUR_OF_DAY)</code>.
789      */

790     @Deprecated
791     public int getHours() {
792         return normalize().getHours();
793     }
794
795     /**
796      * Sets the hour of this <tt>Date</tt> object to the specified value.
797      * This <tt>Date</tt> object is modified so that it represents a point
798      * in time within the specified hour of the day, with the year, month,
799      * date, minute, and second the same as before, as interpreted in the
800      * local time zone.
801      *
802      * @param   hours   the hour value.
803      * @see     java.util.Calendar
804      * @deprecated As of JDK version 1.1,
805      * replaced by <code>Calendar.set(Calendar.HOUR_OF_DAY, int hours)</code>.
806      */

807     @Deprecated
808     public void setHours(int hours) {
809         getCalendarDate().setHours(hours);
810     }
811
812     /**
813      * Returns the number of minutes past the hour represented by this date,
814      * as interpreted in the local time zone.
815      * The value returned is between <code>0</code> and <code>59</code>.
816      *
817      * @return  the number of minutes past the hour represented by this date.
818      * @see     java.util.Calendar
819      * @deprecated As of JDK version 1.1,
820      * replaced by <code>Calendar.get(Calendar.MINUTE)</code>.
821      */

822     @Deprecated
823     public int getMinutes() {
824         return normalize().getMinutes();
825     }
826
827     /**
828      * Sets the minutes of this <tt>Date</tt> object to the specified value.
829      * This <tt>Date</tt> object is modified so that it represents a point
830      * in time within the specified minute of the hour, with the year, month,
831      * date, hour, and second the same as before, as interpreted in the
832      * local time zone.
833      *
834      * @param   minutes   the value of the minutes.
835      * @see     java.util.Calendar
836      * @deprecated As of JDK version 1.1,
837      * replaced by <code>Calendar.set(Calendar.MINUTE, int minutes)</code>.
838      */

839     @Deprecated
840     public void setMinutes(int minutes) {
841         getCalendarDate().setMinutes(minutes);
842     }
843
844     /**
845      * Returns the number of seconds past the minute represented by this date.
846      * The value returned is between <code>0</code> and <code>61</code>. The
847      * values <code>60</code> and <code>61</code> can only occur on those
848      * Java Virtual Machines that take leap seconds into account.
849      *
850      * @return  the number of seconds past the minute represented by this date.
851      * @see     java.util.Calendar
852      * @deprecated As of JDK version 1.1,
853      * replaced by <code>Calendar.get(Calendar.SECOND)</code>.
854      */

855     @Deprecated
856     public int getSeconds() {
857         return normalize().getSeconds();
858     }
859
860     /**
861      * Sets the seconds of this <tt>Date</tt> to the specified value.
862      * This <tt>Date</tt> object is modified so that it represents a
863      * point in time within the specified second of the minute, with
864      * the year, month, date, hour, and minute the same as before, as
865      * interpreted in the local time zone.
866      *
867      * @param   seconds   the seconds value.
868      * @see     java.util.Calendar
869      * @deprecated As of JDK version 1.1,
870      * replaced by <code>Calendar.set(Calendar.SECOND, int seconds)</code>.
871      */

872     @Deprecated
873     public void setSeconds(int seconds) {
874         getCalendarDate().setSeconds(seconds);
875     }
876
877     /**
878      * Returns the number of milliseconds since January 1, 1970, 00:00:00 GMT
879      * represented by this <tt>Date</tt> object.
880      *
881      * @return  the number of milliseconds since January 1, 1970, 00:00:00 GMT
882      *          represented by this date.
883      */

884     public long getTime() {
885         return getTimeImpl();
886     }
887
888     private final long getTimeImpl() {
889         if (cdate != null && !cdate.isNormalized()) {
890             normalize();
891         }
892         return fastTime;
893     }
894
895     /**
896      * Sets this <code>Date</code> object to represent a point in time that is
897      * <code>time</code> milliseconds after January 1, 1970 00:00:00 GMT.
898      *
899      * @param   time   the number of milliseconds.
900      */

901     public void setTime(long time) {
902         fastTime = time;
903         cdate = null;
904     }
905
906     /**
907      * Tests if this date is before the specified date.
908      *
909      * @param   when   a date.
910      * @return  <code>true</code> if and only if the instant of time
911      *            represented by this <tt>Date</tt> object is strictly
912      *            earlier than the instant represented by <tt>when</tt>;
913      *          <code>false</code> otherwise.
914      * @exception NullPointerException if <code>when</code> is null.
915      */

916     public boolean before(Date when) {
917         return getMillisOf(this) < getMillisOf(when);
918     }
919
920     /**
921      * Tests if this date is after the specified date.
922      *
923      * @param   when   a date.
924      * @return  <code>true</code> if and only if the instant represented
925      *          by this <tt>Date</tt> object is strictly later than the
926      *          instant represented by <tt>when</tt>;
927      *          <code>false</code> otherwise.
928      * @exception NullPointerException if <code>when</code> is null.
929      */

930     public boolean after(Date when) {
931         return getMillisOf(this) > getMillisOf(when);
932     }
933
934     /**
935      * Compares two dates for equality.
936      * The result is <code>true</code> if and only if the argument is
937      * not <code>null</code> and is a <code>Date</code> object that
938      * represents the same point in time, to the millisecond, as this object.
939      * <p>
940      * Thus, two <code>Date</code> objects are equal if and only if the
941      * <code>getTime</code> method returns the same <code>long</code>
942      * value for both.
943      *
944      * @param   obj   the object to compare with.
945      * @return  <code>true</code> if the objects are the same;
946      *          <code>false</code> otherwise.
947      * @see     java.util.Date#getTime()
948      */

949     public boolean equals(Object obj) {
950         return obj instanceof Date && getTime() == ((Date) obj).getTime();
951     }
952
953     /**
954      * Returns the millisecond value of this <code>Date</code> object
955      * without affecting its internal state.
956      */

957     static final long getMillisOf(Date date) {
958         if (date.cdate == null || date.cdate.isNormalized()) {
959             return date.fastTime;
960         }
961         BaseCalendar.Date d = (BaseCalendar.Date) date.cdate.clone();
962         return gcal.getTime(d);
963     }
964
965     /**
966      * Compares two Dates for ordering.
967      *
968      * @param   anotherDate   the <code>Date</code> to be compared.
969      * @return  the value <code>0</code> if the argument Date is equal to
970      *          this Date; a value less than <code>0</code> if this Date
971      *          is before the Date argument; and a value greater than
972      *      <code>0</code> if this Date is after the Date argument.
973      * @since   1.2
974      * @exception NullPointerException if <code>anotherDate</code> is null.
975      */

976     public int compareTo(Date anotherDate) {
977         long thisTime = getMillisOf(this);
978         long anotherTime = getMillisOf(anotherDate);
979         return (thisTime<anotherTime ? -1 : (thisTime==anotherTime ? 0 : 1));
980     }
981
982     /**
983      * Returns a hash code value for this object. The result is the
984      * exclusive OR of the two halves of the primitive <tt>long</tt>
985      * value returned by the {@link Date#getTime}
986      * method. That is, the hash code is the value of the expression:
987      * <blockquote><pre>{@code
988      * (int)(this.getTime()^(this.getTime() >>> 32))
989      * }</pre></blockquote>
990      *
991      * @return  a hash code value for this object.
992      */

993     public int hashCode() {
994         long ht = this.getTime();
995         return (int) ht ^ (int) (ht >> 32);
996     }
997
998     /**
999      * Converts this <code>Date</code> object to a <code>String</code>
1000      * of the form:
1001      * <blockquote><pre>
1002      * dow mon dd hh:mm:ss zzz yyyy</pre></blockquote>
1003      * where:<ul>
1004      * <li><tt>dow</tt> is the day of the week (<tt>Sun, Mon, Tue, Wed,
1005      *     Thu, Fri, Sat</tt>).
1006      * <li><tt>mon</tt> is the month (<tt>Jan, Feb, Mar, Apr, May, Jun,
1007      *     Jul, Aug, Sep, Oct, Nov, Dec</tt>).
1008      * <li><tt>dd</tt> is the day of the month (<tt>01</tt> through
1009      *     <tt>31</tt>), as two decimal digits.
1010      * <li><tt>hh</tt> is the hour of the day (<tt>00</tt> through
1011      *     <tt>23</tt>), as two decimal digits.
1012      * <li><tt>mm</tt> is the minute within the hour (<tt>00</tt> through
1013      *     <tt>59</tt>), as two decimal digits.
1014      * <li><tt>ss</tt> is the second within the minute (<tt>00</tt> through
1015      *     <tt>61</tt>, as two decimal digits.
1016      * <li><tt>zzz</tt> is the time zone (and may reflect daylight saving
1017      *     time). Standard time zone abbreviations include those
1018      *     recognized by the method <tt>parse</tt>. If time zone
1019      *     information is not available, then <tt>zzz</tt> is empty -
1020      *     that is, it consists of no characters at all.
1021      * <li><tt>yyyy</tt> is the year, as four decimal digits.
1022      * </ul>
1023      *
1024      * @return  a string representation of this date.
1025      * @see     java.util.Date#toLocaleString()
1026      * @see     java.util.Date#toGMTString()
1027      */

1028     public String toString() {
1029         // "EEE MMM dd HH:mm:ss zzz yyyy";
1030         BaseCalendar.Date date = normalize();
1031         StringBuilder sb = new StringBuilder(28);
1032         int index = date.getDayOfWeek();
1033         if (index == BaseCalendar.SUNDAY) {
1034             index = 8;
1035         }
1036         convertToAbbr(sb, wtb[index]).append(' ');                        // EEE
1037         convertToAbbr(sb, wtb[date.getMonth() - 1 + 2 + 7]).append(' ');  // MMM
1038         CalendarUtils.sprintf0d(sb, date.getDayOfMonth(), 2).append(' '); // dd
1039
1040         CalendarUtils.sprintf0d(sb, date.getHours(), 2).append(':');   // HH
1041         CalendarUtils.sprintf0d(sb, date.getMinutes(), 2).append(':'); // mm
1042         CalendarUtils.sprintf0d(sb, date.getSeconds(), 2).append(' '); // ss
1043         TimeZone zi = date.getZone();
1044         if (zi != null) {
1045             sb.append(zi.getDisplayName(date.isDaylightTime(), TimeZone.SHORT, Locale.US)); // zzz
1046         } else {
1047             sb.append("GMT");
1048         }
1049         sb.append(' ').append(date.getYear());  // yyyy
1050         return sb.toString();
1051     }
1052
1053     /**
1054      * Converts the given name to its 3-letter abbreviation (e.g.,
1055      * "monday" -> "Mon") and stored the abbreviation in the given
1056      * <code>StringBuilder</code>.
1057      */

1058     private static final StringBuilder convertToAbbr(StringBuilder sb, String name) {
1059         sb.append(Character.toUpperCase(name.charAt(0)));
1060         sb.append(name.charAt(1)).append(name.charAt(2));
1061         return sb;
1062     }
1063
1064     /**
1065      * Creates a string representation of this <tt>Date</tt> object in an
1066      * implementation-dependent form. The intent is that the form should
1067      * be familiar to the user of the Java application, wherever it may
1068      * happen to be running. The intent is comparable to that of the
1069      * "<code>%c</code>" format supported by the <code>strftime()</code>
1070      * function of ISO&nbsp;C.
1071      *
1072      * @return  a string representation of this date, using the locale
1073      *          conventions.
1074      * @see     java.text.DateFormat
1075      * @see     java.util.Date#toString()
1076      * @see     java.util.Date#toGMTString()
1077      * @deprecated As of JDK version 1.1,
1078      * replaced by <code>DateFormat.format(Date date)</code>.
1079      */

1080     @Deprecated
1081     public String toLocaleString() {
1082         DateFormat formatter = DateFormat.getDateTimeInstance();
1083         return formatter.format(this);
1084     }
1085
1086     /**
1087      * Creates a string representation of this <tt>Date</tt> object of
1088      * the form:
1089      * <blockquote><pre>
1090      * d mon yyyy hh:mm:ss GMT</pre></blockquote>
1091      * where:<ul>
1092      * <li><i>d</i> is the day of the month (<tt>1</tt> through <tt>31</tt>),
1093      *     as one or two decimal digits.
1094      * <li><i>mon</i> is the month (<tt>Jan, Feb, Mar, Apr, May, Jun, Jul,
1095      *     Aug, Sep, Oct, Nov, Dec</tt>).
1096      * <li><i>yyyy</i> is the year, as four decimal digits.
1097      * <li><i>hh</i> is the hour of the day (<tt>00</tt> through <tt>23</tt>),
1098      *     as two decimal digits.
1099      * <li><i>mm</i> is the minute within the hour (<tt>00</tt> through
1100      *     <tt>59</tt>), as two decimal digits.
1101      * <li><i>ss</i> is the second within the minute (<tt>00</tt> through
1102      *     <tt>61</tt>), as two decimal digits.
1103      * <li><i>GMT</i> is exactly the ASCII letters "<tt>GMT</tt>" to indicate
1104      *     Greenwich Mean Time.
1105      * </ul><p>
1106      * The result does not depend on the local time zone.
1107      *
1108      * @return  a string representation of this date, using the Internet GMT
1109      *          conventions.
1110      * @see     java.text.DateFormat
1111      * @see     java.util.Date#toString()
1112      * @see     java.util.Date#toLocaleString()
1113      * @deprecated As of JDK version 1.1,
1114      * replaced by <code>DateFormat.format(Date date)</code>, using a
1115      * GMT <code>TimeZone</code>.
1116      */

1117     @Deprecated
1118     public String toGMTString() {
1119         // d MMM yyyy HH:mm:ss 'GMT'
1120         long t = getTime();
1121         BaseCalendar cal = getCalendarSystem(t);
1122         BaseCalendar.Date date =
1123             (BaseCalendar.Date) cal.getCalendarDate(getTime(), (TimeZone)null);
1124         StringBuilder sb = new StringBuilder(32);
1125         CalendarUtils.sprintf0d(sb, date.getDayOfMonth(), 1).append(' '); // d
1126         convertToAbbr(sb, wtb[date.getMonth() - 1 + 2 + 7]).append(' ');  // MMM
1127         sb.append(date.getYear()).append(' ');                            // yyyy
1128         CalendarUtils.sprintf0d(sb, date.getHours(), 2).append(':');      // HH
1129         CalendarUtils.sprintf0d(sb, date.getMinutes(), 2).append(':');    // mm
1130         CalendarUtils.sprintf0d(sb, date.getSeconds(), 2);                // ss
1131         sb.append(" GMT");                                                // ' GMT'
1132         return sb.toString();
1133     }
1134
1135     /**
1136      * Returns the offset, measured in minutes, for the local time zone
1137      * relative to UTC that is appropriate for the time represented by
1138      * this <code>Date</code> object.
1139      * <p>
1140      * For example, in Massachusetts, five time zones west of Greenwich:
1141      * <blockquote><pre>
1142      * new Date(96, 1, 14).getTimezoneOffset() returns 300</pre></blockquote>
1143      * because on February 14, 1996, standard time (Eastern Standard Time)
1144      * is in use, which is offset five hours from UTC; but:
1145      * <blockquote><pre>
1146      * new Date(96, 5, 1).getTimezoneOffset() returns 240</pre></blockquote>
1147      * because on June 1, 1996, daylight saving time (Eastern Daylight Time)
1148      * is in use, which is offset only four hours from UTC.<p>
1149      * This method produces the same result as if it computed:
1150      * <blockquote><pre>
1151      * (this.getTime() - UTC(this.getYear(),
1152      *                       this.getMonth(),
1153      *                       this.getDate(),
1154      *                       this.getHours(),
1155      *                       this.getMinutes(),
1156      *                       this.getSeconds())) / (60 * 1000)
1157      * </pre></blockquote>
1158      *
1159      * @return  the time-zone offset, in minutes, for the current time zone.
1160      * @see     java.util.Calendar#ZONE_OFFSET
1161      * @see     java.util.Calendar#DST_OFFSET
1162      * @see     java.util.TimeZone#getDefault
1163      * @deprecated As of JDK version 1.1,
1164      * replaced by <code>-(Calendar.get(Calendar.ZONE_OFFSET) +
1165      * Calendar.get(Calendar.DST_OFFSET)) / (60 * 1000)</code>.
1166      */

1167     @Deprecated
1168     public int getTimezoneOffset() {
1169         int zoneOffset;
1170         if (cdate == null) {
1171             TimeZone tz = TimeZone.getDefaultRef();
1172             if (tz instanceof ZoneInfo) {
1173                 zoneOffset = ((ZoneInfo)tz).getOffsets(fastTime, null);
1174             } else {
1175                 zoneOffset = tz.getOffset(fastTime);
1176             }
1177         } else {
1178             normalize();
1179             zoneOffset = cdate.getZoneOffset();
1180         }
1181         return -zoneOffset/60000;  // convert to minutes
1182     }
1183
1184     private final BaseCalendar.Date getCalendarDate() {
1185         if (cdate == null) {
1186             BaseCalendar cal = getCalendarSystem(fastTime);
1187             cdate = (BaseCalendar.Date) cal.getCalendarDate(fastTime,
1188                                                             TimeZone.getDefaultRef());
1189         }
1190         return cdate;
1191     }
1192
1193     private final BaseCalendar.Date normalize() {
1194         if (cdate == null) {
1195             BaseCalendar cal = getCalendarSystem(fastTime);
1196             cdate = (BaseCalendar.Date) cal.getCalendarDate(fastTime,
1197                                                             TimeZone.getDefaultRef());
1198             return cdate;
1199         }
1200
1201         // Normalize cdate with the TimeZone in cdate first. This is
1202         // required for the compatible behavior.
1203         if (!cdate.isNormalized()) {
1204             cdate = normalize(cdate);
1205         }
1206
1207         // If the default TimeZone has changed, then recalculate the
1208         // fields with the new TimeZone.
1209         TimeZone tz = TimeZone.getDefaultRef();
1210         if (tz != cdate.getZone()) {
1211             cdate.setZone(tz);
1212             CalendarSystem cal = getCalendarSystem(cdate);
1213             cal.getCalendarDate(fastTime, cdate);
1214         }
1215         return cdate;
1216     }
1217
1218     // fastTime and the returned data are in sync upon return.
1219     private final BaseCalendar.Date normalize(BaseCalendar.Date date) {
1220         int y = date.getNormalizedYear();
1221         int m = date.getMonth();
1222         int d = date.getDayOfMonth();
1223         int hh = date.getHours();
1224         int mm = date.getMinutes();
1225         int ss = date.getSeconds();
1226         int ms = date.getMillis();
1227         TimeZone tz = date.getZone();
1228
1229         // If the specified year can't be handled using a long value
1230         // in milliseconds, GregorianCalendar is used for full
1231         // compatibility with underflow and overflow. This is required
1232         // by some JCK tests. The limits are based max year values -
1233         // years that can be represented by max values of d, hh, mm,
1234         // ss and ms. Also, let GregorianCalendar handle the default
1235         // cutover year so that we don't need to worry about the
1236         // transition here.
1237         if (y == 1582 || y > 280000000 || y < -280000000) {
1238             if (tz == null) {
1239                 tz = TimeZone.getTimeZone("GMT");
1240             }
1241             GregorianCalendar gc = new GregorianCalendar(tz);
1242             gc.clear();
1243             gc.set(GregorianCalendar.MILLISECOND, ms);
1244             gc.set(y, m-1, d, hh, mm, ss);
1245             fastTime = gc.getTimeInMillis();
1246             BaseCalendar cal = getCalendarSystem(fastTime);
1247             date = (BaseCalendar.Date) cal.getCalendarDate(fastTime, tz);
1248             return date;
1249         }
1250
1251         BaseCalendar cal = getCalendarSystem(y);
1252         if (cal != getCalendarSystem(date)) {
1253             date = (BaseCalendar.Date) cal.newCalendarDate(tz);
1254             date.setNormalizedDate(y, m, d).setTimeOfDay(hh, mm, ss, ms);
1255         }
1256         // Perform the GregorianCalendar-style normalization.
1257         fastTime = cal.getTime(date);
1258
1259         // In case the normalized date requires the other calendar
1260         // system, we need to recalculate it using the other one.
1261         BaseCalendar ncal = getCalendarSystem(fastTime);
1262         if (ncal != cal) {
1263             date = (BaseCalendar.Date) ncal.newCalendarDate(tz);
1264             date.setNormalizedDate(y, m, d).setTimeOfDay(hh, mm, ss, ms);
1265             fastTime = ncal.getTime(date);
1266         }
1267         return date;
1268     }
1269
1270     /**
1271      * Returns the Gregorian or Julian calendar system to use with the
1272      * given date. Use Gregorian from October 15, 1582.
1273      *
1274      * @param year normalized calendar year (not -1900)
1275      * @return the CalendarSystem to use for the specified date
1276      */

1277     private static final BaseCalendar getCalendarSystem(int year) {
1278         if (year >= 1582) {
1279             return gcal;
1280         }
1281         return getJulianCalendar();
1282     }
1283
1284     private static final BaseCalendar getCalendarSystem(long utc) {
1285         // Quickly check if the time stamp given by `utc' is the Epoch
1286         // or later. If it's before 1970, we convert the cutover to
1287         // local time to compare.
1288         if (utc >= 0
1289             || utc >= GregorianCalendar.DEFAULT_GREGORIAN_CUTOVER
1290                         - TimeZone.getDefaultRef().getOffset(utc)) {
1291             return gcal;
1292         }
1293         return getJulianCalendar();
1294     }
1295
1296     private static final BaseCalendar getCalendarSystem(BaseCalendar.Date cdate) {
1297         if (jcal == null) {
1298             return gcal;
1299         }
1300         if (cdate.getEra() != null) {
1301             return jcal;
1302         }
1303         return gcal;
1304     }
1305
1306     synchronized private static final BaseCalendar getJulianCalendar() {
1307         if (jcal == null) {
1308             jcal = (BaseCalendar) CalendarSystem.forName("julian");
1309         }
1310         return jcal;
1311     }
1312
1313     /**
1314      * Save the state of this object to a stream (i.e., serialize it).
1315      *
1316      * @serialData The value returned by <code>getTime()</code>
1317      *             is emitted (long).  This represents the offset from
1318      *             January 1, 1970, 00:00:00 GMT in milliseconds.
1319      */

1320     private void writeObject(ObjectOutputStream s)
1321          throws IOException
1322     {
1323         s.writeLong(getTimeImpl());
1324     }
1325
1326     /**
1327      * Reconstitute this object from a stream (i.e., deserialize it).
1328      */

1329     private void readObject(ObjectInputStream s)
1330          throws IOException, ClassNotFoundException
1331     {
1332         fastTime = s.readLong();
1333     }
1334
1335     /**
1336      * Obtains an instance of {@code Date} from an {@code Instant} object.
1337      * <p>
1338      * {@code Instant} uses a precision of nanoseconds, whereas {@code Date}
1339      * uses a precision of milliseconds.  The conversion will trancate any
1340      * excess precision information as though the amount in nanoseconds was
1341      * subject to integer division by one million.
1342      * <p>
1343      * {@code Instant} can store points on the time-line further in the future
1344      * and further in the past than {@code Date}. In this scenario, this method
1345      * will throw an exception.
1346      *
1347      * @param instant  the instant to convert
1348      * @return a {@code Date} representing the same point on the time-line as
1349      *  the provided instant
1350      * @exception NullPointerException if {@code instant} is null.
1351      * @exception IllegalArgumentException if the instant is too large to
1352      *  represent as a {@code Date}
1353      * @since 1.8
1354      */

1355     public static Date from(Instant instant) {
1356         try {
1357             return new Date(instant.toEpochMilli());
1358         } catch (ArithmeticException ex) {
1359             throw new IllegalArgumentException(ex);
1360         }
1361     }
1362
1363     /**
1364      * Converts this {@code Date} object to an {@code Instant}.
1365      * <p>
1366      * The conversion creates an {@code Instant} that represents the same
1367      * point on the time-line as this {@code Date}.
1368      *
1369      * @return an instant representing the same point on the time-line as
1370      *  this {@code Date} object
1371      * @since 1.8
1372      */

1373     public Instant toInstant() {
1374         return Instant.ofEpochMilli(getTime());
1375     }
1376 }
1377
Powered by JavaMelody