Home | History | Annotate | Download | only in util
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  * Copyright (c) 1994, 2013, 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</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                         // BEGIN Android-changed: Android specific time zone logic
    498 
    499                         if (tzoffset != 0 && tzoffset != -1)
    500                             break syntax;
    501 
    502                         // timezone offset
    503                         if (n < 24) {
    504                             n = n * 60; // EG. "GMT-3"
    505 
    506                             // Support for Timezones of the form GMT-3:30. We look for an ':" and
    507                             // parse the number following it as loosely as the original hours
    508                             // section (i.e, no range or validity checks).
    509                             int minutesPart = 0;
    510                             if (i < limit && (s.charAt(i) == ':')) {
    511                                 i++;
    512                                 while (i < limit && '0' <= (c = s.charAt(i)) && c <= '9') {
    513                                     minutesPart = (minutesPart * 10) + (c - '0');
    514                                     i++;
    515                                 }
    516                             }
    517 
    518                             n += minutesPart;
    519                         } else {
    520                             n = (n % 100) + ((n / 100) * 60); // eg "GMT-0430"
    521                         }
    522 
    523                         if (prevc == '+')   // plus means east of GMT
    524                             n = -n;
    525                         // END Android-changed: Android specific time zone logic
    526 
    527                         tzoffset = n;
    528                     } else if (n >= 70)
    529                         if (year != Integer.MIN_VALUE)
    530                             break syntax;
    531                         else if (c <= ' ' || c == ',' || c == '/' || i >= limit)
    532                             // year = n < 1900 ? n : n - 1900;
    533                             year = n;
    534                         else
    535                             break syntax;
    536                     else if (c == ':')
    537                         if (hour < 0)
    538                             hour = (byte) n;
    539                         else if (min < 0)
    540                             min = (byte) n;
    541                         else
    542                             break syntax;
    543                     else if (c == '/')
    544                         if (mon < 0)
    545                             mon = (byte) (n - 1);
    546                         else if (mday < 0)
    547                             mday = (byte) n;
    548                         else
    549                             break syntax;
    550                     else if (i < limit && c != ',' && c > ' ' && c != '-')
    551                         break syntax;
    552                     else if (hour >= 0 && min < 0)
    553                         min = (byte) n;
    554                     else if (min >= 0 && sec < 0)
    555                         sec = (byte) n;
    556                     else if (mday < 0)
    557                         mday = (byte) n;
    558                     // Handle two-digit years < 70 (70-99 handled above).
    559                     else if (year == Integer.MIN_VALUE && mon >= 0 && mday >= 0)
    560                         year = n;
    561                     else
    562                         break syntax;
    563                     prevc = 0;
    564                 } else if (c == '/' || c == ':' || c == '+' || c == '-')
    565                     prevc = c;
    566                 else {
    567                     int st = i - 1;
    568                     while (i < limit) {
    569                         c = s.charAt(i);
    570                         if (!('A' <= c && c <= 'Z' || 'a' <= c && c <= 'z'))
    571                             break;
    572                         i++;
    573                     }
    574                     if (i <= st + 1)
    575                         break syntax;
    576                     int k;
    577                     for (k = wtb.length; --k >= 0;)
    578                         if (wtb[k].regionMatches(true, 0, s, st, i - st)) {
    579                             int action = ttb[k];
    580                             if (action != 0) {
    581                                 if (action == 1) {  // pm
    582                                     if (hour > 12 || hour < 1)
    583                                         break syntax;
    584                                     else if (hour < 12)
    585                                         hour += 12;
    586                                 } else if (action == 14) {  // am
    587                                     if (hour > 12 || hour < 1)
    588                                         break syntax;
    589                                     else if (hour == 12)
    590                                         hour = 0;
    591                                 } else if (action <= 13) {  // month!
    592                                     if (mon < 0)
    593                                         mon = (byte) (action - 2);
    594                                     else
    595                                         break syntax;
    596                                 } else {
    597                                     tzoffset = action - 10000;
    598                                 }
    599                             }
    600                             break;
    601                         }
    602                     if (k < 0)
    603                         break syntax;
    604                     prevc = 0;
    605                 }
    606             }
    607             if (year == Integer.MIN_VALUE || mon < 0 || mday < 0)
    608                 break syntax;
    609             // Parse 2-digit years within the correct default century.
    610             if (year < 100) {
    611                 synchronized (Date.class) {
    612                     if (defaultCenturyStart == 0) {
    613                         defaultCenturyStart = gcal.getCalendarDate().getYear() - 80;
    614                     }
    615                 }
    616                 year += (defaultCenturyStart / 100) * 100;
    617                 if (year < defaultCenturyStart) year += 100;
    618             }
    619             if (sec < 0)
    620                 sec = 0;
    621             if (min < 0)
    622                 min = 0;
    623             if (hour < 0)
    624                 hour = 0;
    625             BaseCalendar cal = getCalendarSystem(year);
    626             if (tzoffset == -1)  { // no time zone specified, have to use local
    627                 BaseCalendar.Date ldate = (BaseCalendar.Date) cal.newCalendarDate(TimeZone.getDefaultRef());
    628                 ldate.setDate(year, mon + 1, mday);
    629                 ldate.setTimeOfDay(hour, min, sec, 0);
    630                 return cal.getTime(ldate);
    631             }
    632             BaseCalendar.Date udate = (BaseCalendar.Date) cal.newCalendarDate(null); // no time zone
    633             udate.setDate(year, mon + 1, mday);
    634             udate.setTimeOfDay(hour, min, sec, 0);
    635             return cal.getTime(udate) + tzoffset * (60 * 1000);
    636         }
    637         // syntax error
    638         throw new IllegalArgumentException();
    639     }
    640     private final static String wtb[] = {
    641         "am", "pm",
    642         "monday", "tuesday", "wednesday", "thursday", "friday",
    643         "saturday", "sunday",
    644         "january", "february", "march", "april", "may", "june",
    645         "july", "august", "september", "october", "november", "december",
    646         "gmt", "ut", "utc", "est", "edt", "cst", "cdt",
    647         "mst", "mdt", "pst", "pdt"
    648     };
    649     private final static int ttb[] = {
    650         14, 1, 0, 0, 0, 0, 0, 0, 0,
    651         2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
    652         10000 + 0, 10000 + 0, 10000 + 0,    // GMT/UT/UTC
    653         10000 + 5 * 60, 10000 + 4 * 60,     // EST/EDT
    654         10000 + 6 * 60, 10000 + 5 * 60,     // CST/CDT
    655         10000 + 7 * 60, 10000 + 6 * 60,     // MST/MDT
    656         10000 + 8 * 60, 10000 + 7 * 60      // PST/PDT
    657     };
    658 
    659     /**
    660      * Returns a value that is the result of subtracting 1900 from the
    661      * year that contains or begins with the instant in time represented
    662      * by this <code>Date</code> object, as interpreted in the local
    663      * time zone.
    664      *
    665      * @return  the year represented by this date, minus 1900.
    666      * @see     java.util.Calendar
    667      * @deprecated As of JDK version 1.1,
    668      * replaced by <code>Calendar.get(Calendar.YEAR) - 1900</code>.
    669      */
    670     @Deprecated
    671     public int getYear() {
    672         return normalize().getYear() - 1900;
    673     }
    674 
    675     /**
    676      * Sets the year of this <tt>Date</tt> object to be the specified
    677      * value plus 1900. This <code>Date</code> object is modified so
    678      * that it represents a point in time within the specified year,
    679      * with the month, date, hour, minute, and second the same as
    680      * before, as interpreted in the local time zone. (Of course, if
    681      * the date was February 29, for example, and the year is set to a
    682      * non-leap year, then the new date will be treated as if it were
    683      * on March 1.)
    684      *
    685      * @param   year    the year value.
    686      * @see     java.util.Calendar
    687      * @deprecated As of JDK version 1.1,
    688      * replaced by <code>Calendar.set(Calendar.YEAR, year + 1900)</code>.
    689      */
    690     @Deprecated
    691     public void setYear(int year) {
    692         getCalendarDate().setNormalizedYear(year + 1900);
    693     }
    694 
    695     /**
    696      * Returns a number representing the month that contains or begins
    697      * with the instant in time represented by this <tt>Date</tt> object.
    698      * The value returned is between <code>0</code> and <code>11</code>,
    699      * with the value <code>0</code> representing January.
    700      *
    701      * @return  the month represented by this date.
    702      * @see     java.util.Calendar
    703      * @deprecated As of JDK version 1.1,
    704      * replaced by <code>Calendar.get(Calendar.MONTH)</code>.
    705      */
    706     @Deprecated
    707     public int getMonth() {
    708         return normalize().getMonth() - 1; // adjust 1-based to 0-based
    709     }
    710 
    711     /**
    712      * Sets the month of this date to the specified value. This
    713      * <tt>Date</tt> object is modified so that it represents a point
    714      * in time within the specified month, with the year, date, hour,
    715      * minute, and second the same as before, as interpreted in the
    716      * local time zone. If the date was October 31, for example, and
    717      * the month is set to June, then the new date will be treated as
    718      * if it were on July 1, because June has only 30 days.
    719      *
    720      * @param   month   the month value between 0-11.
    721      * @see     java.util.Calendar
    722      * @deprecated As of JDK version 1.1,
    723      * replaced by <code>Calendar.set(Calendar.MONTH, int month)</code>.
    724      */
    725     @Deprecated
    726     public void setMonth(int month) {
    727         int y = 0;
    728         if (month >= 12) {
    729             y = month / 12;
    730             month %= 12;
    731         } else if (month < 0) {
    732             y = CalendarUtils.floorDivide(month, 12);
    733             month = CalendarUtils.mod(month, 12);
    734         }
    735         BaseCalendar.Date d = getCalendarDate();
    736         if (y != 0) {
    737             d.setNormalizedYear(d.getNormalizedYear() + y);
    738         }
    739         d.setMonth(month + 1); // adjust 0-based to 1-based month numbering
    740     }
    741 
    742     /**
    743      * Returns the day of the month represented by this <tt>Date</tt> object.
    744      * The value returned is between <code>1</code> and <code>31</code>
    745      * representing the day of the month that contains or begins with the
    746      * instant in time represented by this <tt>Date</tt> object, as
    747      * interpreted in the local time zone.
    748      *
    749      * @return  the day of the month represented by this date.
    750      * @see     java.util.Calendar
    751      * @deprecated As of JDK version 1.1,
    752      * replaced by <code>Calendar.get(Calendar.DAY_OF_MONTH)</code>.
    753      */
    754     @Deprecated
    755     // Android-removed stray @deprecated tag.
    756     public int getDate() {
    757         return normalize().getDayOfMonth();
    758     }
    759 
    760     /**
    761      * Sets the day of the month of this <tt>Date</tt> object to the
    762      * specified value. This <tt>Date</tt> object is modified so that
    763      * it represents a point in time within the specified day of the
    764      * month, with the year, month, hour, minute, and second the same
    765      * as before, as interpreted in the local time zone. If the date
    766      * was April 30, for example, and the date is set to 31, then it
    767      * will be treated as if it were on May 1, because April has only
    768      * 30 days.
    769      *
    770      * @param   date   the day of the month value between 1-31.
    771      * @see     java.util.Calendar
    772      * @deprecated As of JDK version 1.1,
    773      * replaced by <code>Calendar.set(Calendar.DAY_OF_MONTH, int date)</code>.
    774      */
    775     @Deprecated
    776     public void setDate(int date) {
    777         getCalendarDate().setDayOfMonth(date);
    778     }
    779 
    780     /**
    781      * Returns the day of the week represented by this date. The
    782      * returned value (<tt>0</tt> = Sunday, <tt>1</tt> = Monday,
    783      * <tt>2</tt> = Tuesday, <tt>3</tt> = Wednesday, <tt>4</tt> =
    784      * Thursday, <tt>5</tt> = Friday, <tt>6</tt> = Saturday)
    785      * represents the day of the week that contains or begins with
    786      * the instant in time represented by this <tt>Date</tt> object,
    787      * as interpreted in the local time zone.
    788      *
    789      * @return  the day of the week represented by this date.
    790      * @see     java.util.Calendar
    791      * @deprecated As of JDK version 1.1,
    792      * replaced by <code>Calendar.get(Calendar.DAY_OF_WEEK)</code>.
    793      */
    794     @Deprecated
    795     public int getDay() {
    796         return normalize().getDayOfWeek() - BaseCalendar.SUNDAY;
    797     }
    798 
    799     /**
    800      * Returns the hour represented by this <tt>Date</tt> object. The
    801      * returned value is a number (<tt>0</tt> through <tt>23</tt>)
    802      * representing the hour within the day that contains or begins
    803      * with the instant in time represented by this <tt>Date</tt>
    804      * object, as interpreted in the local time zone.
    805      *
    806      * @return  the hour represented by this date.
    807      * @see     java.util.Calendar
    808      * @deprecated As of JDK version 1.1,
    809      * replaced by <code>Calendar.get(Calendar.HOUR_OF_DAY)</code>.
    810      */
    811     @Deprecated
    812     public int getHours() {
    813         return normalize().getHours();
    814     }
    815 
    816     /**
    817      * Sets the hour of this <tt>Date</tt> object to the specified value.
    818      * This <tt>Date</tt> object is modified so that it represents a point
    819      * in time within the specified hour of the day, with the year, month,
    820      * date, minute, and second the same as before, as interpreted in the
    821      * local time zone.
    822      *
    823      * @param   hours   the hour value.
    824      * @see     java.util.Calendar
    825      * @deprecated As of JDK version 1.1,
    826      * replaced by <code>Calendar.set(Calendar.HOUR_OF_DAY, int hours)</code>.
    827      */
    828     @Deprecated
    829     public void setHours(int hours) {
    830         getCalendarDate().setHours(hours);
    831     }
    832 
    833     /**
    834      * Returns the number of minutes past the hour represented by this date,
    835      * as interpreted in the local time zone.
    836      * The value returned is between <code>0</code> and <code>59</code>.
    837      *
    838      * @return  the number of minutes past the hour represented by this date.
    839      * @see     java.util.Calendar
    840      * @deprecated As of JDK version 1.1,
    841      * replaced by <code>Calendar.get(Calendar.MINUTE)</code>.
    842      */
    843     @Deprecated
    844     public int getMinutes() {
    845         return normalize().getMinutes();
    846     }
    847 
    848     /**
    849      * Sets the minutes of this <tt>Date</tt> object to the specified value.
    850      * This <tt>Date</tt> object is modified so that it represents a point
    851      * in time within the specified minute of the hour, with the year, month,
    852      * date, hour, and second the same as before, as interpreted in the
    853      * local time zone.
    854      *
    855      * @param   minutes   the value of the minutes.
    856      * @see     java.util.Calendar
    857      * @deprecated As of JDK version 1.1,
    858      * replaced by <code>Calendar.set(Calendar.MINUTE, int minutes)</code>.
    859      */
    860     @Deprecated
    861     public void setMinutes(int minutes) {
    862         getCalendarDate().setMinutes(minutes);
    863     }
    864 
    865     /**
    866      * Returns the number of seconds past the minute represented by this date.
    867      * The value returned is between <code>0</code> and <code>61</code>. The
    868      * values <code>60</code> and <code>61</code> can only occur on those
    869      * Java Virtual Machines that take leap seconds into account.
    870      *
    871      * @return  the number of seconds past the minute represented by this date.
    872      * @see     java.util.Calendar
    873      * @deprecated As of JDK version 1.1,
    874      * replaced by <code>Calendar.get(Calendar.SECOND)</code>.
    875      */
    876     @Deprecated
    877     public int getSeconds() {
    878         return normalize().getSeconds();
    879     }
    880 
    881     /**
    882      * Sets the seconds of this <tt>Date</tt> to the specified value.
    883      * This <tt>Date</tt> object is modified so that it represents a
    884      * point in time within the specified second of the minute, with
    885      * the year, month, date, hour, and minute the same as before, as
    886      * interpreted in the local time zone.
    887      *
    888      * @param   seconds   the seconds value.
    889      * @see     java.util.Calendar
    890      * @deprecated As of JDK version 1.1,
    891      * replaced by <code>Calendar.set(Calendar.SECOND, int seconds)</code>.
    892      */
    893     @Deprecated
    894     public void setSeconds(int seconds) {
    895         getCalendarDate().setSeconds(seconds);
    896     }
    897 
    898     /**
    899      * Returns the number of milliseconds since January 1, 1970, 00:00:00 GMT
    900      * represented by this <tt>Date</tt> object.
    901      *
    902      * @return  the number of milliseconds since January 1, 1970, 00:00:00 GMT
    903      *          represented by this date.
    904      */
    905     public long getTime() {
    906         return getTimeImpl();
    907     }
    908 
    909     private final long getTimeImpl() {
    910         if (cdate != null && !cdate.isNormalized()) {
    911             normalize();
    912         }
    913         return fastTime;
    914     }
    915 
    916     /**
    917      * Sets this <code>Date</code> object to represent a point in time that is
    918      * <code>time</code> milliseconds after January 1, 1970 00:00:00 GMT.
    919      *
    920      * @param   time   the number of milliseconds.
    921      */
    922     public void setTime(long time) {
    923         fastTime = time;
    924         cdate = null;
    925     }
    926 
    927     /**
    928      * Tests if this date is before the specified date.
    929      *
    930      * @param   when   a date.
    931      * @return  <code>true</code> if and only if the instant of time
    932      *            represented by this <tt>Date</tt> object is strictly
    933      *            earlier than the instant represented by <tt>when</tt>;
    934      *          <code>false</code> otherwise.
    935      * @exception NullPointerException if <code>when</code> is null.
    936      */
    937     public boolean before(Date when) {
    938         return getMillisOf(this) < getMillisOf(when);
    939     }
    940 
    941     /**
    942      * Tests if this date is after the specified date.
    943      *
    944      * @param   when   a date.
    945      * @return  <code>true</code> if and only if the instant represented
    946      *          by this <tt>Date</tt> object is strictly later than the
    947      *          instant represented by <tt>when</tt>;
    948      *          <code>false</code> otherwise.
    949      * @exception NullPointerException if <code>when</code> is null.
    950      */
    951     public boolean after(Date when) {
    952         return getMillisOf(this) > getMillisOf(when);
    953     }
    954 
    955     /**
    956      * Compares two dates for equality.
    957      * The result is <code>true</code> if and only if the argument is
    958      * not <code>null</code> and is a <code>Date</code> object that
    959      * represents the same point in time, to the millisecond, as this object.
    960      * <p>
    961      * Thus, two <code>Date</code> objects are equal if and only if the
    962      * <code>getTime</code> method returns the same <code>long</code>
    963      * value for both.
    964      *
    965      * @param   obj   the object to compare with.
    966      * @return  <code>true</code> if the objects are the same;
    967      *          <code>false</code> otherwise.
    968      * @see     java.util.Date#getTime()
    969      */
    970     public boolean equals(Object obj) {
    971         return obj instanceof Date && getTime() == ((Date) obj).getTime();
    972     }
    973 
    974     /**
    975      * Returns the millisecond value of this <code>Date</code> object
    976      * without affecting its internal state.
    977      */
    978     static final long getMillisOf(Date date) {
    979         if (date.cdate == null || date.cdate.isNormalized()) {
    980             return date.fastTime;
    981         }
    982         BaseCalendar.Date d = (BaseCalendar.Date) date.cdate.clone();
    983         return gcal.getTime(d);
    984     }
    985 
    986     /**
    987      * Compares two Dates for ordering.
    988      *
    989      * @param   anotherDate   the <code>Date</code> to be compared.
    990      * @return  the value <code>0</code> if the argument Date is equal to
    991      *          this Date; a value less than <code>0</code> if this Date
    992      *          is before the Date argument; and a value greater than
    993      *      <code>0</code> if this Date is after the Date argument.
    994      * @since   1.2
    995      * @exception NullPointerException if <code>anotherDate</code> is null.
    996      */
    997     public int compareTo(Date anotherDate) {
    998         long thisTime = getMillisOf(this);
    999         long anotherTime = getMillisOf(anotherDate);
   1000         return (thisTime<anotherTime ? -1 : (thisTime==anotherTime ? 0 : 1));
   1001     }
   1002 
   1003     /**
   1004      * Returns a hash code value for this object. The result is the
   1005      * exclusive OR of the two halves of the primitive <tt>long</tt>
   1006      * value returned by the {@link Date#getTime}
   1007      * method. That is, the hash code is the value of the expression:
   1008      * <blockquote><pre>{@code
   1009      * (int)(this.getTime()^(this.getTime() >>> 32))
   1010      * }</pre></blockquote>
   1011      *
   1012      * @return  a hash code value for this object.
   1013      */
   1014     public int hashCode() {
   1015         long ht = this.getTime();
   1016         return (int) ht ^ (int) (ht >> 32);
   1017     }
   1018 
   1019     /**
   1020      * Converts this <code>Date</code> object to a <code>String</code>
   1021      * of the form:
   1022      * <blockquote><pre>
   1023      * dow mon dd hh:mm:ss zzz yyyy</pre></blockquote>
   1024      * where:<ul>
   1025      * <li><tt>dow</tt> is the day of the week (<tt>Sun, Mon, Tue, Wed,
   1026      *     Thu, Fri, Sat</tt>).
   1027      * <li><tt>mon</tt> is the month (<tt>Jan, Feb, Mar, Apr, May, Jun,
   1028      *     Jul, Aug, Sep, Oct, Nov, Dec</tt>).
   1029      * <li><tt>dd</tt> is the day of the month (<tt>01</tt> through
   1030      *     <tt>31</tt>), as two decimal digits.
   1031      * <li><tt>hh</tt> is the hour of the day (<tt>00</tt> through
   1032      *     <tt>23</tt>), as two decimal digits.
   1033      * <li><tt>mm</tt> is the minute within the hour (<tt>00</tt> through
   1034      *     <tt>59</tt>), as two decimal digits.
   1035      * <li><tt>ss</tt> is the second within the minute (<tt>00</tt> through
   1036      *     <tt>61</tt>, as two decimal digits.
   1037      * <li><tt>zzz</tt> is the time zone (and may reflect daylight saving
   1038      *     time). Standard time zone abbreviations include those
   1039      *     recognized by the method <tt>parse</tt>. If time zone
   1040      *     information is not available, then <tt>zzz</tt> is empty -
   1041      *     that is, it consists of no characters at all.
   1042      * <li><tt>yyyy</tt> is the year, as four decimal digits.
   1043      * </ul>
   1044      *
   1045      * @return  a string representation of this date.
   1046      * @see     java.util.Date#toLocaleString()
   1047      * @see     java.util.Date#toGMTString()
   1048      */
   1049     public String toString() {
   1050         // "EEE MMM dd HH:mm:ss zzz yyyy";
   1051         BaseCalendar.Date date = normalize();
   1052         StringBuilder sb = new StringBuilder(28);
   1053         int index = date.getDayOfWeek();
   1054         if (index == BaseCalendar.SUNDAY) {
   1055             index = 8;
   1056         }
   1057         convertToAbbr(sb, wtb[index]).append(' ');                        // EEE
   1058         convertToAbbr(sb, wtb[date.getMonth() - 1 + 2 + 7]).append(' ');  // MMM
   1059         CalendarUtils.sprintf0d(sb, date.getDayOfMonth(), 2).append(' '); // dd
   1060 
   1061         CalendarUtils.sprintf0d(sb, date.getHours(), 2).append(':');   // HH
   1062         CalendarUtils.sprintf0d(sb, date.getMinutes(), 2).append(':'); // mm
   1063         CalendarUtils.sprintf0d(sb, date.getSeconds(), 2).append(' '); // ss
   1064         TimeZone zi = date.getZone();
   1065         if (zi != null) {
   1066             sb.append(zi.getDisplayName(date.isDaylightTime(), TimeZone.SHORT, Locale.US)); // zzz
   1067         } else {
   1068             sb.append("GMT");
   1069         }
   1070         sb.append(' ').append(date.getYear());  // yyyy
   1071         return sb.toString();
   1072     }
   1073 
   1074     /**
   1075      * Converts the given name to its 3-letter abbreviation (e.g.,
   1076      * "monday" -> "Mon") and stored the abbreviation in the given
   1077      * <code>StringBuilder</code>.
   1078      */
   1079     private static final StringBuilder convertToAbbr(StringBuilder sb, String name) {
   1080         sb.append(Character.toUpperCase(name.charAt(0)));
   1081         sb.append(name.charAt(1)).append(name.charAt(2));
   1082         return sb;
   1083     }
   1084 
   1085     /**
   1086      * Creates a string representation of this <tt>Date</tt> object in an
   1087      * implementation-dependent form. The intent is that the form should
   1088      * be familiar to the user of the Java application, wherever it may
   1089      * happen to be running. The intent is comparable to that of the
   1090      * "<code>%c</code>" format supported by the <code>strftime()</code>
   1091      * function of ISO&nbsp;C.
   1092      *
   1093      * @return  a string representation of this date, using the locale
   1094      *          conventions.
   1095      * @see     java.text.DateFormat
   1096      * @see     java.util.Date#toString()
   1097      * @see     java.util.Date#toGMTString()
   1098      * @deprecated As of JDK version 1.1,
   1099      * replaced by <code>DateFormat.format(Date date)</code>.
   1100      */
   1101     @Deprecated
   1102     public String toLocaleString() {
   1103         DateFormat formatter = DateFormat.getDateTimeInstance();
   1104         return formatter.format(this);
   1105     }
   1106 
   1107     /**
   1108      * Creates a string representation of this <tt>Date</tt> object of
   1109      * the form:
   1110      * <blockquote><pre>
   1111      * d mon yyyy hh:mm:ss GMT</pre></blockquote>
   1112      * where:<ul>
   1113      * <li><i>d</i> is the day of the month (<tt>1</tt> through <tt>31</tt>),
   1114      *     as one or two decimal digits.
   1115      * <li><i>mon</i> is the month (<tt>Jan, Feb, Mar, Apr, May, Jun, Jul,
   1116      *     Aug, Sep, Oct, Nov, Dec</tt>).
   1117      * <li><i>yyyy</i> is the year, as four decimal digits.
   1118      * <li><i>hh</i> is the hour of the day (<tt>00</tt> through <tt>23</tt>),
   1119      *     as two decimal digits.
   1120      * <li><i>mm</i> is the minute within the hour (<tt>00</tt> through
   1121      *     <tt>59</tt>), as two decimal digits.
   1122      * <li><i>ss</i> is the second within the minute (<tt>00</tt> through
   1123      *     <tt>61</tt>), as two decimal digits.
   1124      * <li><i>GMT</i> is exactly the ASCII letters "<tt>GMT</tt>" to indicate
   1125      *     Greenwich Mean Time.
   1126      * </ul><p>
   1127      * The result does not depend on the local time zone.
   1128      *
   1129      * @return  a string representation of this date, using the Internet GMT
   1130      *          conventions.
   1131      * @see     java.text.DateFormat
   1132      * @see     java.util.Date#toString()
   1133      * @see     java.util.Date#toLocaleString()
   1134      * @deprecated As of JDK version 1.1,
   1135      * replaced by <code>DateFormat.format(Date date)</code>, using a
   1136      * GMT <code>TimeZone</code>.
   1137      */
   1138     @Deprecated
   1139     public String toGMTString() {
   1140         // d MMM yyyy HH:mm:ss 'GMT'
   1141         long t = getTime();
   1142         BaseCalendar cal = getCalendarSystem(t);
   1143         BaseCalendar.Date date =
   1144             (BaseCalendar.Date) cal.getCalendarDate(getTime(), (TimeZone)null);
   1145         StringBuilder sb = new StringBuilder(32);
   1146         CalendarUtils.sprintf0d(sb, date.getDayOfMonth(), 1).append(' '); // d
   1147         convertToAbbr(sb, wtb[date.getMonth() - 1 + 2 + 7]).append(' ');  // MMM
   1148         sb.append(date.getYear()).append(' ');                            // yyyy
   1149         CalendarUtils.sprintf0d(sb, date.getHours(), 2).append(':');      // HH
   1150         CalendarUtils.sprintf0d(sb, date.getMinutes(), 2).append(':');    // mm
   1151         CalendarUtils.sprintf0d(sb, date.getSeconds(), 2);                // ss
   1152         sb.append(" GMT");                                                // ' GMT'
   1153         return sb.toString();
   1154     }
   1155 
   1156     /**
   1157      * Returns the offset, measured in minutes, for the local time zone
   1158      * relative to UTC that is appropriate for the time represented by
   1159      * this <code>Date</code> object.
   1160      * <p>
   1161      * For example, in Massachusetts, five time zones west of Greenwich:
   1162      * <blockquote><pre>
   1163      * new Date(96, 1, 14).getTimezoneOffset() returns 300</pre></blockquote>
   1164      * because on February 14, 1996, standard time (Eastern Standard Time)
   1165      * is in use, which is offset five hours from UTC; but:
   1166      * <blockquote><pre>
   1167      * new Date(96, 5, 1).getTimezoneOffset() returns 240</pre></blockquote>
   1168      * because on June 1, 1996, daylight saving time (Eastern Daylight Time)
   1169      * is in use, which is offset only four hours from UTC.<p>
   1170      * This method produces the same result as if it computed:
   1171      * <blockquote><pre>
   1172      * (this.getTime() - UTC(this.getYear(),
   1173      *                       this.getMonth(),
   1174      *                       this.getDate(),
   1175      *                       this.getHours(),
   1176      *                       this.getMinutes(),
   1177      *                       this.getSeconds())) / (60 * 1000)
   1178      * </pre></blockquote>
   1179      *
   1180      * @return  the time-zone offset, in minutes, for the current time zone.
   1181      * @see     java.util.Calendar#ZONE_OFFSET
   1182      * @see     java.util.Calendar#DST_OFFSET
   1183      * @see     java.util.TimeZone#getDefault
   1184      * @deprecated As of JDK version 1.1,
   1185      * replaced by <code>-(Calendar.get(Calendar.ZONE_OFFSET) +
   1186      * Calendar.get(Calendar.DST_OFFSET)) / (60 * 1000)</code>.
   1187      */
   1188     @Deprecated
   1189     public int getTimezoneOffset() {
   1190         int zoneOffset;
   1191         if (cdate == null) {
   1192             // Android-changed: Android specific time zone logic
   1193             GregorianCalendar cal = new GregorianCalendar(fastTime);
   1194             zoneOffset = (cal.get(Calendar.ZONE_OFFSET) + cal.get(Calendar.DST_OFFSET));
   1195         } else {
   1196             normalize();
   1197             zoneOffset = cdate.getZoneOffset();
   1198         }
   1199         return -zoneOffset/60000;  // convert to minutes
   1200     }
   1201 
   1202     private final BaseCalendar.Date getCalendarDate() {
   1203         if (cdate == null) {
   1204             BaseCalendar cal = getCalendarSystem(fastTime);
   1205             cdate = (BaseCalendar.Date) cal.getCalendarDate(fastTime,
   1206                                                             TimeZone.getDefaultRef());
   1207         }
   1208         return cdate;
   1209     }
   1210 
   1211     private final BaseCalendar.Date normalize() {
   1212         if (cdate == null) {
   1213             BaseCalendar cal = getCalendarSystem(fastTime);
   1214             cdate = (BaseCalendar.Date) cal.getCalendarDate(fastTime,
   1215                                                             TimeZone.getDefaultRef());
   1216             return cdate;
   1217         }
   1218 
   1219         // Normalize cdate with the TimeZone in cdate first. This is
   1220         // required for the compatible behavior.
   1221         if (!cdate.isNormalized()) {
   1222             cdate = normalize(cdate);
   1223         }
   1224 
   1225         // If the default TimeZone has changed, then recalculate the
   1226         // fields with the new TimeZone.
   1227         TimeZone tz = TimeZone.getDefaultRef();
   1228         if (tz != cdate.getZone()) {
   1229             cdate.setZone(tz);
   1230             CalendarSystem cal = getCalendarSystem(cdate);
   1231             cal.getCalendarDate(fastTime, cdate);
   1232         }
   1233         return cdate;
   1234     }
   1235 
   1236     // fastTime and the returned data are in sync upon return.
   1237     private final BaseCalendar.Date normalize(BaseCalendar.Date date) {
   1238         int y = date.getNormalizedYear();
   1239         int m = date.getMonth();
   1240         int d = date.getDayOfMonth();
   1241         int hh = date.getHours();
   1242         int mm = date.getMinutes();
   1243         int ss = date.getSeconds();
   1244         int ms = date.getMillis();
   1245         TimeZone tz = date.getZone();
   1246 
   1247         // If the specified year can't be handled using a long value
   1248         // in milliseconds, GregorianCalendar is used for full
   1249         // compatibility with underflow and overflow. This is required
   1250         // by some JCK tests. The limits are based max year values -
   1251         // years that can be represented by max values of d, hh, mm,
   1252         // ss and ms. Also, let GregorianCalendar handle the default
   1253         // cutover year so that we don't need to worry about the
   1254         // transition here.
   1255         if (y == 1582 || y > 280000000 || y < -280000000) {
   1256             if (tz == null) {
   1257                 tz = TimeZone.getTimeZone("GMT");
   1258             }
   1259             GregorianCalendar gc = new GregorianCalendar(tz);
   1260             gc.clear();
   1261             gc.set(GregorianCalendar.MILLISECOND, ms);
   1262             gc.set(y, m-1, d, hh, mm, ss);
   1263             fastTime = gc.getTimeInMillis();
   1264             BaseCalendar cal = getCalendarSystem(fastTime);
   1265             date = (BaseCalendar.Date) cal.getCalendarDate(fastTime, tz);
   1266             return date;
   1267         }
   1268 
   1269         BaseCalendar cal = getCalendarSystem(y);
   1270         if (cal != getCalendarSystem(date)) {
   1271             date = (BaseCalendar.Date) cal.newCalendarDate(tz);
   1272             date.setNormalizedDate(y, m, d).setTimeOfDay(hh, mm, ss, ms);
   1273         }
   1274         // Perform the GregorianCalendar-style normalization.
   1275         fastTime = cal.getTime(date);
   1276 
   1277         // In case the normalized date requires the other calendar
   1278         // system, we need to recalculate it using the other one.
   1279         BaseCalendar ncal = getCalendarSystem(fastTime);
   1280         if (ncal != cal) {
   1281             date = (BaseCalendar.Date) ncal.newCalendarDate(tz);
   1282             date.setNormalizedDate(y, m, d).setTimeOfDay(hh, mm, ss, ms);
   1283             fastTime = ncal.getTime(date);
   1284         }
   1285         return date;
   1286     }
   1287 
   1288     /**
   1289      * Returns the Gregorian or Julian calendar system to use with the
   1290      * given date. Use Gregorian from October 15, 1582.
   1291      *
   1292      * @param year normalized calendar year (not -1900)
   1293      * @return the CalendarSystem to use for the specified date
   1294      */
   1295     private static final BaseCalendar getCalendarSystem(int year) {
   1296         if (year >= 1582) {
   1297             return gcal;
   1298         }
   1299         return getJulianCalendar();
   1300     }
   1301 
   1302     private static final BaseCalendar getCalendarSystem(long utc) {
   1303         // Quickly check if the time stamp given by `utc' is the Epoch
   1304         // or later. If it's before 1970, we convert the cutover to
   1305         // local time to compare.
   1306         if (utc >= 0
   1307             || utc >= GregorianCalendar.DEFAULT_GREGORIAN_CUTOVER
   1308                         - TimeZone.getDefaultRef().getOffset(utc)) {
   1309             return gcal;
   1310         }
   1311         return getJulianCalendar();
   1312     }
   1313 
   1314     private static final BaseCalendar getCalendarSystem(BaseCalendar.Date cdate) {
   1315         if (jcal == null) {
   1316             return gcal;
   1317         }
   1318         if (cdate.getEra() != null) {
   1319             return jcal;
   1320         }
   1321         return gcal;
   1322     }
   1323 
   1324     synchronized private static final BaseCalendar getJulianCalendar() {
   1325         if (jcal == null) {
   1326             jcal = (BaseCalendar) CalendarSystem.forName("julian");
   1327         }
   1328         return jcal;
   1329     }
   1330 
   1331     /**
   1332      * Save the state of this object to a stream (i.e., serialize it).
   1333      *
   1334      * @serialData The value returned by <code>getTime()</code>
   1335      *             is emitted (long).  This represents the offset from
   1336      *             January 1, 1970, 00:00:00 GMT in milliseconds.
   1337      */
   1338     private void writeObject(ObjectOutputStream s)
   1339          throws IOException
   1340     {
   1341         s.writeLong(getTimeImpl());
   1342     }
   1343 
   1344     /**
   1345      * Reconstitute this object from a stream (i.e., deserialize it).
   1346      */
   1347     private void readObject(ObjectInputStream s)
   1348          throws IOException, ClassNotFoundException
   1349     {
   1350         fastTime = s.readLong();
   1351     }
   1352 
   1353     /**
   1354      * Obtains an instance of {@code Date} from an {@code Instant} object.
   1355      * <p>
   1356      * {@code Instant} uses a precision of nanoseconds, whereas {@code Date}
   1357      * uses a precision of milliseconds.  The conversion will trancate any
   1358      * excess precision information as though the amount in nanoseconds was
   1359      * subject to integer division by one million.
   1360      * <p>
   1361      * {@code Instant} can store points on the time-line further in the future
   1362      * and further in the past than {@code Date}. In this scenario, this method
   1363      * will throw an exception.
   1364      *
   1365      * @param instant  the instant to convert
   1366      * @return a {@code Date} representing the same point on the time-line as
   1367      *  the provided instant
   1368      * @exception NullPointerException if {@code instant} is null.
   1369      * @exception IllegalArgumentException if the instant is too large to
   1370      *  represent as a {@code Date}
   1371      * @since 1.8
   1372      */
   1373     public static Date from(Instant instant) {
   1374         try {
   1375             return new Date(instant.toEpochMilli());
   1376         } catch (ArithmeticException ex) {
   1377             throw new IllegalArgumentException(ex);
   1378         }
   1379     }
   1380 
   1381     /**
   1382      * Converts this {@code Date} object to an {@code Instant}.
   1383      * <p>
   1384      * The conversion creates an {@code Instant} that represents the same
   1385      * point on the time-line as this {@code Date}.
   1386      *
   1387      * @return an instant representing the same point on the time-line as
   1388      *  this {@code Date} object
   1389      * @since 1.8
   1390      */
   1391     public Instant toInstant() {
   1392         return Instant.ofEpochMilli(getTime());
   1393     }
   1394 }
   1395