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