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