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