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 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 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 day = 61 * 24 × 60 × 60 = 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> <code>- 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 */ Date()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 */ Date(long date)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 Date(int year, int month, int date)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 Date(int year, int month, int date, int hrs, int min)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 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</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 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 <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 UTC(int year, int month, int date, int hrs, int min, int sec)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 parse(String s)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 getYear()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 setYear(int year)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 getMonth()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 setMonth(int month)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. getDate()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 setDate(int date)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 getDay()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 getHours()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 setHours(int hours)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 getMinutes()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 setMinutes(int minutes)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 getSeconds()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 setSeconds(int seconds)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 */ getTime()905 public long getTime() { 906 return getTimeImpl(); 907 } 908 getTimeImpl()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 */ setTime(long time)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 */ before(Date when)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 */ after(Date when)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 */ equals(Object obj)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 */ getMillisOf(Date date)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 */ compareTo(Date anotherDate)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 */ hashCode()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 */ toString()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 */ convertToAbbr(StringBuilder sb, String name)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 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 toLocaleString()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 toGMTString()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 getTimezoneOffset()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 getCalendarDate()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 normalize()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. normalize(BaseCalendar.Date date)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 */ getCalendarSystem(int year)1295 private static final BaseCalendar getCalendarSystem(int year) { 1296 if (year >= 1582) { 1297 return gcal; 1298 } 1299 return getJulianCalendar(); 1300 } 1301 getCalendarSystem(long utc)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 getCalendarSystem(BaseCalendar.Date cdate)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 getJulianCalendar()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 */ writeObject(ObjectOutputStream s)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 */ readObject(ObjectInputStream s)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 */ from(Instant instant)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 */ toInstant()1391 public Instant toInstant() { 1392 return Instant.ofEpochMilli(getTime()); 1393 } 1394 } 1395