• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  * Copyright (c) 1994, 2016, Oracle and/or its affiliates. All rights reserved.
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This code is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License version 2 only, as
8  * published by the Free Software Foundation.  Oracle designates this
9  * particular file as subject to the "Classpath" exception as provided
10  * by Oracle in the LICENSE file that accompanied this code.
11  *
12  * This code is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15  * version 2 for more details (a copy is included in the LICENSE file that
16  * accompanied this code).
17  *
18  * You should have received a copy of the GNU General Public License version
19  * 2 along with this work; if not, write to the Free Software Foundation,
20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21  *
22  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
23  * or visit www.oracle.com if you need additional information or have any
24  * questions.
25  */
26 
27 package java.util;
28 
29 import java.text.DateFormat;
30 import java.time.LocalDate;
31 import java.io.IOException;
32 import java.io.ObjectOutputStream;
33 import java.io.ObjectInputStream;
34 import java.lang.ref.SoftReference;
35 import java.time.Instant;
36 import sun.util.calendar.BaseCalendar;
37 import sun.util.calendar.CalendarDate;
38 import sun.util.calendar.CalendarSystem;
39 import sun.util.calendar.CalendarUtils;
40 import sun.util.calendar.Era;
41 import sun.util.calendar.Gregorian;
42 
43 /**
44  * The class {@code Date} represents a specific instant
45  * in time, with millisecond precision.
46  * <p>
47  * Prior to JDK&nbsp;1.1, the class {@code Date} 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} class should be used to convert between dates and time
53  * fields and the {@code DateFormat} class should be used to format and
54  * parse date strings.
55  * The corresponding methods in {@code Date} are deprecated.
56  * <p>
57  * Although the {@code Date} 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 United States Naval Observatory (USNO):
86  * <blockquote><pre>
87  *     <a href="http://www.usno.navy.mil/USNO">http://www.usno.navy.mil/USNO</a>
88  * </pre></blockquote>
89  * <p>
90  * and the material regarding "Systems of Time" at:
91  * <blockquote><pre>
92  *     <a href="http://www.usno.navy.mil/USNO/time/master-clock/systems-of-time">http://www.usno.navy.mil/USNO/time/master-clock/systems-of-time</a>
93  * </pre></blockquote>
94  * <p>
95  * which has descriptions of various different time systems including
96  * UT, UT1, and UTC.
97  * <p>
98  * In all methods of class {@code Date} that accept or return
99  * year, month, date, hours, minutes, and seconds values, the
100  * following representations are used:
101  * <ul>
102  * <li>A year <i>y</i> is represented by the integer
103  *     <i>y</i>&nbsp;{@code - 1900}.
104  * <li>A month is represented by an integer from 0 to 11; 0 is January,
105  *     1 is February, and so forth; thus 11 is December.
106  * <li>A date (day of month) is represented by an integer from 1 to 31
107  *     in the usual manner.
108  * <li>An hour is represented by an integer from 0 to 23. Thus, the hour
109  *     from midnight to 1 a.m. is hour 0, and the hour from noon to 1
110  *     p.m. is hour 12.
111  * <li>A minute is represented by an integer from 0 to 59 in the usual manner.
112  * <li>A second is represented by an integer from 0 to 61; the values 60 and
113  *     61 occur only for leap seconds and even then only in Java
114  *     implementations that actually track leap seconds correctly. Because
115  *     of the manner in which leap seconds are currently introduced, it is
116  *     extremely unlikely that two leap seconds will occur in the same
117  *     minute, but this specification follows the date and time conventions
118  *     for ISO C.
119  * </ul>
120  * <p>
121  * In all cases, arguments given to methods for these purposes need
122  * not fall within the indicated ranges; for example, a date may be
123  * specified as January 32 and is interpreted as meaning February 1.
124  *
125  * @author  James Gosling
126  * @author  Arthur van Hoff
127  * @author  Alan Liu
128  * @see     java.text.DateFormat
129  * @see     java.util.Calendar
130  * @see     java.util.TimeZone
131  * @since   1.0
132  */
133 public class Date
134     implements java.io.Serializable, Cloneable, Comparable<Date>
135 {
136     private static final BaseCalendar gcal =
137                                 CalendarSystem.getGregorianCalendar();
138     private static BaseCalendar jcal;
139 
140     private transient long fastTime;
141 
142     /*
143      * If cdate is null, then fastTime indicates the time in millis.
144      * If cdate.isNormalized() is true, then fastTime and cdate are in
145      * synch. Otherwise, fastTime is ignored, and cdate indicates the
146      * time.
147      */
148     private transient BaseCalendar.Date cdate;
149 
150     // Initialized just before the value is used. See parse().
151     private static int defaultCenturyStart;
152 
153     /* use serialVersionUID from modified java.util.Date for
154      * interoperability with JDK1.1. The Date was modified to write
155      * and read only the UTC time.
156      */
157     private static final long serialVersionUID = 7523967970034938905L;
158 
159     /**
160      * Allocates a {@code Date} object and initializes it so that
161      * it represents the time at which it was allocated, measured to the
162      * nearest millisecond.
163      *
164      * @see     java.lang.System#currentTimeMillis()
165      */
Date()166     public Date() {
167         this(System.currentTimeMillis());
168     }
169 
170     /**
171      * Allocates a {@code Date} object and initializes it to
172      * represent the specified number of milliseconds since the
173      * standard base time known as "the epoch", namely January 1,
174      * 1970, 00:00:00 GMT.
175      *
176      * @param   date   the milliseconds since January 1, 1970, 00:00:00 GMT.
177      * @see     java.lang.System#currentTimeMillis()
178      */
Date(long date)179     public Date(long date) {
180         fastTime = date;
181     }
182 
183     /**
184      * Allocates a {@code Date} object and initializes it so that
185      * it represents midnight, local time, at the beginning of the day
186      * specified by the {@code year}, {@code month}, and
187      * {@code date} arguments.
188      *
189      * @param   year    the year minus 1900.
190      * @param   month   the month between 0-11.
191      * @param   date    the day of the month between 1-31.
192      * @see     java.util.Calendar
193      * @deprecated As of JDK version 1.1,
194      * replaced by {@code Calendar.set(year + 1900, month, date)}
195      * or {@code GregorianCalendar(year + 1900, month, date)}.
196      */
197     @Deprecated
Date(int year, int month, int date)198     public Date(int year, int month, int date) {
199         this(year, month, date, 0, 0, 0);
200     }
201 
202     /**
203      * Allocates a {@code Date} object and initializes it so that
204      * it represents the instant at the start of the minute specified by
205      * the {@code year}, {@code month}, {@code date},
206      * {@code hrs}, and {@code min} arguments, in the local
207      * time zone.
208      *
209      * @param   year    the year minus 1900.
210      * @param   month   the month between 0-11.
211      * @param   date    the day of the month between 1-31.
212      * @param   hrs     the hours between 0-23.
213      * @param   min     the minutes between 0-59.
214      * @see     java.util.Calendar
215      * @deprecated As of JDK version 1.1,
216      * replaced by {@code Calendar.set(year + 1900, month, date, hrs, min)}
217      * or {@code GregorianCalendar(year + 1900, month, date, hrs, min)}.
218      */
219     @Deprecated
Date(int year, int month, int date, int hrs, int min)220     public Date(int year, int month, int date, int hrs, int min) {
221         this(year, month, date, hrs, min, 0);
222     }
223 
224     /**
225      * Allocates a {@code Date} object and initializes it so that
226      * it represents the instant at the start of the second specified
227      * by the {@code year}, {@code month}, {@code date},
228      * {@code hrs}, {@code min}, and {@code sec} arguments,
229      * in the local time zone.
230      *
231      * @param   year    the year minus 1900.
232      * @param   month   the month between 0-11.
233      * @param   date    the day of the month between 1-31.
234      * @param   hrs     the hours between 0-23.
235      * @param   min     the minutes between 0-59.
236      * @param   sec     the seconds between 0-59.
237      * @see     java.util.Calendar
238      * @deprecated As of JDK version 1.1,
239      * replaced by {@code Calendar.set(year + 1900, month, date, hrs, min, sec)}
240      * or {@code GregorianCalendar(year + 1900, month, date, hrs, min, sec)}.
241      */
242     @Deprecated
Date(int year, int month, int date, int hrs, int min, int sec)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} object and initializes it so that
262      * it represents the date and time indicated by the string
263      * {@code s}, 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)}.
271      */
272     @Deprecated
Date(String s)273     public Date(String s) {
274         this(parse(s));
275     }
276 
277     /**
278      * Return a copy of this object.
279      */
clone()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 {@code Date} 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, hrs, min, sec)}
312      * or {@code GregorianCalendar(year + 1900, month, date, hrs, min, sec)}, using a UTC
313      * {@code TimeZone}, followed by {@code Calendar.getTime().getTime()}.
314      */
315     @Deprecated
UTC(int year, int month, int date, int hrs, int min, int sec)316     public static long UTC(int year, int month, int date,
317                            int hrs, int min, int sec) {
318         int y = year + 1900;
319         // month is 0-based. So we have to normalize month to support Long.MAX_VALUE.
320         if (month >= 12) {
321             y += month / 12;
322             month %= 12;
323         } else if (month < 0) {
324             y += CalendarUtils.floorDivide(month, 12);
325             month = CalendarUtils.mod(month, 12);
326         }
327         int m = month + 1;
328         BaseCalendar cal = getCalendarSystem(y);
329         BaseCalendar.Date udate = (BaseCalendar.Date) cal.newCalendarDate(null);
330         udate.setNormalizedDate(y, m, date).setTimeOfDay(hrs, min, sec, 0);
331 
332         // Use a Date instance to perform normalization. Its fastTime
333         // is the UTC value after the normalization.
334         Date d = new Date(0);
335         d.normalize(udate);
336         return d.fastTime;
337     }
338 
339     /**
340      * Attempts to interpret the string {@code s} as a representation
341      * of a date and time. If the attempt is successful, the time
342      * indicated is returned represented as the distance, measured in
343      * milliseconds, of that time from the epoch (00:00:00 GMT on
344      * January 1, 1970). If the attempt fails, an
345      * {@code IllegalArgumentException} is thrown.
346      * <p>
347      * It accepts many syntaxes; in particular, it recognizes the IETF
348      * standard date syntax: "Sat, 12 Aug 1995 13:30:00 GMT". It also
349      * understands the continental U.S. time-zone abbreviations, but for
350      * general use, a time-zone offset should be used: "Sat, 12 Aug 1995
351      * 13:30:00 GMT+0430" (4 hours, 30 minutes west of the Greenwich
352      * meridian). If no time zone is specified, the local time zone is
353      * assumed. GMT and UTC are considered equivalent.
354      * <p>
355      * The string {@code s} is processed from left to right, looking for
356      * data of interest. Any material in {@code s} that is within the
357      * ASCII parenthesis characters {@code (} and {@code )} is ignored.
358      * Parentheses may be nested. Otherwise, the only characters permitted
359      * within {@code s} are these ASCII characters:
360      * <blockquote><pre>
361      * abcdefghijklmnopqrstuvwxyz
362      * ABCDEFGHIJKLMNOPQRSTUVWXYZ
363      * 0123456789,+-:/</pre></blockquote>
364      * and whitespace characters.<p>
365      * A consecutive sequence of decimal digits is treated as a decimal
366      * number:<ul>
367      * <li>If a number is preceded by {@code +} or {@code -} and a year
368      *     has already been recognized, then the number is a time-zone
369      *     offset. If the number is less than 24, it is an offset measured
370      *     in hours. Otherwise, it is regarded as an offset in minutes,
371      *     expressed in 24-hour time format without punctuation. A
372      *     preceding {@code -} means a westward offset. Time zone offsets
373      *     are always relative to UTC (Greenwich). Thus, for example,
374      *     {@code -5} occurring in the string would mean "five hours west
375      *     of Greenwich" and {@code +0430} would mean "four hours and
376      *     thirty minutes east of Greenwich." It is permitted for the
377      *     string to specify {@code GMT}, {@code UT}, or {@code UTC}
378      *     redundantly-for example, {@code GMT-5} or {@code utc+0430}.
379      * <li>The number is regarded as a year number if one of the
380      *     following conditions is true:
381      * <ul>
382      *     <li>The number is equal to or greater than 70 and followed by a
383      *         space, comma, slash, or end of string
384      *     <li>The number is less than 70, and both a month and a day of
385      *         the month have already been recognized</li>
386      * </ul>
387      *     If the recognized year number is less than 100, it is
388      *     interpreted as an abbreviated year relative to a century of
389      *     which dates are within 80 years before and 19 years after
390      *     the time when the Date class is initialized.
391      *     After adjusting the year number, 1900 is subtracted from
392      *     it. For example, if the current year is 1999 then years in
393      *     the range 19 to 99 are assumed to mean 1919 to 1999, while
394      *     years from 0 to 18 are assumed to mean 2000 to 2018.  Note
395      *     that this is slightly different from the interpretation of
396      *     years less than 100 that is used in {@link java.text.SimpleDateFormat}.
397      * <li>If the number is followed by a colon, it is regarded as an hour,
398      *     unless an hour has already been recognized, in which case it is
399      *     regarded as a minute.
400      * <li>If the number is followed by a slash, it is regarded as a month
401      *     (it is decreased by 1 to produce a number in the range {@code 0}
402      *     to {@code 11}), unless a month has already been recognized, in
403      *     which case it is regarded as a day of the month.
404      * <li>If the number is followed by whitespace, a comma, a hyphen, or
405      *     end of string, then if an hour has been recognized but not a
406      *     minute, it is regarded as a minute; otherwise, if a minute has
407      *     been recognized but not a second, it is regarded as a second;
408      *     otherwise, it is regarded as a day of the month. </ul><p>
409      * A consecutive sequence of letters is regarded as a word and treated
410      * as follows:<ul>
411      * <li>A word that matches {@code AM}, ignoring case, is ignored (but
412      *     the parse fails if an hour has not been recognized or is less
413      *     than {@code 1} or greater than {@code 12}).
414      * <li>A word that matches {@code PM}, ignoring case, adds {@code 12}
415      *     to the hour (but the parse fails if an hour has not been
416      *     recognized or is less than {@code 1} or greater than {@code 12}).
417      * <li>Any word that matches any prefix of {@code SUNDAY, MONDAY, TUESDAY,
418      *     WEDNESDAY, THURSDAY, FRIDAY}, or {@code SATURDAY}, ignoring
419      *     case, is ignored. For example, {@code sat, Friday, TUE}, and
420      *     {@code Thurs} are ignored.
421      * <li>Otherwise, any word that matches any prefix of {@code JANUARY,
422      *     FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, AUGUST, SEPTEMBER,
423      *     OCTOBER, NOVEMBER}, or {@code DECEMBER}, ignoring case, and
424      *     considering them in the order given here, is recognized as
425      *     specifying a month and is converted to a number ({@code 0} to
426      *     {@code 11}). For example, {@code aug, Sept, april}, and
427      *     {@code NOV} are recognized as months. So is {@code Ma}, which
428      *     is recognized as {@code MARCH}, not {@code MAY}.
429      * <li>Any word that matches {@code GMT, UT}, or {@code UTC}, ignoring
430      *     case, is treated as referring to UTC.
431      * <li>Any word that matches {@code EST, CST, MST}, or {@code PST},
432      *     ignoring case, is recognized as referring to the time zone in
433      *     North America that is five, six, seven, or eight hours west of
434      *     Greenwich, respectively. Any word that matches {@code EDT, CDT,
435      *     MDT}, or {@code PDT}, ignoring case, is recognized as
436      *     referring to the same time zone, respectively, during daylight
437      *     saving time.</ul><p>
438      * Once the entire string s has been scanned, it is converted to a time
439      * result in one of two ways. If a time zone or time-zone offset has been
440      * recognized, then the year, month, day of month, hour, minute, and
441      * second are interpreted in UTC and then the time-zone offset is
442      * applied. Otherwise, the year, month, day of month, hour, minute, and
443      * second are interpreted in the local time zone.
444      *
445      * @param   s   a string to be parsed as a date.
446      * @return  the number of milliseconds since January 1, 1970, 00:00:00 GMT
447      *          represented by the string argument.
448      * @see     java.text.DateFormat
449      * @deprecated As of JDK version 1.1,
450      * replaced by {@code DateFormat.parse(String s)}.
451      */
452     @Deprecated
parse(String s)453     public static long parse(String s) {
454         int year = Integer.MIN_VALUE;
455         int mon = -1;
456         int mday = -1;
457         int hour = -1;
458         int min = -1;
459         int sec = -1;
460         int millis = -1;
461         int c = -1;
462         int i = 0;
463         int n = -1;
464         int wst = -1;
465         int tzoffset = -1;
466         int prevc = 0;
467     syntax:
468         {
469             if (s == null)
470                 break syntax;
471             int limit = s.length();
472             while (i < limit) {
473                 c = s.charAt(i);
474                 i++;
475                 if (c <= ' ' || c == ',')
476                     continue;
477                 if (c == '(') { // skip comments
478                     int depth = 1;
479                     while (i < limit) {
480                         c = s.charAt(i);
481                         i++;
482                         if (c == '(') depth++;
483                         else if (c == ')')
484                             if (--depth <= 0)
485                                 break;
486                     }
487                     continue;
488                 }
489                 if ('0' <= c && c <= '9') {
490                     n = c - '0';
491                     while (i < limit && '0' <= (c = s.charAt(i)) && c <= '9') {
492                         n = n * 10 + c - '0';
493                         i++;
494                     }
495                     if (prevc == '+' || prevc == '-' && year != Integer.MIN_VALUE) {
496                         // BEGIN Android-changed: Android specific time zone logic
497 
498                         if (tzoffset != 0 && tzoffset != -1)
499                             break syntax;
500 
501                         // timezone offset
502                         if (n < 24) {
503                             n = n * 60; // EG. "GMT-3"
504 
505                             // Support for Timezones of the form GMT-3:30. We look for an ':" and
506                             // parse the number following it as loosely as the original hours
507                             // section (i.e, no range or validity checks).
508                             int minutesPart = 0;
509                             if (i < limit && (s.charAt(i) == ':')) {
510                                 i++;
511                                 while (i < limit && '0' <= (c = s.charAt(i)) && c <= '9') {
512                                     minutesPart = (minutesPart * 10) + (c - '0');
513                                     i++;
514                                 }
515                             }
516 
517                             n += minutesPart;
518                         } else {
519                             n = (n % 100) + ((n / 100) * 60); // eg "GMT-0430"
520                         }
521 
522                         if (prevc == '+')   // plus means east of GMT
523                             n = -n;
524                         // END Android-changed: Android specific time zone logic
525 
526                         tzoffset = n;
527                     } else if (n >= 70)
528                         if (year != Integer.MIN_VALUE)
529                             break syntax;
530                         else if (c <= ' ' || c == ',' || c == '/' || i >= limit)
531                             // year = n < 1900 ? n : n - 1900;
532                             year = n;
533                         else
534                             break syntax;
535                     else if (c == ':')
536                         if (hour < 0)
537                             hour = (byte) n;
538                         else if (min < 0)
539                             min = (byte) n;
540                         else
541                             break syntax;
542                     else if (c == '/')
543                         if (mon < 0)
544                             mon = (byte) (n - 1);
545                         else if (mday < 0)
546                             mday = (byte) n;
547                         else
548                             break syntax;
549                     else if (i < limit && c != ',' && c > ' ' && c != '-')
550                         break syntax;
551                     else if (hour >= 0 && min < 0)
552                         min = (byte) n;
553                     else if (min >= 0 && sec < 0)
554                         sec = (byte) n;
555                     else if (mday < 0)
556                         mday = (byte) n;
557                     // Handle two-digit years < 70 (70-99 handled above).
558                     else if (year == Integer.MIN_VALUE && mon >= 0 && mday >= 0)
559                         year = n;
560                     else
561                         break syntax;
562                     prevc = 0;
563                 } else if (c == '/' || c == ':' || c == '+' || c == '-')
564                     prevc = c;
565                 else {
566                     int st = i - 1;
567                     while (i < limit) {
568                         c = s.charAt(i);
569                         if (!('A' <= c && c <= 'Z' || 'a' <= c && c <= 'z'))
570                             break;
571                         i++;
572                     }
573                     if (i <= st + 1)
574                         break syntax;
575                     int k;
576                     for (k = wtb.length; --k >= 0;)
577                         if (wtb[k].regionMatches(true, 0, s, st, i - st)) {
578                             int action = ttb[k];
579                             if (action != 0) {
580                                 if (action == 1) {  // pm
581                                     if (hour > 12 || hour < 1)
582                                         break syntax;
583                                     else if (hour < 12)
584                                         hour += 12;
585                                 } else if (action == 14) {  // am
586                                     if (hour > 12 || hour < 1)
587                                         break syntax;
588                                     else if (hour == 12)
589                                         hour = 0;
590                                 } else if (action <= 13) {  // month!
591                                     if (mon < 0)
592                                         mon = (byte) (action - 2);
593                                     else
594                                         break syntax;
595                                 } else {
596                                     tzoffset = action - 10000;
597                                 }
598                             }
599                             break;
600                         }
601                     if (k < 0)
602                         break syntax;
603                     prevc = 0;
604                 }
605             }
606             if (year == Integer.MIN_VALUE || mon < 0 || mday < 0)
607                 break syntax;
608             // Parse 2-digit years within the correct default century.
609             if (year < 100) {
610                 synchronized (Date.class) {
611                     if (defaultCenturyStart == 0) {
612                         defaultCenturyStart = gcal.getCalendarDate().getYear() - 80;
613                     }
614                 }
615                 year += (defaultCenturyStart / 100) * 100;
616                 if (year < defaultCenturyStart) year += 100;
617             }
618             if (sec < 0)
619                 sec = 0;
620             if (min < 0)
621                 min = 0;
622             if (hour < 0)
623                 hour = 0;
624             BaseCalendar cal = getCalendarSystem(year);
625             if (tzoffset == -1)  { // no time zone specified, have to use local
626                 BaseCalendar.Date ldate = (BaseCalendar.Date) cal.newCalendarDate(TimeZone.getDefaultRef());
627                 ldate.setDate(year, mon + 1, mday);
628                 ldate.setTimeOfDay(hour, min, sec, 0);
629                 return cal.getTime(ldate);
630             }
631             BaseCalendar.Date udate = (BaseCalendar.Date) cal.newCalendarDate(null); // no time zone
632             udate.setDate(year, mon + 1, mday);
633             udate.setTimeOfDay(hour, min, sec, 0);
634             return cal.getTime(udate) + tzoffset * (60 * 1000);
635         }
636         // syntax error
637         throw new IllegalArgumentException();
638     }
639     private static final String wtb[] = {
640         "am", "pm",
641         "monday", "tuesday", "wednesday", "thursday", "friday",
642         "saturday", "sunday",
643         "january", "february", "march", "april", "may", "june",
644         "july", "august", "september", "october", "november", "december",
645         "gmt", "ut", "utc", "est", "edt", "cst", "cdt",
646         "mst", "mdt", "pst", "pdt"
647     };
648     private static final int ttb[] = {
649         14, 1, 0, 0, 0, 0, 0, 0, 0,
650         2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
651         10000 + 0, 10000 + 0, 10000 + 0,    // GMT/UT/UTC
652         10000 + 5 * 60, 10000 + 4 * 60,     // EST/EDT
653         10000 + 6 * 60, 10000 + 5 * 60,     // CST/CDT
654         10000 + 7 * 60, 10000 + 6 * 60,     // MST/MDT
655         10000 + 8 * 60, 10000 + 7 * 60      // PST/PDT
656     };
657 
658     /**
659      * Returns a value that is the result of subtracting 1900 from the
660      * year that contains or begins with the instant in time represented
661      * by this {@code Date} object, as interpreted in the local
662      * time zone.
663      *
664      * @return  the year represented by this date, minus 1900.
665      * @see     java.util.Calendar
666      * @deprecated As of JDK version 1.1,
667      * replaced by {@code Calendar.get(Calendar.YEAR) - 1900}.
668      */
669     @Deprecated
getYear()670     public int getYear() {
671         return normalize().getYear() - 1900;
672     }
673 
674     /**
675      * Sets the year of this {@code Date} object to be the specified
676      * value plus 1900. This {@code Date} object is modified so
677      * that it represents a point in time within the specified year,
678      * with the month, date, hour, minute, and second the same as
679      * before, as interpreted in the local time zone. (Of course, if
680      * the date was February 29, for example, and the year is set to a
681      * non-leap year, then the new date will be treated as if it were
682      * on March 1.)
683      *
684      * @param   year    the year value.
685      * @see     java.util.Calendar
686      * @deprecated As of JDK version 1.1,
687      * replaced by {@code Calendar.set(Calendar.YEAR, year + 1900)}.
688      */
689     @Deprecated
setYear(int year)690     public void setYear(int year) {
691         getCalendarDate().setNormalizedYear(year + 1900);
692     }
693 
694     /**
695      * Returns a number representing the month that contains or begins
696      * with the instant in time represented by this {@code Date} object.
697      * The value returned is between {@code 0} and {@code 11},
698      * with the value {@code 0} representing January.
699      *
700      * @return  the month represented by this date.
701      * @see     java.util.Calendar
702      * @deprecated As of JDK version 1.1,
703      * replaced by {@code Calendar.get(Calendar.MONTH)}.
704      */
705     @Deprecated
getMonth()706     public int getMonth() {
707         return normalize().getMonth() - 1; // adjust 1-based to 0-based
708     }
709 
710     /**
711      * Sets the month of this date to the specified value. This
712      * {@code Date} object is modified so that it represents a point
713      * in time within the specified month, with the year, date, hour,
714      * minute, and second the same as before, as interpreted in the
715      * local time zone. If the date was October 31, for example, and
716      * the month is set to June, then the new date will be treated as
717      * if it were on July 1, because June has only 30 days.
718      *
719      * @param   month   the month value between 0-11.
720      * @see     java.util.Calendar
721      * @deprecated As of JDK version 1.1,
722      * replaced by {@code Calendar.set(Calendar.MONTH, int month)}.
723      */
724     @Deprecated
setMonth(int month)725     public void setMonth(int month) {
726         int y = 0;
727         if (month >= 12) {
728             y = month / 12;
729             month %= 12;
730         } else if (month < 0) {
731             y = CalendarUtils.floorDivide(month, 12);
732             month = CalendarUtils.mod(month, 12);
733         }
734         BaseCalendar.Date d = getCalendarDate();
735         if (y != 0) {
736             d.setNormalizedYear(d.getNormalizedYear() + y);
737         }
738         d.setMonth(month + 1); // adjust 0-based to 1-based month numbering
739     }
740 
741     /**
742      * Returns the day of the month represented by this {@code Date} object.
743      * The value returned is between {@code 1} and {@code 31}
744      * representing the day of the month that contains or begins with the
745      * instant in time represented by this {@code Date} object, as
746      * interpreted in the local time zone.
747      *
748      * @return  the day of the month represented by this date.
749      * @see     java.util.Calendar
750      * @deprecated As of JDK version 1.1,
751      * replaced by {@code Calendar.get(Calendar.DAY_OF_MONTH)}.
752      */
753     @Deprecated
getDate()754     public int getDate() {
755         return normalize().getDayOfMonth();
756     }
757 
758     /**
759      * Sets the day of the month of this {@code Date} object to the
760      * specified value. This {@code Date} object is modified so that
761      * it represents a point in time within the specified day of the
762      * month, with the year, month, hour, minute, and second the same
763      * as before, as interpreted in the local time zone. If the date
764      * was April 30, for example, and the date is set to 31, then it
765      * will be treated as if it were on May 1, because April has only
766      * 30 days.
767      *
768      * @param   date   the day of the month value between 1-31.
769      * @see     java.util.Calendar
770      * @deprecated As of JDK version 1.1,
771      * replaced by {@code Calendar.set(Calendar.DAY_OF_MONTH, int date)}.
772      */
773     @Deprecated
setDate(int date)774     public void setDate(int date) {
775         getCalendarDate().setDayOfMonth(date);
776     }
777 
778     /**
779      * Returns the day of the week represented by this date. The
780      * returned value ({@code 0} = Sunday, {@code 1} = Monday,
781      * {@code 2} = Tuesday, {@code 3} = Wednesday, {@code 4} =
782      * Thursday, {@code 5} = Friday, {@code 6} = Saturday)
783      * represents the day of the week that contains or begins with
784      * the instant in time represented by this {@code Date} object,
785      * as interpreted in the local time zone.
786      *
787      * @return  the day of the week represented by this date.
788      * @see     java.util.Calendar
789      * @deprecated As of JDK version 1.1,
790      * replaced by {@code Calendar.get(Calendar.DAY_OF_WEEK)}.
791      */
792     @Deprecated
getDay()793     public int getDay() {
794         return normalize().getDayOfWeek() - BaseCalendar.SUNDAY;
795     }
796 
797     /**
798      * Returns the hour represented by this {@code Date} object. The
799      * returned value is a number ({@code 0} through {@code 23})
800      * representing the hour within the day that contains or begins
801      * with the instant in time represented by this {@code Date}
802      * object, as interpreted in the local time zone.
803      *
804      * @return  the hour represented by this date.
805      * @see     java.util.Calendar
806      * @deprecated As of JDK version 1.1,
807      * replaced by {@code Calendar.get(Calendar.HOUR_OF_DAY)}.
808      */
809     @Deprecated
getHours()810     public int getHours() {
811         return normalize().getHours();
812     }
813 
814     /**
815      * Sets the hour of this {@code Date} object to the specified value.
816      * This {@code Date} object is modified so that it represents a point
817      * in time within the specified hour of the day, with the year, month,
818      * date, minute, and second the same as before, as interpreted in the
819      * local time zone.
820      *
821      * @param   hours   the hour value.
822      * @see     java.util.Calendar
823      * @deprecated As of JDK version 1.1,
824      * replaced by {@code Calendar.set(Calendar.HOUR_OF_DAY, int hours)}.
825      */
826     @Deprecated
setHours(int hours)827     public void setHours(int hours) {
828         getCalendarDate().setHours(hours);
829     }
830 
831     /**
832      * Returns the number of minutes past the hour represented by this date,
833      * as interpreted in the local time zone.
834      * The value returned is between {@code 0} and {@code 59}.
835      *
836      * @return  the number of minutes past the hour represented by this date.
837      * @see     java.util.Calendar
838      * @deprecated As of JDK version 1.1,
839      * replaced by {@code Calendar.get(Calendar.MINUTE)}.
840      */
841     @Deprecated
getMinutes()842     public int getMinutes() {
843         return normalize().getMinutes();
844     }
845 
846     /**
847      * Sets the minutes of this {@code Date} object to the specified value.
848      * This {@code Date} object is modified so that it represents a point
849      * in time within the specified minute of the hour, with the year, month,
850      * date, hour, and second the same as before, as interpreted in the
851      * local time zone.
852      *
853      * @param   minutes   the value of the minutes.
854      * @see     java.util.Calendar
855      * @deprecated As of JDK version 1.1,
856      * replaced by {@code Calendar.set(Calendar.MINUTE, int minutes)}.
857      */
858     @Deprecated
setMinutes(int minutes)859     public void setMinutes(int minutes) {
860         getCalendarDate().setMinutes(minutes);
861     }
862 
863     /**
864      * Returns the number of seconds past the minute represented by this date.
865      * The value returned is between {@code 0} and {@code 61}. The
866      * values {@code 60} and {@code 61} can only occur on those
867      * Java Virtual Machines that take leap seconds into account.
868      *
869      * @return  the number of seconds past the minute represented by this date.
870      * @see     java.util.Calendar
871      * @deprecated As of JDK version 1.1,
872      * replaced by {@code Calendar.get(Calendar.SECOND)}.
873      */
874     @Deprecated
getSeconds()875     public int getSeconds() {
876         return normalize().getSeconds();
877     }
878 
879     /**
880      * Sets the seconds of this {@code Date} to the specified value.
881      * This {@code Date} object is modified so that it represents a
882      * point in time within the specified second of the minute, with
883      * the year, month, date, hour, and minute the same as before, as
884      * interpreted in the local time zone.
885      *
886      * @param   seconds   the seconds value.
887      * @see     java.util.Calendar
888      * @deprecated As of JDK version 1.1,
889      * replaced by {@code Calendar.set(Calendar.SECOND, int seconds)}.
890      */
891     @Deprecated
setSeconds(int seconds)892     public void setSeconds(int seconds) {
893         getCalendarDate().setSeconds(seconds);
894     }
895 
896     /**
897      * Returns the number of milliseconds since January 1, 1970, 00:00:00 GMT
898      * represented by this {@code Date} object.
899      *
900      * @return  the number of milliseconds since January 1, 1970, 00:00:00 GMT
901      *          represented by this date.
902      */
getTime()903     public long getTime() {
904         return getTimeImpl();
905     }
906 
getTimeImpl()907     private final long getTimeImpl() {
908         if (cdate != null && !cdate.isNormalized()) {
909             normalize();
910         }
911         return fastTime;
912     }
913 
914     /**
915      * Sets this {@code Date} object to represent a point in time that is
916      * {@code time} milliseconds after January 1, 1970 00:00:00 GMT.
917      *
918      * @param   time   the number of milliseconds.
919      */
setTime(long time)920     public void setTime(long time) {
921         fastTime = time;
922         cdate = null;
923     }
924 
925     /**
926      * Tests if this date is before the specified date.
927      *
928      * @param   when   a date.
929      * @return  {@code true} if and only if the instant of time
930      *            represented by this {@code Date} object is strictly
931      *            earlier than the instant represented by {@code when};
932      *          {@code false} otherwise.
933      * @exception NullPointerException if {@code when} is null.
934      */
before(Date when)935     public boolean before(Date when) {
936         return getMillisOf(this) < getMillisOf(when);
937     }
938 
939     /**
940      * Tests if this date is after the specified date.
941      *
942      * @param   when   a date.
943      * @return  {@code true} if and only if the instant represented
944      *          by this {@code Date} object is strictly later than the
945      *          instant represented by {@code when};
946      *          {@code false} otherwise.
947      * @exception NullPointerException if {@code when} is null.
948      */
after(Date when)949     public boolean after(Date when) {
950         return getMillisOf(this) > getMillisOf(when);
951     }
952 
953     /**
954      * Compares two dates for equality.
955      * The result is {@code true} if and only if the argument is
956      * not {@code null} and is a {@code Date} object that
957      * represents the same point in time, to the millisecond, as this object.
958      * <p>
959      * Thus, two {@code Date} objects are equal if and only if the
960      * {@code getTime} method returns the same {@code long}
961      * value for both.
962      *
963      * @param   obj   the object to compare with.
964      * @return  {@code true} if the objects are the same;
965      *          {@code false} otherwise.
966      * @see     java.util.Date#getTime()
967      */
equals(Object obj)968     public boolean equals(Object obj) {
969         return obj instanceof Date && getTime() == ((Date) obj).getTime();
970     }
971 
972     /**
973      * Returns the millisecond value of this {@code Date} object
974      * without affecting its internal state.
975      */
getMillisOf(Date date)976     static final long getMillisOf(Date date) {
977         if (date.getClass() != Date.class) {
978             return date.getTime();
979         }
980         if (date.cdate == null || date.cdate.isNormalized()) {
981             return date.fastTime;
982         }
983         BaseCalendar.Date d = (BaseCalendar.Date) date.cdate.clone();
984         return gcal.getTime(d);
985     }
986 
987     /**
988      * Compares two Dates for ordering.
989      *
990      * @param   anotherDate   the {@code Date} to be compared.
991      * @return  the value {@code 0} if the argument Date is equal to
992      *          this Date; a value less than {@code 0} if this Date
993      *          is before the Date argument; and a value greater than
994      *      {@code 0} if this Date is after the Date argument.
995      * @since   1.2
996      * @exception NullPointerException if {@code anotherDate} is null.
997      */
compareTo(Date anotherDate)998     public int compareTo(Date anotherDate) {
999         long thisTime = getMillisOf(this);
1000         long anotherTime = getMillisOf(anotherDate);
1001         return (thisTime<anotherTime ? -1 : (thisTime==anotherTime ? 0 : 1));
1002     }
1003 
1004     /**
1005      * Returns a hash code value for this object. The result is the
1006      * exclusive OR of the two halves of the primitive {@code long}
1007      * value returned by the {@link Date#getTime}
1008      * method. That is, the hash code is the value of the expression:
1009      * <blockquote><pre>{@code
1010      * (int)(this.getTime()^(this.getTime() >>> 32))
1011      * }</pre></blockquote>
1012      *
1013      * @return  a hash code value for this object.
1014      */
hashCode()1015     public int hashCode() {
1016         long ht = this.getTime();
1017         return (int) ht ^ (int) (ht >> 32);
1018     }
1019 
1020     /**
1021      * Converts this {@code Date} object to a {@code String}
1022      * of the form:
1023      * <blockquote><pre>
1024      * dow mon dd hh:mm:ss zzz yyyy</pre></blockquote>
1025      * where:<ul>
1026      * <li>{@code dow} is the day of the week ({@code Sun, Mon, Tue, Wed,
1027      *     Thu, Fri, Sat}).
1028      * <li>{@code mon} is the month ({@code Jan, Feb, Mar, Apr, May, Jun,
1029      *     Jul, Aug, Sep, Oct, Nov, Dec}).
1030      * <li>{@code dd} is the day of the month ({@code 01} through
1031      *     {@code 31}), as two decimal digits.
1032      * <li>{@code hh} is the hour of the day ({@code 00} through
1033      *     {@code 23}), as two decimal digits.
1034      * <li>{@code mm} is the minute within the hour ({@code 00} through
1035      *     {@code 59}), as two decimal digits.
1036      * <li>{@code ss} is the second within the minute ({@code 00} through
1037      *     {@code 61}, as two decimal digits.
1038      * <li>{@code zzz} is the time zone (and may reflect daylight saving
1039      *     time). Standard time zone abbreviations include those
1040      *     recognized by the method {@code parse}. If time zone
1041      *     information is not available, then {@code zzz} is empty -
1042      *     that is, it consists of no characters at all.
1043      * <li>{@code yyyy} is the year, as four decimal digits.
1044      * </ul>
1045      *
1046      * @return  a string representation of this date.
1047      * @see     java.util.Date#toLocaleString()
1048      * @see     java.util.Date#toGMTString()
1049      */
toString()1050     public String toString() {
1051         // "EEE MMM dd HH:mm:ss zzz yyyy";
1052         BaseCalendar.Date date = normalize();
1053         StringBuilder sb = new StringBuilder(28);
1054         int index = date.getDayOfWeek();
1055         if (index == BaseCalendar.SUNDAY) {
1056             index = 8;
1057         }
1058         convertToAbbr(sb, wtb[index]).append(' ');                        // EEE
1059         convertToAbbr(sb, wtb[date.getMonth() - 1 + 2 + 7]).append(' ');  // MMM
1060         CalendarUtils.sprintf0d(sb, date.getDayOfMonth(), 2).append(' '); // dd
1061 
1062         CalendarUtils.sprintf0d(sb, date.getHours(), 2).append(':');   // HH
1063         CalendarUtils.sprintf0d(sb, date.getMinutes(), 2).append(':'); // mm
1064         CalendarUtils.sprintf0d(sb, date.getSeconds(), 2).append(' '); // ss
1065         TimeZone zi = date.getZone();
1066         if (zi != null) {
1067             sb.append(zi.getDisplayName(date.isDaylightTime(), TimeZone.SHORT, Locale.US)); // zzz
1068         } else {
1069             sb.append("GMT");
1070         }
1071         sb.append(' ').append(date.getYear());  // yyyy
1072         return sb.toString();
1073     }
1074 
1075     /**
1076      * Converts the given name to its 3-letter abbreviation (e.g.,
1077      * "monday" -> "Mon") and stored the abbreviation in the given
1078      * {@code StringBuilder}.
1079      */
convertToAbbr(StringBuilder sb, String name)1080     private static final StringBuilder convertToAbbr(StringBuilder sb, String name) {
1081         sb.append(Character.toUpperCase(name.charAt(0)));
1082         sb.append(name.charAt(1)).append(name.charAt(2));
1083         return sb;
1084     }
1085 
1086     /**
1087      * Creates a string representation of this {@code Date} object in an
1088      * implementation-dependent form. The intent is that the form should
1089      * be familiar to the user of the Java application, wherever it may
1090      * happen to be running. The intent is comparable to that of the
1091      * "{@code %c}" format supported by the {@code strftime()}
1092      * function of ISO&nbsp;C.
1093      *
1094      * @return  a string representation of this date, using the locale
1095      *          conventions.
1096      * @see     java.text.DateFormat
1097      * @see     java.util.Date#toString()
1098      * @see     java.util.Date#toGMTString()
1099      * @deprecated As of JDK version 1.1,
1100      * replaced by {@code DateFormat.format(Date date)}.
1101      */
1102     @Deprecated
toLocaleString()1103     public String toLocaleString() {
1104         DateFormat formatter = DateFormat.getDateTimeInstance();
1105         return formatter.format(this);
1106     }
1107 
1108     /**
1109      * Creates a string representation of this {@code Date} object of
1110      * the form:
1111      * <blockquote><pre>
1112      * d mon yyyy hh:mm:ss GMT</pre></blockquote>
1113      * where:<ul>
1114      * <li><i>d</i> is the day of the month ({@code 1} through {@code 31}),
1115      *     as one or two decimal digits.
1116      * <li><i>mon</i> is the month ({@code Jan, Feb, Mar, Apr, May, Jun, Jul,
1117      *     Aug, Sep, Oct, Nov, Dec}).
1118      * <li><i>yyyy</i> is the year, as four decimal digits.
1119      * <li><i>hh</i> is the hour of the day ({@code 00} through {@code 23}),
1120      *     as two decimal digits.
1121      * <li><i>mm</i> is the minute within the hour ({@code 00} through
1122      *     {@code 59}), as two decimal digits.
1123      * <li><i>ss</i> is the second within the minute ({@code 00} through
1124      *     {@code 61}), as two decimal digits.
1125      * <li><i>GMT</i> is exactly the ASCII letters "{@code GMT}" to indicate
1126      *     Greenwich Mean Time.
1127      * </ul><p>
1128      * The result does not depend on the local time zone.
1129      *
1130      * @return  a string representation of this date, using the Internet GMT
1131      *          conventions.
1132      * @see     java.text.DateFormat
1133      * @see     java.util.Date#toString()
1134      * @see     java.util.Date#toLocaleString()
1135      * @deprecated As of JDK version 1.1,
1136      * replaced by {@code DateFormat.format(Date date)}, using a
1137      * GMT {@code TimeZone}.
1138      */
1139     @Deprecated
toGMTString()1140     public String toGMTString() {
1141         // d MMM yyyy HH:mm:ss 'GMT'
1142         long t = getTime();
1143         BaseCalendar cal = getCalendarSystem(t);
1144         BaseCalendar.Date date =
1145             (BaseCalendar.Date) cal.getCalendarDate(getTime(), (TimeZone)null);
1146         StringBuilder sb = new StringBuilder(32);
1147         CalendarUtils.sprintf0d(sb, date.getDayOfMonth(), 1).append(' '); // d
1148         convertToAbbr(sb, wtb[date.getMonth() - 1 + 2 + 7]).append(' ');  // MMM
1149         sb.append(date.getYear()).append(' ');                            // yyyy
1150         CalendarUtils.sprintf0d(sb, date.getHours(), 2).append(':');      // HH
1151         CalendarUtils.sprintf0d(sb, date.getMinutes(), 2).append(':');    // mm
1152         CalendarUtils.sprintf0d(sb, date.getSeconds(), 2);                // ss
1153         sb.append(" GMT");                                                // ' GMT'
1154         return sb.toString();
1155     }
1156 
1157     /**
1158      * Returns the offset, measured in minutes, for the local time zone
1159      * relative to UTC that is appropriate for the time represented by
1160      * this {@code Date} object.
1161      * <p>
1162      * For example, in Massachusetts, five time zones west of Greenwich:
1163      * <blockquote><pre>
1164      * new Date(96, 1, 14).getTimezoneOffset() returns 300</pre></blockquote>
1165      * because on February 14, 1996, standard time (Eastern Standard Time)
1166      * is in use, which is offset five hours from UTC; but:
1167      * <blockquote><pre>
1168      * new Date(96, 5, 1).getTimezoneOffset() returns 240</pre></blockquote>
1169      * because on June 1, 1996, daylight saving time (Eastern Daylight Time)
1170      * is in use, which is offset only four hours from UTC.<p>
1171      * This method produces the same result as if it computed:
1172      * <blockquote><pre>
1173      * (this.getTime() - UTC(this.getYear(),
1174      *                       this.getMonth(),
1175      *                       this.getDate(),
1176      *                       this.getHours(),
1177      *                       this.getMinutes(),
1178      *                       this.getSeconds())) / (60 * 1000)
1179      * </pre></blockquote>
1180      *
1181      * @return  the time-zone offset, in minutes, for the current time zone.
1182      * @see     java.util.Calendar#ZONE_OFFSET
1183      * @see     java.util.Calendar#DST_OFFSET
1184      * @see     java.util.TimeZone#getDefault
1185      * @deprecated As of JDK version 1.1,
1186      * replaced by {@code -(Calendar.get(Calendar.ZONE_OFFSET) +
1187      * Calendar.get(Calendar.DST_OFFSET)) / (60 * 1000)}.
1188      */
1189     @Deprecated
getTimezoneOffset()1190     public int getTimezoneOffset() {
1191         int zoneOffset;
1192         if (cdate == null) {
1193             // Android-changed: Android specific time zone logic
1194             GregorianCalendar cal = new GregorianCalendar(fastTime);
1195             zoneOffset = (cal.get(Calendar.ZONE_OFFSET) + cal.get(Calendar.DST_OFFSET));
1196         } else {
1197             normalize();
1198             zoneOffset = cdate.getZoneOffset();
1199         }
1200         return -zoneOffset/60000;  // convert to minutes
1201     }
1202 
getCalendarDate()1203     private final BaseCalendar.Date getCalendarDate() {
1204         if (cdate == null) {
1205             BaseCalendar cal = getCalendarSystem(fastTime);
1206             cdate = (BaseCalendar.Date) cal.getCalendarDate(fastTime,
1207                                                             TimeZone.getDefaultRef());
1208         }
1209         return cdate;
1210     }
1211 
normalize()1212     private final BaseCalendar.Date normalize() {
1213         if (cdate == null) {
1214             BaseCalendar cal = getCalendarSystem(fastTime);
1215             cdate = (BaseCalendar.Date) cal.getCalendarDate(fastTime,
1216                                                             TimeZone.getDefaultRef());
1217             return cdate;
1218         }
1219 
1220         // Normalize cdate with the TimeZone in cdate first. This is
1221         // required for the compatible behavior.
1222         if (!cdate.isNormalized()) {
1223             cdate = normalize(cdate);
1224         }
1225 
1226         // If the default TimeZone has changed, then recalculate the
1227         // fields with the new TimeZone.
1228         TimeZone tz = TimeZone.getDefaultRef();
1229         if (tz != cdate.getZone()) {
1230             cdate.setZone(tz);
1231             CalendarSystem cal = getCalendarSystem(cdate);
1232             cal.getCalendarDate(fastTime, cdate);
1233         }
1234         return cdate;
1235     }
1236 
1237     // fastTime and the returned data are in sync upon return.
normalize(BaseCalendar.Date date)1238     private final BaseCalendar.Date normalize(BaseCalendar.Date date) {
1239         int y = date.getNormalizedYear();
1240         int m = date.getMonth();
1241         int d = date.getDayOfMonth();
1242         int hh = date.getHours();
1243         int mm = date.getMinutes();
1244         int ss = date.getSeconds();
1245         int ms = date.getMillis();
1246         TimeZone tz = date.getZone();
1247 
1248         // If the specified year can't be handled using a long value
1249         // in milliseconds, GregorianCalendar is used for full
1250         // compatibility with underflow and overflow. This is required
1251         // by some JCK tests. The limits are based max year values -
1252         // years that can be represented by max values of d, hh, mm,
1253         // ss and ms. Also, let GregorianCalendar handle the default
1254         // cutover year so that we don't need to worry about the
1255         // transition here.
1256         if (y == 1582 || y > 280000000 || y < -280000000) {
1257             if (tz == null) {
1258                 tz = TimeZone.getTimeZone("GMT");
1259             }
1260             GregorianCalendar gc = new GregorianCalendar(tz);
1261             gc.clear();
1262             gc.set(GregorianCalendar.MILLISECOND, ms);
1263             gc.set(y, m-1, d, hh, mm, ss);
1264             fastTime = gc.getTimeInMillis();
1265             BaseCalendar cal = getCalendarSystem(fastTime);
1266             date = (BaseCalendar.Date) cal.getCalendarDate(fastTime, tz);
1267             return date;
1268         }
1269 
1270         BaseCalendar cal = getCalendarSystem(y);
1271         if (cal != getCalendarSystem(date)) {
1272             date = (BaseCalendar.Date) cal.newCalendarDate(tz);
1273             date.setNormalizedDate(y, m, d).setTimeOfDay(hh, mm, ss, ms);
1274         }
1275         // Perform the GregorianCalendar-style normalization.
1276         fastTime = cal.getTime(date);
1277 
1278         // In case the normalized date requires the other calendar
1279         // system, we need to recalculate it using the other one.
1280         BaseCalendar ncal = getCalendarSystem(fastTime);
1281         if (ncal != cal) {
1282             date = (BaseCalendar.Date) ncal.newCalendarDate(tz);
1283             date.setNormalizedDate(y, m, d).setTimeOfDay(hh, mm, ss, ms);
1284             fastTime = ncal.getTime(date);
1285         }
1286         return date;
1287     }
1288 
1289     /**
1290      * Returns the Gregorian or Julian calendar system to use with the
1291      * given date. Use Gregorian from October 15, 1582.
1292      *
1293      * @param year normalized calendar year (not -1900)
1294      * @return the CalendarSystem to use for the specified date
1295      */
getCalendarSystem(int year)1296     private static final BaseCalendar getCalendarSystem(int year) {
1297         if (year >= 1582) {
1298             return gcal;
1299         }
1300         return getJulianCalendar();
1301     }
1302 
getCalendarSystem(long utc)1303     private static final BaseCalendar getCalendarSystem(long utc) {
1304         // Quickly check if the time stamp given by `utc' is the Epoch
1305         // or later. If it's before 1970, we convert the cutover to
1306         // local time to compare.
1307         if (utc >= 0
1308             || utc >= GregorianCalendar.DEFAULT_GREGORIAN_CUTOVER
1309                         - TimeZone.getDefaultRef().getOffset(utc)) {
1310             return gcal;
1311         }
1312         return getJulianCalendar();
1313     }
1314 
getCalendarSystem(BaseCalendar.Date cdate)1315     private static final BaseCalendar getCalendarSystem(BaseCalendar.Date cdate) {
1316         if (jcal == null) {
1317             return gcal;
1318         }
1319         if (cdate.getEra() != null) {
1320             return jcal;
1321         }
1322         return gcal;
1323     }
1324 
getJulianCalendar()1325     private static final synchronized BaseCalendar getJulianCalendar() {
1326         if (jcal == null) {
1327             jcal = (BaseCalendar) CalendarSystem.forName("julian");
1328         }
1329         return jcal;
1330     }
1331 
1332     /**
1333      * Save the state of this object to a stream (i.e., serialize it).
1334      *
1335      * @serialData The value returned by {@code getTime()}
1336      *             is emitted (long).  This represents the offset from
1337      *             January 1, 1970, 00:00:00 GMT in milliseconds.
1338      */
writeObject(ObjectOutputStream s)1339     private void writeObject(ObjectOutputStream s)
1340          throws IOException
1341     {
1342         s.defaultWriteObject();
1343         s.writeLong(getTimeImpl());
1344     }
1345 
1346     /**
1347      * Reconstitute this object from a stream (i.e., deserialize it).
1348      */
readObject(ObjectInputStream s)1349     private void readObject(ObjectInputStream s)
1350          throws IOException, ClassNotFoundException
1351     {
1352         s.defaultReadObject();
1353         fastTime = s.readLong();
1354     }
1355 
1356     /**
1357      * Obtains an instance of {@code Date} from an {@code Instant} object.
1358      * <p>
1359      * {@code Instant} uses a precision of nanoseconds, whereas {@code Date}
1360      * uses a precision of milliseconds.  The conversion will truncate any
1361      * excess precision information as though the amount in nanoseconds was
1362      * subject to integer division by one million.
1363      * <p>
1364      * {@code Instant} can store points on the time-line further in the future
1365      * and further in the past than {@code Date}. In this scenario, this method
1366      * will throw an exception.
1367      *
1368      * @param instant  the instant to convert
1369      * @return a {@code Date} representing the same point on the time-line as
1370      *  the provided instant
1371      * @exception NullPointerException if {@code instant} is null.
1372      * @exception IllegalArgumentException if the instant is too large to
1373      *  represent as a {@code Date}
1374      * @since 1.8
1375      */
from(Instant instant)1376     public static Date from(Instant instant) {
1377         try {
1378             return new Date(instant.toEpochMilli());
1379         } catch (ArithmeticException ex) {
1380             throw new IllegalArgumentException(ex);
1381         }
1382     }
1383 
1384     /**
1385      * Converts this {@code Date} object to an {@code Instant}.
1386      * <p>
1387      * The conversion creates an {@code Instant} that represents the same
1388      * point on the time-line as this {@code Date}.
1389      *
1390      * @return an instant representing the same point on the time-line as
1391      *  this {@code Date} object
1392      * @since 1.8
1393      */
toInstant()1394     public Instant toInstant() {
1395         return Instant.ofEpochMilli(getTime());
1396     }
1397 }
1398