2 * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
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.
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).
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.
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
28 import java.text.DateFormat;
29 import java.io.IOException;
30 import java.io.ObjectOutputStream;
31 import java.io.ObjectInputStream;
32 import java.lang.ref.SoftReference;
33 import sun.util.calendar.BaseCalendar;
34 import sun.util.calendar.CalendarDate;
35 import sun.util.calendar.CalendarSystem;
36 import sun.util.calendar.CalendarUtils;
37 import sun.util.calendar.Era;
38 import sun.util.calendar.Gregorian;
39 import sun.util.calendar.ZoneInfo;
42 * The class <code>Date</code> represents a specific instant
43 * in time, with millisecond precision.
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
53 * The corresponding methods in <code>Date</code> are deprecated.
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.
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:
86 * <a href=http://tycho.usno.navy.mil>http://tycho.usno.navy.mil</a>
89 * and their definitions of "Systems of Time" at:
91 * <a href=http://tycho.usno.navy.mil/systime.html>http://tycho.usno.navy.mil/systime.html</a>
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:
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
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
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.
121 * @author James Gosling
122 * @author Arthur van Hoff
124 * @see java.text.DateFormat
125 * @see java.util.Calendar
126 * @see java.util.TimeZone
130 implements java.io.Serializable, Cloneable, Comparable<Date>
132 private static final BaseCalendar gcal =
133 CalendarSystem.getGregorianCalendar();
134 private static BaseCalendar jcal;
136 private transient long fastTime;
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
144 private transient BaseCalendar.Date cdate;
146 // Initialized just before the value is used. See parse().
147 private static int defaultCenturyStart;
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.
153 private static final long serialVersionUID = 7523967970034938905L;
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.
160 * @see java.lang.System#currentTimeMillis()
163 this(System.currentTimeMillis());
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.
172 * @param date the milliseconds since January 1, 1970, 00:00:00 GMT.
173 * @see java.lang.System#currentTimeMillis()
175 public Date(long date) {
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.
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>.
194 public Date(int year, int month, int date) {
195 this(year, month, date, 0, 0, 0);
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
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>.
217 public Date(int year, int month, int date, int hrs, int min) {
218 this(year, month, date, hrs, min, 0);
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.
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>.
241 public Date(int year, int month, int date, int hrs, int min, int sec) {
243 // month is 0-based. So we have to normalize month to support Long.MAX_VALUE.
247 } else if (month < 0) {
248 y += CalendarUtils.floorDivide(month, 12);
249 month = CalendarUtils.mod(month, 12);
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);
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.
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>.
271 public Date(String s) {
276 * Return a copy of this object.
278 public Object clone() {
281 d = (Date)super.clone();
283 d.cdate = (BaseCalendar.Date) cdate.clone();
285 } catch (CloneNotSupportedException e) {} // Won't happen
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).
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>.
315 public static long UTC(int year, int month, int date,
316 int hrs, int min, int sec) {
318 // month is 0-based. So we have to normalize month to support Long.MAX_VALUE.
322 } else if (month < 0) {
323 y += CalendarUtils.floorDivide(month, 12);
324 month = CalendarUtils.mod(month, 12);
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);
331 // Use a Date instance to perform normalization. Its fastTime
332 // is the UTC value after the normalization.
333 Date d = new Date(0);
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.
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.
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:
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
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:
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>
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
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.
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>.
452 public static long parse(String s) {
453 int year = Integer.MIN_VALUE;
470 int limit = s.length();
474 if (c <= ' ' || c == ',')
476 if (c == '(') { // skip comments
481 if (c == '(') depth++;
488 if ('0' <= c && c <= '9') {
490 while (i < limit && '0' <= (c = s.charAt(i)) && c <= '9') {
491 n = n * 10 + c - '0';
494 if (prevc == '+' || prevc == '-' && year != Integer.MIN_VALUE) {
497 n = n * 60; // EG. "GMT-3"
499 n = n % 100 + n / 100 * 60; // eg "GMT-0430"
500 if (prevc == '+') // plus means east of GMT
502 if (tzoffset != 0 && tzoffset != -1)
506 if (year != Integer.MIN_VALUE)
508 else if (c <= ' ' || c == ',' || c == '/' || i >= limit)
509 // year = n < 1900 ? n : n - 1900;
522 mon = (byte) (n - 1);
527 else if (i < limit && c != ',' && c > ' ' && c != '-')
529 else if (hour >= 0 && min < 0)
531 else if (min >= 0 && sec < 0)
535 // Handle two-digit years < 70 (70-99 handled above).
536 else if (year == Integer.MIN_VALUE && mon >= 0 && mday >= 0)
541 } else if (c == '/' || c == ':' || c == '+' || c == '-')
547 if (!('A' <= c && c <= 'Z' || 'a' <= c && c <= 'z'))
554 for (k = wtb.length; --k >= 0;)
555 if (wtb[k].regionMatches(true, 0, s, st, i - st)) {
558 if (action == 1) { // pm
559 if (hour > 12 || hour < 1)
563 } else if (action == 14) { // am
564 if (hour > 12 || hour < 1)
568 } else if (action <= 13) { // month!
570 mon = (byte) (action - 2);
574 tzoffset = action - 10000;
584 if (year == Integer.MIN_VALUE || mon < 0 || mday < 0)
586 // Parse 2-digit years within the correct default century.
588 synchronized (Date.class) {
589 if (defaultCenturyStart == 0) {
590 defaultCenturyStart = gcal.getCalendarDate().getYear() - 80;
593 year += (defaultCenturyStart / 100) * 100;
594 if (year < defaultCenturyStart) year += 100;
602 BaseCalendar cal = getCalendarSystem(year);
603 if (tzoffset == -1) { // no time zone specified, have to use local
604 BaseCalendar.Date ldate = (BaseCalendar.Date) cal.newCalendarDate(TimeZone.getDefaultRef());
605 ldate.setDate(year, mon + 1, mday);
606 ldate.setTimeOfDay(hour, min, sec, 0);
607 return cal.getTime(ldate);
609 BaseCalendar.Date udate = (BaseCalendar.Date) cal.newCalendarDate(null); // no time zone
610 udate.setDate(year, mon + 1, mday);
611 udate.setTimeOfDay(hour, min, sec, 0);
612 return cal.getTime(udate) + tzoffset * (60 * 1000);
615 throw new IllegalArgumentException();
617 private final static String wtb[] = {
619 "monday", "tuesday", "wednesday", "thursday", "friday",
620 "saturday", "sunday",
621 "january", "february", "march", "april", "may", "june",
622 "july", "august", "september", "october", "november", "december",
623 "gmt", "ut", "utc", "est", "edt", "cst", "cdt",
624 "mst", "mdt", "pst", "pdt"
626 private final static int ttb[] = {
627 14, 1, 0, 0, 0, 0, 0, 0, 0,
628 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
629 10000 + 0, 10000 + 0, 10000 + 0, // GMT/UT/UTC
630 10000 + 5 * 60, 10000 + 4 * 60, // EST/EDT
631 10000 + 6 * 60, 10000 + 5 * 60, // CST/CDT
632 10000 + 7 * 60, 10000 + 6 * 60, // MST/MDT
633 10000 + 8 * 60, 10000 + 7 * 60 // PST/PDT
637 * Returns a value that is the result of subtracting 1900 from the
638 * year that contains or begins with the instant in time represented
639 * by this <code>Date</code> object, as interpreted in the local
642 * @return the year represented by this date, minus 1900.
643 * @see java.util.Calendar
644 * @deprecated As of JDK version 1.1,
645 * replaced by <code>Calendar.get(Calendar.YEAR) - 1900</code>.
648 public int getYear() {
649 return normalize().getYear() - 1900;
653 * Sets the year of this <tt>Date</tt> object to be the specified
654 * value plus 1900. This <code>Date</code> object is modified so
655 * that it represents a point in time within the specified year,
656 * with the month, date, hour, minute, and second the same as
657 * before, as interpreted in the local time zone. (Of course, if
658 * the date was February 29, for example, and the year is set to a
659 * non-leap year, then the new date will be treated as if it were
662 * @param year the year value.
663 * @see java.util.Calendar
664 * @deprecated As of JDK version 1.1,
665 * replaced by <code>Calendar.set(Calendar.YEAR, year + 1900)</code>.
668 public void setYear(int year) {
669 getCalendarDate().setNormalizedYear(year + 1900);
673 * Returns a number representing the month that contains or begins
674 * with the instant in time represented by this <tt>Date</tt> object.
675 * The value returned is between <code>0</code> and <code>11</code>,
676 * with the value <code>0</code> representing January.
678 * @return the month represented by this date.
679 * @see java.util.Calendar
680 * @deprecated As of JDK version 1.1,
681 * replaced by <code>Calendar.get(Calendar.MONTH)</code>.
684 public int getMonth() {
685 return normalize().getMonth() - 1; // adjust 1-based to 0-based
689 * Sets the month of this date to the specified value. This
690 * <tt>Date</tt> object is modified so that it represents a point
691 * in time within the specified month, with the year, date, hour,
692 * minute, and second the same as before, as interpreted in the
693 * local time zone. If the date was October 31, for example, and
694 * the month is set to June, then the new date will be treated as
695 * if it were on July 1, because June has only 30 days.
697 * @param month the month value between 0-11.
698 * @see java.util.Calendar
699 * @deprecated As of JDK version 1.1,
700 * replaced by <code>Calendar.set(Calendar.MONTH, int month)</code>.
703 public void setMonth(int month) {
708 } else if (month < 0) {
709 y = CalendarUtils.floorDivide(month, 12);
710 month = CalendarUtils.mod(month, 12);
712 BaseCalendar.Date d = getCalendarDate();
714 d.setNormalizedYear(d.getNormalizedYear() + y);
716 d.setMonth(month + 1); // adjust 0-based to 1-based month numbering
720 * Returns the day of the month represented by this <tt>Date</tt> object.
721 * The value returned is between <code>1</code> and <code>31</code>
722 * representing the day of the month that contains or begins with the
723 * instant in time represented by this <tt>Date</tt> object, as
724 * interpreted in the local time zone.
726 * @return the day of the month represented by this date.
727 * @see java.util.Calendar
728 * @deprecated As of JDK version 1.1,
729 * replaced by <code>Calendar.get(Calendar.DAY_OF_MONTH)</code>.
733 public int getDate() {
734 return normalize().getDayOfMonth();
738 * Sets the day of the month of this <tt>Date</tt> object to the
739 * specified value. This <tt>Date</tt> 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
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)</code>.
753 public void setDate(int date) {
754 getCalendarDate().setDayOfMonth(date);
758 * Returns the day of the week represented by this date. The
759 * returned value (<tt>0</tt> = Sunday, <tt>1</tt> = Monday,
760 * <tt>2</tt> = Tuesday, <tt>3</tt> = Wednesday, <tt>4</tt> =
761 * Thursday, <tt>5</tt> = Friday, <tt>6</tt> = Saturday)
762 * represents the day of the week that contains or begins with
763 * the instant in time represented by this <tt>Date</tt> object,
764 * as interpreted in the local time zone.
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)</code>.
772 public int getDay() {
773 return normalize().getDayOfWeek() - gcal.SUNDAY;
777 * Returns the hour represented by this <tt>Date</tt> object. The
778 * returned value is a number (<tt>0</tt> through <tt>23</tt>)
779 * representing the hour within the day that contains or begins
780 * with the instant in time represented by this <tt>Date</tt>
781 * object, as interpreted in the local time zone.
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)</code>.
789 public int getHours() {
790 return normalize().getHours();
794 * Sets the hour of this <tt>Date</tt> object to the specified value.
795 * This <tt>Date</tt> 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
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)</code>.
806 public void setHours(int hours) {
807 getCalendarDate().setHours(hours);
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</code> and <code>59</code>.
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)</code>.
821 public int getMinutes() {
822 return normalize().getMinutes();
826 * Sets the minutes of this <tt>Date</tt> object to the specified value.
827 * This <tt>Date</tt> 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
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)</code>.
838 public void setMinutes(int minutes) {
839 getCalendarDate().setMinutes(minutes);
843 * Returns the number of seconds past the minute represented by this date.
844 * The value returned is between <code>0</code> and <code>61</code>. The
845 * values <code>60</code> and <code>61</code> can only occur on those
846 * Java Virtual Machines that take leap seconds into account.
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)</code>.
854 public int getSeconds() {
855 return normalize().getSeconds();
859 * Sets the seconds of this <tt>Date</tt> to the specified value.
860 * This <tt>Date</tt> 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.
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)</code>.
871 public void setSeconds(int seconds) {
872 getCalendarDate().setSeconds(seconds);
876 * Returns the number of milliseconds since January 1, 1970, 00:00:00 GMT
877 * represented by this <tt>Date</tt> object.
879 * @return the number of milliseconds since January 1, 1970, 00:00:00 GMT
880 * represented by this date.
882 public long getTime() {
883 return getTimeImpl();
886 private final long getTimeImpl() {
887 if (cdate != null && !cdate.isNormalized()) {
894 * Sets this <code>Date</code> object to represent a point in time that is
895 * <code>time</code> milliseconds after January 1, 1970 00:00:00 GMT.
897 * @param time the number of milliseconds.
899 public void setTime(long time) {
905 * Tests if this date is before the specified date.
907 * @param when a date.
908 * @return <code>true</code> if and only if the instant of time
909 * represented by this <tt>Date</tt> object is strictly
910 * earlier than the instant represented by <tt>when</tt>;
911 * <code>false</code> otherwise.
912 * @exception NullPointerException if <code>when</code> is null.
914 public boolean before(Date when) {
915 return getMillisOf(this) < getMillisOf(when);
919 * Tests if this date is after the specified date.
921 * @param when a date.
922 * @return <code>true</code> if and only if the instant represented
923 * by this <tt>Date</tt> object is strictly later than the
924 * instant represented by <tt>when</tt>;
925 * <code>false</code> otherwise.
926 * @exception NullPointerException if <code>when</code> is null.
928 public boolean after(Date when) {
929 return getMillisOf(this) > getMillisOf(when);
933 * Compares two dates for equality.
934 * The result is <code>true</code> if and only if the argument is
935 * not <code>null</code> and is a <code>Date</code> object that
936 * represents the same point in time, to the millisecond, as this object.
938 * Thus, two <code>Date</code> objects are equal if and only if the
939 * <code>getTime</code> method returns the same <code>long</code>
942 * @param obj the object to compare with.
943 * @return <code>true</code> if the objects are the same;
944 * <code>false</code> otherwise.
945 * @see java.util.Date#getTime()
947 public boolean equals(Object obj) {
948 return obj instanceof Date && getTime() == ((Date) obj).getTime();
952 * Returns the millisecond value of this <code>Date</code> object
953 * without affecting its internal state.
955 static final long getMillisOf(Date date) {
956 if (date.cdate == null || date.cdate.isNormalized()) {
957 return date.fastTime;
959 BaseCalendar.Date d = (BaseCalendar.Date) date.cdate.clone();
960 return gcal.getTime(d);
964 * Compares two Dates for ordering.
966 * @param anotherDate the <code>Date</code> to be compared.
967 * @return the value <code>0</code> if the argument Date is equal to
968 * this Date; a value less than <code>0</code> if this Date
969 * is before the Date argument; and a value greater than
970 * <code>0</code> if this Date is after the Date argument.
972 * @exception NullPointerException if <code>anotherDate</code> is null.
974 public int compareTo(Date anotherDate) {
975 long thisTime = getMillisOf(this);
976 long anotherTime = getMillisOf(anotherDate);
977 return (thisTime<anotherTime ? -1 : (thisTime==anotherTime ? 0 : 1));
981 * Returns a hash code value for this object. The result is the
982 * exclusive OR of the two halves of the primitive <tt>long</tt>
983 * value returned by the {@link Date#getTime}
984 * method. That is, the hash code is the value of the expression:
986 * (int)(this.getTime()^(this.getTime() >>> 32))</pre></blockquote>
988 * @return a hash code value for this object.
990 public int hashCode() {
991 long ht = this.getTime();
992 return (int) ht ^ (int) (ht >> 32);
996 * Converts this <code>Date</code> object to a <code>String</code>
999 * dow mon dd hh:mm:ss zzz yyyy</pre></blockquote>
1001 * <li><tt>dow</tt> is the day of the week (<tt>Sun, Mon, Tue, Wed,
1002 * Thu, Fri, Sat</tt>).
1003 * <li><tt>mon</tt> is the month (<tt>Jan, Feb, Mar, Apr, May, Jun,
1004 * Jul, Aug, Sep, Oct, Nov, Dec</tt>).
1005 * <li><tt>dd</tt> is the day of the month (<tt>01</tt> through
1006 * <tt>31</tt>), as two decimal digits.
1007 * <li><tt>hh</tt> is the hour of the day (<tt>00</tt> through
1008 * <tt>23</tt>), as two decimal digits.
1009 * <li><tt>mm</tt> is the minute within the hour (<tt>00</tt> through
1010 * <tt>59</tt>), as two decimal digits.
1011 * <li><tt>ss</tt> is the second within the minute (<tt>00</tt> through
1012 * <tt>61</tt>, as two decimal digits.
1013 * <li><tt>zzz</tt> is the time zone (and may reflect daylight saving
1014 * time). Standard time zone abbreviations include those
1015 * recognized by the method <tt>parse</tt>. If time zone
1016 * information is not available, then <tt>zzz</tt> is empty -
1017 * that is, it consists of no characters at all.
1018 * <li><tt>yyyy</tt> is the year, as four decimal digits.
1021 * @return a string representation of this date.
1022 * @see java.util.Date#toLocaleString()
1023 * @see java.util.Date#toGMTString()
1025 public String toString() {
1026 // "EEE MMM dd HH:mm:ss zzz yyyy";
1027 BaseCalendar.Date date = normalize();
1028 StringBuilder sb = new StringBuilder(28);
1029 int index = date.getDayOfWeek();
1030 if (index == gcal.SUNDAY) {
1033 convertToAbbr(sb, wtb[index]).append(' '); // EEE
1034 convertToAbbr(sb, wtb[date.getMonth() - 1 + 2 + 7]).append(' '); // MMM
1035 CalendarUtils.sprintf0d(sb, date.getDayOfMonth(), 2).append(' '); // dd
1037 CalendarUtils.sprintf0d(sb, date.getHours(), 2).append(':'); // HH
1038 CalendarUtils.sprintf0d(sb, date.getMinutes(), 2).append(':'); // mm
1039 CalendarUtils.sprintf0d(sb, date.getSeconds(), 2).append(' '); // ss
1040 TimeZone zi = date.getZone();
1042 sb.append(zi.getDisplayName(date.isDaylightTime(), zi.SHORT, Locale.US)); // zzz
1046 sb.append(' ').append(date.getYear()); // yyyy
1047 return sb.toString();
1051 * Converts the given name to its 3-letter abbreviation (e.g.,
1052 * "monday" -> "Mon") and stored the abbreviation in the given
1053 * <code>StringBuilder</code>.
1055 private static final StringBuilder convertToAbbr(StringBuilder sb, String name) {
1056 sb.append(Character.toUpperCase(name.charAt(0)));
1057 sb.append(name.charAt(1)).append(name.charAt(2));
1062 * Creates a string representation of this <tt>Date</tt> object in an
1063 * implementation-dependent form. The intent is that the form should
1064 * be familiar to the user of the Java application, wherever it may
1065 * happen to be running. The intent is comparable to that of the
1066 * "<code>%c</code>" format supported by the <code>strftime()</code>
1067 * function of ISO C.
1069 * @return a string representation of this date, using the locale
1071 * @see java.text.DateFormat
1072 * @see java.util.Date#toString()
1073 * @see java.util.Date#toGMTString()
1074 * @deprecated As of JDK version 1.1,
1075 * replaced by <code>DateFormat.format(Date date)</code>.
1078 public String toLocaleString() {
1079 DateFormat formatter = DateFormat.getDateTimeInstance();
1080 return formatter.format(this);
1084 * Creates a string representation of this <tt>Date</tt> object of
1087 * d mon yyyy hh:mm:ss GMT</pre></blockquote>
1089 * <li><i>d</i> is the day of the month (<tt>1</tt> through <tt>31</tt>),
1090 * as one or two decimal digits.
1091 * <li><i>mon</i> is the month (<tt>Jan, Feb, Mar, Apr, May, Jun, Jul,
1092 * Aug, Sep, Oct, Nov, Dec</tt>).
1093 * <li><i>yyyy</i> is the year, as four decimal digits.
1094 * <li><i>hh</i> is the hour of the day (<tt>00</tt> through <tt>23</tt>),
1095 * as two decimal digits.
1096 * <li><i>mm</i> is the minute within the hour (<tt>00</tt> through
1097 * <tt>59</tt>), as two decimal digits.
1098 * <li><i>ss</i> is the second within the minute (<tt>00</tt> through
1099 * <tt>61</tt>), as two decimal digits.
1100 * <li><i>GMT</i> is exactly the ASCII letters "<tt>GMT</tt>" to indicate
1101 * Greenwich Mean Time.
1103 * The result does not depend on the local time zone.
1105 * @return a string representation of this date, using the Internet GMT
1107 * @see java.text.DateFormat
1108 * @see java.util.Date#toString()
1109 * @see java.util.Date#toLocaleString()
1110 * @deprecated As of JDK version 1.1,
1111 * replaced by <code>DateFormat.format(Date date)</code>, using a
1112 * GMT <code>TimeZone</code>.
1115 public String toGMTString() {
1116 // d MMM yyyy HH:mm:ss 'GMT'
1118 BaseCalendar cal = getCalendarSystem(t);
1119 BaseCalendar.Date date =
1120 (BaseCalendar.Date) cal.getCalendarDate(getTime(), (TimeZone)null);
1121 StringBuilder sb = new StringBuilder(32);
1122 CalendarUtils.sprintf0d(sb, date.getDayOfMonth(), 1).append(' '); // d
1123 convertToAbbr(sb, wtb[date.getMonth() - 1 + 2 + 7]).append(' '); // MMM
1124 sb.append(date.getYear()).append(' '); // yyyy
1125 CalendarUtils.sprintf0d(sb, date.getHours(), 2).append(':'); // HH
1126 CalendarUtils.sprintf0d(sb, date.getMinutes(), 2).append(':'); // mm
1127 CalendarUtils.sprintf0d(sb, date.getSeconds(), 2); // ss
1128 sb.append(" GMT"); // ' GMT'
1129 return sb.toString();
1133 * Returns the offset, measured in minutes, for the local time zone
1134 * relative to UTC that is appropriate for the time represented by
1135 * this <code>Date</code> object.
1137 * For example, in Massachusetts, five time zones west of Greenwich:
1139 * new Date(96, 1, 14).getTimezoneOffset() returns 300</pre></blockquote>
1140 * because on February 14, 1996, standard time (Eastern Standard Time)
1141 * is in use, which is offset five hours from UTC; but:
1143 * new Date(96, 5, 1).getTimezoneOffset() returns 240</pre></blockquote>
1144 * because on June 1, 1996, daylight saving time (Eastern Daylight Time)
1145 * is in use, which is offset only four hours from UTC.<p>
1146 * This method produces the same result as if it computed:
1148 * (this.getTime() - UTC(this.getYear(),
1152 * this.getMinutes(),
1153 * this.getSeconds())) / (60 * 1000)
1154 * </pre></blockquote>
1156 * @return the time-zone offset, in minutes, for the current time zone.
1157 * @see java.util.Calendar#ZONE_OFFSET
1158 * @see java.util.Calendar#DST_OFFSET
1159 * @see java.util.TimeZone#getDefault
1160 * @deprecated As of JDK version 1.1,
1161 * replaced by <code>-(Calendar.get(Calendar.ZONE_OFFSET) +
1162 * Calendar.get(Calendar.DST_OFFSET)) / (60 * 1000)</code>.
1165 public int getTimezoneOffset() {
1167 if (cdate == null) {
1168 TimeZone tz = TimeZone.getDefaultRef();
1169 if (tz instanceof ZoneInfo) {
1170 zoneOffset = ((ZoneInfo)tz).getOffsets(fastTime, null);
1172 zoneOffset = tz.getOffset(fastTime);
1176 zoneOffset = cdate.getZoneOffset();
1178 return -zoneOffset/60000; // convert to minutes
1181 private final BaseCalendar.Date getCalendarDate() {
1182 if (cdate == null) {
1183 BaseCalendar cal = getCalendarSystem(fastTime);
1184 cdate = (BaseCalendar.Date) cal.getCalendarDate(fastTime,
1185 TimeZone.getDefaultRef());
1190 private final BaseCalendar.Date normalize() {
1191 if (cdate == null) {
1192 BaseCalendar cal = getCalendarSystem(fastTime);
1193 cdate = (BaseCalendar.Date) cal.getCalendarDate(fastTime,
1194 TimeZone.getDefaultRef());
1198 // Normalize cdate with the TimeZone in cdate first. This is
1199 // required for the compatible behavior.
1200 if (!cdate.isNormalized()) {
1201 cdate = normalize(cdate);
1204 // If the default TimeZone has changed, then recalculate the
1205 // fields with the new TimeZone.
1206 TimeZone tz = TimeZone.getDefaultRef();
1207 if (tz != cdate.getZone()) {
1209 CalendarSystem cal = getCalendarSystem(cdate);
1210 cal.getCalendarDate(fastTime, cdate);
1215 // fastTime and the returned data are in sync upon return.
1216 private final BaseCalendar.Date normalize(BaseCalendar.Date date) {
1217 int y = date.getNormalizedYear();
1218 int m = date.getMonth();
1219 int d = date.getDayOfMonth();
1220 int hh = date.getHours();
1221 int mm = date.getMinutes();
1222 int ss = date.getSeconds();
1223 int ms = date.getMillis();
1224 TimeZone tz = date.getZone();
1226 // If the specified year can't be handled using a long value
1227 // in milliseconds, GregorianCalendar is used for full
1228 // compatibility with underflow and overflow. This is required
1229 // by some JCK tests. The limits are based max year values -
1230 // years that can be represented by max values of d, hh, mm,
1231 // ss and ms. Also, let GregorianCalendar handle the default
1232 // cutover year so that we don't need to worry about the
1234 if (y == 1582 || y > 280000000 || y < -280000000) {
1236 tz = TimeZone.getTimeZone("GMT");
1238 GregorianCalendar gc = new GregorianCalendar(tz);
1240 gc.set(gc.MILLISECOND, ms);
1241 gc.set(y, m-1, d, hh, mm, ss);
1242 fastTime = gc.getTimeInMillis();
1243 BaseCalendar cal = getCalendarSystem(fastTime);
1244 date = (BaseCalendar.Date) cal.getCalendarDate(fastTime, tz);
1248 BaseCalendar cal = getCalendarSystem(y);
1249 if (cal != getCalendarSystem(date)) {
1250 date = (BaseCalendar.Date) cal.newCalendarDate(tz);
1251 date.setNormalizedDate(y, m, d).setTimeOfDay(hh, mm, ss, ms);
1253 // Perform the GregorianCalendar-style normalization.
1254 fastTime = cal.getTime(date);
1256 // In case the normalized date requires the other calendar
1257 // system, we need to recalculate it using the other one.
1258 BaseCalendar ncal = getCalendarSystem(fastTime);
1260 date = (BaseCalendar.Date) ncal.newCalendarDate(tz);
1261 date.setNormalizedDate(y, m, d).setTimeOfDay(hh, mm, ss, ms);
1262 fastTime = ncal.getTime(date);
1268 * Returns the Gregorian or Julian calendar system to use with the
1269 * given date. Use Gregorian from October 15, 1582.
1271 * @param year normalized calendar year (not -1900)
1272 * @return the CalendarSystem to use for the specified date
1274 private static final BaseCalendar getCalendarSystem(int year) {
1278 return getJulianCalendar();
1281 private static final BaseCalendar getCalendarSystem(long utc) {
1282 // Quickly check if the time stamp given by `utc' is the Epoch
1283 // or later. If it's before 1970, we convert the cutover to
1284 // local time to compare.
1286 || utc >= GregorianCalendar.DEFAULT_GREGORIAN_CUTOVER
1287 - TimeZone.getDefaultRef().getOffset(utc)) {
1290 return getJulianCalendar();
1293 private static final BaseCalendar getCalendarSystem(BaseCalendar.Date cdate) {
1297 if (cdate.getEra() != null) {
1303 synchronized private static final BaseCalendar getJulianCalendar() {
1305 jcal = (BaseCalendar) CalendarSystem.forName("julian");
1311 * Save the state of this object to a stream (i.e., serialize it).
1313 * @serialData The value returned by <code>getTime()</code>
1314 * is emitted (long). This represents the offset from
1315 * January 1, 1970, 00:00:00 GMT in milliseconds.
1317 private void writeObject(ObjectOutputStream s)
1320 s.writeLong(getTimeImpl());
1324 * Reconstitute this object from a stream (i.e., deserialize it).
1326 private void readObject(ObjectInputStream s)
1327 throws IOException, ClassNotFoundException
1329 fastTime = s.readLong();