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;
34 * The class <code>Date</code> represents a specific instant
35 * in time, with millisecond precision.
37 * Prior to JDK 1.1, the class <code>Date</code> had two additional
38 * functions. It allowed the interpretation of dates as year, month, day, hour,
39 * minute, and second values. It also allowed the formatting and parsing
40 * of date strings. Unfortunately, the API for these functions was not
41 * amenable to internationalization. As of JDK 1.1, the
42 * <code>Calendar</code> class should be used to convert between dates and time
43 * fields and the <code>DateFormat</code> class should be used to format and
45 * The corresponding methods in <code>Date</code> are deprecated.
47 * Although the <code>Date</code> class is intended to reflect
48 * coordinated universal time (UTC), it may not do so exactly,
49 * depending on the host environment of the Java Virtual Machine.
50 * Nearly all modern operating systems assume that 1 day =
51 * 24 × 60 × 60 = 86400 seconds
52 * in all cases. In UTC, however, about once every year or two there
53 * is an extra second, called a "leap second." The leap
54 * second is always added as the last second of the day, and always
55 * on December 31 or June 30. For example, the last minute of the
56 * year 1995 was 61 seconds long, thanks to an added leap second.
57 * Most computer clocks are not accurate enough to be able to reflect
58 * the leap-second distinction.
60 * Some computer standards are defined in terms of Greenwich mean
61 * time (GMT), which is equivalent to universal time (UT). GMT is
62 * the "civil" name for the standard; UT is the
63 * "scientific" name for the same standard. The
64 * distinction between UTC and UT is that UTC is based on an atomic
65 * clock and UT is based on astronomical observations, which for all
66 * practical purposes is an invisibly fine hair to split. Because the
67 * earth's rotation is not uniform (it slows down and speeds up
68 * in complicated ways), UT does not always flow uniformly. Leap
69 * seconds are introduced as needed into UTC so as to keep UTC within
70 * 0.9 seconds of UT1, which is a version of UT with certain
71 * corrections applied. There are other time and date systems as
72 * well; for example, the time scale used by the satellite-based
73 * global positioning system (GPS) is synchronized to UTC but is
74 * <i>not</i> adjusted for leap seconds. An interesting source of
75 * further information is the U.S. Naval Observatory, particularly
76 * the Directorate of Time at:
78 * <a href=http://tycho.usno.navy.mil>http://tycho.usno.navy.mil</a>
81 * and their definitions of "Systems of Time" at:
83 * <a href=http://tycho.usno.navy.mil/systime.html>http://tycho.usno.navy.mil/systime.html</a>
86 * In all methods of class <code>Date</code> that accept or return
87 * year, month, date, hours, minutes, and seconds values, the
88 * following representations are used:
90 * <li>A year <i>y</i> is represented by the integer
91 * <i>y</i> <code>- 1900</code>.
92 * <li>A month is represented by an integer from 0 to 11; 0 is January,
93 * 1 is February, and so forth; thus 11 is December.
94 * <li>A date (day of month) is represented by an integer from 1 to 31
95 * in the usual manner.
96 * <li>An hour is represented by an integer from 0 to 23. Thus, the hour
97 * from midnight to 1 a.m. is hour 0, and the hour from noon to 1
99 * <li>A minute is represented by an integer from 0 to 59 in the usual manner.
100 * <li>A second is represented by an integer from 0 to 61; the values 60 and
101 * 61 occur only for leap seconds and even then only in Java
102 * implementations that actually track leap seconds correctly. Because
103 * of the manner in which leap seconds are currently introduced, it is
104 * extremely unlikely that two leap seconds will occur in the same
105 * minute, but this specification follows the date and time conventions
109 * In all cases, arguments given to methods for these purposes need
110 * not fall within the indicated ranges; for example, a date may be
111 * specified as January 32 and is interpreted as meaning February 1.
113 * @author James Gosling
114 * @author Arthur van Hoff
116 * @see java.text.DateFormat
117 * @see java.util.Calendar
118 * @see java.util.TimeZone
122 implements java.io.Serializable, Cloneable, Comparable<Date>
124 private static final BaseCalendar gcal = new BaseCalendar();
126 private static BaseCalendar jcal;
128 private transient long fastTime;
131 * If cdate is null, then fastTime indicates the time in millis.
132 * If cdate.isNormalized() is true, then fastTime and cdate are in
133 * synch. Otherwise, fastTime is ignored, and cdate indicates the
136 private transient BaseCalendar.Datum cdate;
138 // Initialized just before the value is used. See parse().
139 private static int defaultCenturyStart;
141 /* use serialVersionUID from modified java.util.Date for
142 * interoperability with JDK1.1. The Date was modified to write
143 * and read only the UTC time.
145 private static final long serialVersionUID = 7523967970034938905L;
148 * Allocates a <code>Date</code> object and initializes it so that
149 * it represents the time at which it was allocated, measured to the
150 * nearest millisecond.
152 * @see java.lang.System#currentTimeMillis()
155 this(System.currentTimeMillis());
159 * Allocates a <code>Date</code> object and initializes it to
160 * represent the specified number of milliseconds since the
161 * standard base time known as "the epoch", namely January 1,
162 * 1970, 00:00:00 GMT.
164 * @param date the milliseconds since January 1, 1970, 00:00:00 GMT.
165 * @see java.lang.System#currentTimeMillis()
167 public Date(long date) {
172 * Allocates a <code>Date</code> object and initializes it so that
173 * it represents midnight, local time, at the beginning of the day
174 * specified by the <code>year</code>, <code>month</code>, and
175 * <code>date</code> arguments.
177 * @param year the year minus 1900.
178 * @param month the month between 0-11.
179 * @param date the day of the month between 1-31.
180 * @see java.util.Calendar
181 * @deprecated As of JDK version 1.1,
182 * replaced by <code>Calendar.set(year + 1900, month, date)</code>
183 * or <code>GregorianCalendar(year + 1900, month, date)</code>.
186 public Date(int year, int month, int date) {
187 this(year, month, date, 0, 0, 0);
191 * Allocates a <code>Date</code> object and initializes it so that
192 * it represents the instant at the start of the minute specified by
193 * the <code>year</code>, <code>month</code>, <code>date</code>,
194 * <code>hrs</code>, and <code>min</code> arguments, in the local
197 * @param year the year minus 1900.
198 * @param month the month between 0-11.
199 * @param date the day of the month between 1-31.
200 * @param hrs the hours between 0-23.
201 * @param min the minutes between 0-59.
202 * @see java.util.Calendar
203 * @deprecated As of JDK version 1.1,
204 * replaced by <code>Calendar.set(year + 1900, month, date,
205 * hrs, min)</code> or <code>GregorianCalendar(year + 1900,
206 * month, date, hrs, min)</code>.
209 public Date(int year, int month, int date, int hrs, int min) {
210 this(year, month, date, hrs, min, 0);
214 * Allocates a <code>Date</code> object and initializes it so that
215 * it represents the instant at the start of the second specified
216 * by the <code>year</code>, <code>month</code>, <code>date</code>,
217 * <code>hrs</code>, <code>min</code>, and <code>sec</code> arguments,
218 * in the local time zone.
220 * @param year the year minus 1900.
221 * @param month the month between 0-11.
222 * @param date the day of the month between 1-31.
223 * @param hrs the hours between 0-23.
224 * @param min the minutes between 0-59.
225 * @param sec the seconds between 0-59.
226 * @see java.util.Calendar
227 * @deprecated As of JDK version 1.1,
228 * replaced by <code>Calendar.set(year + 1900, month, date,
229 * hrs, min, sec)</code> or <code>GregorianCalendar(year + 1900,
230 * month, date, hrs, min, sec)</code>.
233 public Date(int year, int month, int date, int hrs, int min, int sec) {
235 // month is 0-based. So we have to normalize month to support Long.MAX_VALUE.
239 } else if (month < 0) {
243 BaseCalendar cal = getCalendarSystem(y);
244 cdate = (BaseCalendar.Datum) cal.newCalendarDate(TimeZone.getDefaultRef());
245 cdate.setNormalizedDate(y, month + 1, date).setTimeOfDay(hrs, min, sec, 0);
251 * Allocates a <code>Date</code> object and initializes it so that
252 * it represents the date and time indicated by the string
253 * <code>s</code>, which is interpreted as if by the
254 * {@link Date#parse} method.
256 * @param s a string representation of the date.
257 * @see java.text.DateFormat
258 * @see java.util.Date#parse(java.lang.String)
259 * @deprecated As of JDK version 1.1,
260 * replaced by <code>DateFormat.parse(String s)</code>.
263 public Date(String s) {
268 * Return a copy of this object.
270 public Object clone() {
273 d = (Date)super.clone();
275 d.cdate = (BaseCalendar.Datum) cdate.clone();
277 } catch (CloneNotSupportedException e) {} // Won't happen
282 * Determines the date and time based on the arguments. The
283 * arguments are interpreted as a year, month, day of the month,
284 * hour of the day, minute within the hour, and second within the
285 * minute, exactly as for the <tt>Date</tt> constructor with six
286 * arguments, except that the arguments are interpreted relative
287 * to UTC rather than to the local time zone. The time indicated is
288 * returned represented as the distance, measured in milliseconds,
289 * of that time from the epoch (00:00:00 GMT on January 1, 1970).
291 * @param year the year minus 1900.
292 * @param month the month between 0-11.
293 * @param date the day of the month between 1-31.
294 * @param hrs the hours between 0-23.
295 * @param min the minutes between 0-59.
296 * @param sec the seconds between 0-59.
297 * @return the number of milliseconds since January 1, 1970, 00:00:00 GMT for
298 * the date and time specified by the arguments.
299 * @see java.util.Calendar
300 * @deprecated As of JDK version 1.1,
301 * replaced by <code>Calendar.set(year + 1900, month, date,
302 * hrs, min, sec)</code> or <code>GregorianCalendar(year + 1900,
303 * month, date, hrs, min, sec)</code>, using a UTC
304 * <code>TimeZone</code>, followed by <code>Calendar.getTime().getTime()</code>.
307 public static long UTC(int year, int month, int date,
308 int hrs, int min, int sec) {
310 // month is 0-based. So we have to normalize month to support Long.MAX_VALUE.
314 } else if (month < 0) {
319 BaseCalendar cal = getCalendarSystem(y);
320 BaseCalendar.Datum udate = (BaseCalendar.Datum) cal.newCalendarDate(null);
321 udate.setNormalizedDate(y, m, date).setTimeOfDay(hrs, min, sec, 0);
323 // Use a Date instance to perform normalization. Its fastTime
324 // is the UTC value after the normalization.
325 Date d = new Date(0);
331 * Attempts to interpret the string <tt>s</tt> as a representation
332 * of a date and time. If the attempt is successful, the time
333 * indicated is returned represented as the distance, measured in
334 * milliseconds, of that time from the epoch (00:00:00 GMT on
335 * January 1, 1970). If the attempt fails, an
336 * <tt>IllegalArgumentException</tt> is thrown.
338 * It accepts many syntaxes; in particular, it recognizes the IETF
339 * standard date syntax: "Sat, 12 Aug 1995 13:30:00 GMT". It also
340 * understands the continental U.S. time-zone abbreviations, but for
341 * general use, a time-zone offset should be used: "Sat, 12 Aug 1995
342 * 13:30:00 GMT+0430" (4 hours, 30 minutes west of the Greenwich
343 * meridian). If no time zone is specified, the local time zone is
344 * assumed. GMT and UTC are considered equivalent.
346 * The string <tt>s</tt> is processed from left to right, looking for
347 * data of interest. Any material in <tt>s</tt> that is within the
348 * ASCII parenthesis characters <tt>(</tt> and <tt>)</tt> is ignored.
349 * Parentheses may be nested. Otherwise, the only characters permitted
350 * within <tt>s</tt> are these ASCII characters:
352 * abcdefghijklmnopqrstuvwxyz
353 * ABCDEFGHIJKLMNOPQRSTUVWXYZ
354 * 0123456789,+-:/</pre></blockquote>
355 * and whitespace characters.<p>
356 * A consecutive sequence of decimal digits is treated as a decimal
358 * <li>If a number is preceded by <tt>+</tt> or <tt>-</tt> and a year
359 * has already been recognized, then the number is a time-zone
360 * offset. If the number is less than 24, it is an offset measured
361 * in hours. Otherwise, it is regarded as an offset in minutes,
362 * expressed in 24-hour time format without punctuation. A
363 * preceding <tt>-</tt> means a westward offset. Time zone offsets
364 * are always relative to UTC (Greenwich). Thus, for example,
365 * <tt>-5</tt> occurring in the string would mean "five hours west
366 * of Greenwich" and <tt>+0430</tt> would mean "four hours and
367 * thirty minutes east of Greenwich." It is permitted for the
368 * string to specify <tt>GMT</tt>, <tt>UT</tt>, or <tt>UTC</tt>
369 * redundantly-for example, <tt>GMT-5</tt> or <tt>utc+0430</tt>.
370 * <li>The number is regarded as a year number if one of the
371 * following conditions is true:
373 * <li>The number is equal to or greater than 70 and followed by a
374 * space, comma, slash, or end of string
375 * <li>The number is less than 70, and both a month and a day of
376 * the month have already been recognized</li>
378 * If the recognized year number is less than 100, it is
379 * interpreted as an abbreviated year relative to a century of
380 * which dates are within 80 years before and 19 years after
381 * the time when the Date class is initialized.
382 * After adjusting the year number, 1900 is subtracted from
383 * it. For example, if the current year is 1999 then years in
384 * the range 19 to 99 are assumed to mean 1919 to 1999, while
385 * years from 0 to 18 are assumed to mean 2000 to 2018. Note
386 * that this is slightly different from the interpretation of
387 * years less than 100 that is used in {@link java.text.SimpleDateFormat}.
388 * <li>If the number is followed by a colon, it is regarded as an hour,
389 * unless an hour has already been recognized, in which case it is
390 * regarded as a minute.
391 * <li>If the number is followed by a slash, it is regarded as a month
392 * (it is decreased by 1 to produce a number in the range <tt>0</tt>
393 * to <tt>11</tt>), unless a month has already been recognized, in
394 * which case it is regarded as a day of the month.
395 * <li>If the number is followed by whitespace, a comma, a hyphen, or
396 * end of string, then if an hour has been recognized but not a
397 * minute, it is regarded as a minute; otherwise, if a minute has
398 * been recognized but not a second, it is regarded as a second;
399 * otherwise, it is regarded as a day of the month. </ul><p>
400 * A consecutive sequence of letters is regarded as a word and treated
402 * <li>A word that matches <tt>AM</tt>, ignoring case, is ignored (but
403 * the parse fails if an hour has not been recognized or is less
404 * than <tt>1</tt> or greater than <tt>12</tt>).
405 * <li>A word that matches <tt>PM</tt>, ignoring case, adds <tt>12</tt>
406 * to the hour (but the parse fails if an hour has not been
407 * recognized or is less than <tt>1</tt> or greater than <tt>12</tt>).
408 * <li>Any word that matches any prefix of <tt>SUNDAY, MONDAY, TUESDAY,
409 * WEDNESDAY, THURSDAY, FRIDAY</tt>, or <tt>SATURDAY</tt>, ignoring
410 * case, is ignored. For example, <tt>sat, Friday, TUE</tt>, and
411 * <tt>Thurs</tt> are ignored.
412 * <li>Otherwise, any word that matches any prefix of <tt>JANUARY,
413 * FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, AUGUST, SEPTEMBER,
414 * OCTOBER, NOVEMBER</tt>, or <tt>DECEMBER</tt>, ignoring case, and
415 * considering them in the order given here, is recognized as
416 * specifying a month and is converted to a number (<tt>0</tt> to
417 * <tt>11</tt>). For example, <tt>aug, Sept, april</tt>, and
418 * <tt>NOV</tt> are recognized as months. So is <tt>Ma</tt>, which
419 * is recognized as <tt>MARCH</tt>, not <tt>MAY</tt>.
420 * <li>Any word that matches <tt>GMT, UT</tt>, or <tt>UTC</tt>, ignoring
421 * case, is treated as referring to UTC.
422 * <li>Any word that matches <tt>EST, CST, MST</tt>, or <tt>PST</tt>,
423 * ignoring case, is recognized as referring to the time zone in
424 * North America that is five, six, seven, or eight hours west of
425 * Greenwich, respectively. Any word that matches <tt>EDT, CDT,
426 * MDT</tt>, or <tt>PDT</tt>, ignoring case, is recognized as
427 * referring to the same time zone, respectively, during daylight
428 * saving time.</ul><p>
429 * Once the entire string s has been scanned, it is converted to a time
430 * result in one of two ways. If a time zone or time-zone offset has been
431 * recognized, then the year, month, day of month, hour, minute, and
432 * second are interpreted in UTC and then the time-zone offset is
433 * applied. Otherwise, the year, month, day of month, hour, minute, and
434 * second are interpreted in the local time zone.
436 * @param s a string to be parsed as a date.
437 * @return the number of milliseconds since January 1, 1970, 00:00:00 GMT
438 * represented by the string argument.
439 * @see java.text.DateFormat
440 * @deprecated As of JDK version 1.1,
441 * replaced by <code>DateFormat.parse(String s)</code>.
444 public static long parse(String s) {
445 int year = Integer.MIN_VALUE;
462 int limit = s.length();
466 if (c <= ' ' || c == ',')
468 if (c == '(') { // skip comments
473 if (c == '(') depth++;
480 if ('0' <= c && c <= '9') {
482 while (i < limit && '0' <= (c = s.charAt(i)) && c <= '9') {
483 n = n * 10 + c - '0';
486 if (prevc == '+' || prevc == '-' && year != Integer.MIN_VALUE) {
489 n = n * 60; // EG. "GMT-3"
491 n = n % 100 + n / 100 * 60; // eg "GMT-0430"
492 if (prevc == '+') // plus means east of GMT
494 if (tzoffset != 0 && tzoffset != -1)
498 if (year != Integer.MIN_VALUE)
500 else if (c <= ' ' || c == ',' || c == '/' || i >= limit)
501 // year = n < 1900 ? n : n - 1900;
514 mon = (byte) (n - 1);
519 else if (i < limit && c != ',' && c > ' ' && c != '-')
521 else if (hour >= 0 && min < 0)
523 else if (min >= 0 && sec < 0)
527 // Handle two-digit years < 70 (70-99 handled above).
528 else if (year == Integer.MIN_VALUE && mon >= 0 && mday >= 0)
533 } else if (c == '/' || c == ':' || c == '+' || c == '-')
539 if (!('A' <= c && c <= 'Z' || 'a' <= c && c <= 'z'))
546 for (k = wtb.length; --k >= 0;)
547 if (wtb[k].regionMatches(true, 0, s, st, i - st)) {
550 if (action == 1) { // pm
551 if (hour > 12 || hour < 1)
555 } else if (action == 14) { // am
556 if (hour > 12 || hour < 1)
560 } else if (action <= 13) { // month!
562 mon = (byte) (action - 2);
566 tzoffset = action - 10000;
576 if (year == Integer.MIN_VALUE || mon < 0 || mday < 0)
578 // Parse 2-digit years within the correct default century.
580 synchronized (Date.class) {
581 if (defaultCenturyStart == 0) {
582 defaultCenturyStart = gcal.getCalendarDate().getYear() - 80;
585 year += (defaultCenturyStart / 100) * 100;
586 if (year < defaultCenturyStart) year += 100;
594 BaseCalendar cal = getCalendarSystem(year);
595 if (tzoffset == -1) { // no time zone specified, have to use local
596 BaseCalendar.Datum ldate = (BaseCalendar.Datum) cal.newCalendarDate(TimeZone.getDefaultRef());
597 ldate.setDate(year, mon + 1, mday);
598 ldate.setTimeOfDay(hour, min, sec, 0);
599 return cal.getTime(ldate);
601 BaseCalendar.Datum udate = (BaseCalendar.Datum) cal.newCalendarDate(null); // no time zone
602 udate.setDate(year, mon + 1, mday);
603 udate.setTimeOfDay(hour, min, sec, 0);
604 return cal.getTime(udate) + tzoffset * (60 * 1000);
607 throw new IllegalArgumentException();
609 private final static String wtb[] = {
611 "monday", "tuesday", "wednesday", "thursday", "friday",
612 "saturday", "sunday",
613 "january", "february", "march", "april", "may", "june",
614 "july", "august", "september", "october", "november", "december",
615 "gmt", "ut", "utc", "est", "edt", "cst", "cdt",
616 "mst", "mdt", "pst", "pdt"
618 private final static int ttb[] = {
619 14, 1, 0, 0, 0, 0, 0, 0, 0,
620 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
621 10000 + 0, 10000 + 0, 10000 + 0, // GMT/UT/UTC
622 10000 + 5 * 60, 10000 + 4 * 60, // EST/EDT
623 10000 + 6 * 60, 10000 + 5 * 60, // CST/CDT
624 10000 + 7 * 60, 10000 + 6 * 60, // MST/MDT
625 10000 + 8 * 60, 10000 + 7 * 60 // PST/PDT
629 * Returns a value that is the result of subtracting 1900 from the
630 * year that contains or begins with the instant in time represented
631 * by this <code>Date</code> object, as interpreted in the local
634 * @return the year represented by this date, minus 1900.
635 * @see java.util.Calendar
636 * @deprecated As of JDK version 1.1,
637 * replaced by <code>Calendar.get(Calendar.YEAR) - 1900</code>.
640 public int getYear() {
641 return normalize().getYear() - 1900;
645 * Sets the year of this <tt>Date</tt> object to be the specified
646 * value plus 1900. This <code>Date</code> object is modified so
647 * that it represents a point in time within the specified year,
648 * with the month, date, hour, minute, and second the same as
649 * before, as interpreted in the local time zone. (Of course, if
650 * the date was February 29, for example, and the year is set to a
651 * non-leap year, then the new date will be treated as if it were
654 * @param year the year value.
655 * @see java.util.Calendar
656 * @deprecated As of JDK version 1.1,
657 * replaced by <code>Calendar.set(Calendar.YEAR, year + 1900)</code>.
660 public void setYear(int year) {
661 getCalendarDate().setNormalizedYear(year + 1900);
665 * Returns a number representing the month that contains or begins
666 * with the instant in time represented by this <tt>Date</tt> object.
667 * The value returned is between <code>0</code> and <code>11</code>,
668 * with the value <code>0</code> representing January.
670 * @return the month represented by this date.
671 * @see java.util.Calendar
672 * @deprecated As of JDK version 1.1,
673 * replaced by <code>Calendar.get(Calendar.MONTH)</code>.
676 public int getMonth() {
677 return normalize().getMonth() - 1; // adjust 1-based to 0-based
681 * Sets the month of this date to the specified value. This
682 * <tt>Date</tt> object is modified so that it represents a point
683 * in time within the specified month, with the year, date, hour,
684 * minute, and second the same as before, as interpreted in the
685 * local time zone. If the date was October 31, for example, and
686 * the month is set to June, then the new date will be treated as
687 * if it were on July 1, because June has only 30 days.
689 * @param month the month value between 0-11.
690 * @see java.util.Calendar
691 * @deprecated As of JDK version 1.1,
692 * replaced by <code>Calendar.set(Calendar.MONTH, int month)</code>.
695 public void setMonth(int month) {
700 } else if (month < 0) {
704 BaseCalendar.Datum d = getCalendarDate();
706 d.setNormalizedYear(d.getNormalizedYear() + y);
708 d.setMonth(month + 1); // adjust 0-based to 1-based month numbering
712 * Returns the day of the month represented by this <tt>Date</tt> object.
713 * The value returned is between <code>1</code> and <code>31</code>
714 * representing the day of the month that contains or begins with the
715 * instant in time represented by this <tt>Date</tt> object, as
716 * interpreted in the local time zone.
718 * @return the day of the month represented by this date.
719 * @see java.util.Calendar
720 * @deprecated As of JDK version 1.1,
721 * replaced by <code>Calendar.get(Calendar.DAY_OF_MONTH)</code>.
725 public int getDate() {
726 return normalize().getDayOfMonth();
730 * Sets the day of the month of this <tt>Date</tt> object to the
731 * specified value. This <tt>Date</tt> object is modified so that
732 * it represents a point in time within the specified day of the
733 * month, with the year, month, hour, minute, and second the same
734 * as before, as interpreted in the local time zone. If the date
735 * was April 30, for example, and the date is set to 31, then it
736 * will be treated as if it were on May 1, because April has only
739 * @param date the day of the month value between 1-31.
740 * @see java.util.Calendar
741 * @deprecated As of JDK version 1.1,
742 * replaced by <code>Calendar.set(Calendar.DAY_OF_MONTH, int date)</code>.
745 public void setDate(int date) {
746 getCalendarDate().setDayOfMonth(date);
750 * Returns the day of the week represented by this date. The
751 * returned value (<tt>0</tt> = Sunday, <tt>1</tt> = Monday,
752 * <tt>2</tt> = Tuesday, <tt>3</tt> = Wednesday, <tt>4</tt> =
753 * Thursday, <tt>5</tt> = Friday, <tt>6</tt> = Saturday)
754 * represents the day of the week that contains or begins with
755 * the instant in time represented by this <tt>Date</tt> object,
756 * as interpreted in the local time zone.
758 * @return the day of the week represented by this date.
759 * @see java.util.Calendar
760 * @deprecated As of JDK version 1.1,
761 * replaced by <code>Calendar.get(Calendar.DAY_OF_WEEK)</code>.
764 public int getDay() {
765 return normalize().getDayOfWeek() - 7;//gcal.SUNDAY;
769 * Returns the hour represented by this <tt>Date</tt> object. The
770 * returned value is a number (<tt>0</tt> through <tt>23</tt>)
771 * representing the hour within the day that contains or begins
772 * with the instant in time represented by this <tt>Date</tt>
773 * object, as interpreted in the local time zone.
775 * @return the hour represented by this date.
776 * @see java.util.Calendar
777 * @deprecated As of JDK version 1.1,
778 * replaced by <code>Calendar.get(Calendar.HOUR_OF_DAY)</code>.
781 public int getHours() {
782 return normalize().getHours();
786 * Sets the hour of this <tt>Date</tt> object to the specified value.
787 * This <tt>Date</tt> object is modified so that it represents a point
788 * in time within the specified hour of the day, with the year, month,
789 * date, minute, and second the same as before, as interpreted in the
792 * @param hours the hour value.
793 * @see java.util.Calendar
794 * @deprecated As of JDK version 1.1,
795 * replaced by <code>Calendar.set(Calendar.HOUR_OF_DAY, int hours)</code>.
798 public void setHours(int hours) {
799 getCalendarDate().setHours(hours);
803 * Returns the number of minutes past the hour represented by this date,
804 * as interpreted in the local time zone.
805 * The value returned is between <code>0</code> and <code>59</code>.
807 * @return the number of minutes past the hour represented by this date.
808 * @see java.util.Calendar
809 * @deprecated As of JDK version 1.1,
810 * replaced by <code>Calendar.get(Calendar.MINUTE)</code>.
813 public int getMinutes() {
814 return normalize().getMinutes();
818 * Sets the minutes of this <tt>Date</tt> object to the specified value.
819 * This <tt>Date</tt> object is modified so that it represents a point
820 * in time within the specified minute of the hour, with the year, month,
821 * date, hour, and second the same as before, as interpreted in the
824 * @param minutes the value of the minutes.
825 * @see java.util.Calendar
826 * @deprecated As of JDK version 1.1,
827 * replaced by <code>Calendar.set(Calendar.MINUTE, int minutes)</code>.
830 public void setMinutes(int minutes) {
831 getCalendarDate().setMinutes(minutes);
835 * Returns the number of seconds past the minute represented by this date.
836 * The value returned is between <code>0</code> and <code>61</code>. The
837 * values <code>60</code> and <code>61</code> can only occur on those
838 * Java Virtual Machines that take leap seconds into account.
840 * @return the number of seconds past the minute represented by this date.
841 * @see java.util.Calendar
842 * @deprecated As of JDK version 1.1,
843 * replaced by <code>Calendar.get(Calendar.SECOND)</code>.
846 public int getSeconds() {
847 return normalize().getSeconds();
851 * Sets the seconds of this <tt>Date</tt> to the specified value.
852 * This <tt>Date</tt> object is modified so that it represents a
853 * point in time within the specified second of the minute, with
854 * the year, month, date, hour, and minute the same as before, as
855 * interpreted in the local time zone.
857 * @param seconds the seconds value.
858 * @see java.util.Calendar
859 * @deprecated As of JDK version 1.1,
860 * replaced by <code>Calendar.set(Calendar.SECOND, int seconds)</code>.
863 public void setSeconds(int seconds) {
864 getCalendarDate().setSeconds(seconds);
868 * Returns the number of milliseconds since January 1, 1970, 00:00:00 GMT
869 * represented by this <tt>Date</tt> object.
871 * @return the number of milliseconds since January 1, 1970, 00:00:00 GMT
872 * represented by this date.
874 public long getTime() {
875 return getTimeImpl();
878 private final long getTimeImpl() {
879 if (cdate != null && !cdate.isNormalized()) {
886 * Sets this <code>Date</code> object to represent a point in time that is
887 * <code>time</code> milliseconds after January 1, 1970 00:00:00 GMT.
889 * @param time the number of milliseconds.
891 public void setTime(long time) {
897 * Tests if this date is before the specified date.
899 * @param when a date.
900 * @return <code>true</code> if and only if the instant of time
901 * represented by this <tt>Date</tt> object is strictly
902 * earlier than the instant represented by <tt>when</tt>;
903 * <code>false</code> otherwise.
904 * @exception NullPointerException if <code>when</code> is null.
906 public boolean before(Date when) {
907 return getMillisOf(this) < getMillisOf(when);
911 * Tests if this date is after the specified date.
913 * @param when a date.
914 * @return <code>true</code> if and only if the instant represented
915 * by this <tt>Date</tt> object is strictly later than the
916 * instant represented by <tt>when</tt>;
917 * <code>false</code> otherwise.
918 * @exception NullPointerException if <code>when</code> is null.
920 public boolean after(Date when) {
921 return getMillisOf(this) > getMillisOf(when);
925 * Compares two dates for equality.
926 * The result is <code>true</code> if and only if the argument is
927 * not <code>null</code> and is a <code>Date</code> object that
928 * represents the same point in time, to the millisecond, as this object.
930 * Thus, two <code>Date</code> objects are equal if and only if the
931 * <code>getTime</code> method returns the same <code>long</code>
934 * @param obj the object to compare with.
935 * @return <code>true</code> if the objects are the same;
936 * <code>false</code> otherwise.
937 * @see java.util.Date#getTime()
939 public boolean equals(Object obj) {
940 return obj instanceof Date && getTime() == ((Date) obj).getTime();
944 * Returns the millisecond value of this <code>Date</code> object
945 * without affecting its internal state.
947 static final long getMillisOf(Date date) {
948 if (date.cdate == null || date.cdate.isNormalized()) {
949 return date.fastTime;
951 BaseCalendar.Datum d = (BaseCalendar.Datum) date.cdate.clone();
952 return gcal.getTime(d);
956 * Compares two Dates for ordering.
958 * @param anotherDate the <code>Date</code> to be compared.
959 * @return the value <code>0</code> if the argument Date is equal to
960 * this Date; a value less than <code>0</code> if this Date
961 * is before the Date argument; and a value greater than
962 * <code>0</code> if this Date is after the Date argument.
964 * @exception NullPointerException if <code>anotherDate</code> is null.
966 public int compareTo(Date anotherDate) {
967 long thisTime = getMillisOf(this);
968 long anotherTime = getMillisOf(anotherDate);
969 return (thisTime<anotherTime ? -1 : (thisTime==anotherTime ? 0 : 1));
973 * Returns a hash code value for this object. The result is the
974 * exclusive OR of the two halves of the primitive <tt>long</tt>
975 * value returned by the {@link Date#getTime}
976 * method. That is, the hash code is the value of the expression:
978 * (int)(this.getTime()^(this.getTime() >>> 32))</pre></blockquote>
980 * @return a hash code value for this object.
982 public int hashCode() {
983 long ht = this.getTime();
984 return (int) ht ^ (int) (ht >> 32);
988 * Converts this <code>Date</code> object to a <code>String</code>
991 * dow mon dd hh:mm:ss zzz yyyy</pre></blockquote>
993 * <li><tt>dow</tt> is the day of the week (<tt>Sun, Mon, Tue, Wed,
994 * Thu, Fri, Sat</tt>).
995 * <li><tt>mon</tt> is the month (<tt>Jan, Feb, Mar, Apr, May, Jun,
996 * Jul, Aug, Sep, Oct, Nov, Dec</tt>).
997 * <li><tt>dd</tt> is the day of the month (<tt>01</tt> through
998 * <tt>31</tt>), as two decimal digits.
999 * <li><tt>hh</tt> is the hour of the day (<tt>00</tt> through
1000 * <tt>23</tt>), as two decimal digits.
1001 * <li><tt>mm</tt> is the minute within the hour (<tt>00</tt> through
1002 * <tt>59</tt>), as two decimal digits.
1003 * <li><tt>ss</tt> is the second within the minute (<tt>00</tt> through
1004 * <tt>61</tt>, as two decimal digits.
1005 * <li><tt>zzz</tt> is the time zone (and may reflect daylight saving
1006 * time). Standard time zone abbreviations include those
1007 * recognized by the method <tt>parse</tt>. If time zone
1008 * information is not available, then <tt>zzz</tt> is empty -
1009 * that is, it consists of no characters at all.
1010 * <li><tt>yyyy</tt> is the year, as four decimal digits.
1013 * @return a string representation of this date.
1014 * @see java.util.Date#toLocaleString()
1015 * @see java.util.Date#toGMTString()
1017 public String toString() {
1018 // "EEE MMM dd HH:mm:ss zzz yyyy";
1019 BaseCalendar.Datum date = normalize();
1020 StringBuilder sb = new StringBuilder(28);
1021 int index = date.getDayOfWeek();
1025 convertToAbbr(sb, wtb[index]).append(' '); // EEE
1026 convertToAbbr(sb, wtb[date.getMonth() - 1 + 2 + 7]).append(' '); // MMM
1027 // CalendarUtils.sprintf0d(sb, date.getDayOfMonth(), 2).append(' '); // dd
1029 // CalendarUtils.sprintf0d(sb, date.getHours(), 2).append(':'); // HH
1030 // CalendarUtils.sprintf0d(sb, date.getMinutes(), 2).append(':'); // mm
1031 // CalendarUtils.sprintf0d(sb, date.getSeconds(), 2).append(' '); // ss
1032 // TimeZone zi = date.getZone();
1033 // if (zi != null) {
1034 // sb.append(zi.getDisplayName(date.isDaylightTime(), zi.SHORT, Locale.US)); // zzz
1036 // sb.append("GMT");
1038 sb.append(' ').append(date.getYear()); // yyyy
1039 return sb.toString();
1043 * Converts the given name to its 3-letter abbreviation (e.g.,
1044 * "monday" -> "Mon") and stored the abbreviation in the given
1045 * <code>StringBuilder</code>.
1047 private static final StringBuilder convertToAbbr(StringBuilder sb, String name) {
1048 sb.append(Character.toUpperCase(name.charAt(0)));
1049 sb.append(name.charAt(1)).append(name.charAt(2));
1054 * Creates a string representation of this <tt>Date</tt> object in an
1055 * implementation-dependent form. The intent is that the form should
1056 * be familiar to the user of the Java application, wherever it may
1057 * happen to be running. The intent is comparable to that of the
1058 * "<code>%c</code>" format supported by the <code>strftime()</code>
1059 * function of ISO C.
1061 * @return a string representation of this date, using the locale
1063 * @see java.text.DateFormat
1064 * @see java.util.Date#toString()
1065 * @see java.util.Date#toGMTString()
1066 * @deprecated As of JDK version 1.1,
1067 * replaced by <code>DateFormat.format(Date date)</code>.
1070 public String toLocaleString() {
1071 DateFormat formatter = DateFormat.getDateTimeInstance();
1072 return formatter.format(this);
1076 * Creates a string representation of this <tt>Date</tt> object of
1079 * d mon yyyy hh:mm:ss GMT</pre></blockquote>
1081 * <li><i>d</i> is the day of the month (<tt>1</tt> through <tt>31</tt>),
1082 * as one or two decimal digits.
1083 * <li><i>mon</i> is the month (<tt>Jan, Feb, Mar, Apr, May, Jun, Jul,
1084 * Aug, Sep, Oct, Nov, Dec</tt>).
1085 * <li><i>yyyy</i> is the year, as four decimal digits.
1086 * <li><i>hh</i> is the hour of the day (<tt>00</tt> through <tt>23</tt>),
1087 * as two decimal digits.
1088 * <li><i>mm</i> is the minute within the hour (<tt>00</tt> through
1089 * <tt>59</tt>), as two decimal digits.
1090 * <li><i>ss</i> is the second within the minute (<tt>00</tt> through
1091 * <tt>61</tt>), as two decimal digits.
1092 * <li><i>GMT</i> is exactly the ASCII letters "<tt>GMT</tt>" to indicate
1093 * Greenwich Mean Time.
1095 * The result does not depend on the local time zone.
1097 * @return a string representation of this date, using the Internet GMT
1099 * @see java.text.DateFormat
1100 * @see java.util.Date#toString()
1101 * @see java.util.Date#toLocaleString()
1102 * @deprecated As of JDK version 1.1,
1103 * replaced by <code>DateFormat.format(Date date)</code>, using a
1104 * GMT <code>TimeZone</code>.
1107 public String toGMTString() {
1108 // d MMM yyyy HH:mm:ss 'GMT'
1110 BaseCalendar cal = getCalendarSystem(t);
1111 StringBuilder sb = new StringBuilder(32);
1112 // BaseCalendar.Datum date =
1113 // (BaseCalendar.Datum) cal.getCalendarDate(getTime(), (TimeZone)null);
1114 // CalendarUtils.sprintf0d(sb, date.getDayOfMonth(), 1).append(' '); // d
1115 // convertToAbbr(sb, wtb[date.getMonth() - 1 + 2 + 7]).append(' '); // MMM
1116 // sb.append(date.getYear()).append(' '); // yyyy
1117 // CalendarUtils.sprintf0d(sb, date.getHours(), 2).append(':'); // HH
1118 // CalendarUtils.sprintf0d(sb, date.getMinutes(), 2).append(':'); // mm
1119 // CalendarUtils.sprintf0d(sb, date.getSeconds(), 2); // ss
1120 sb.append(" GMT"); // ' GMT'
1121 return sb.toString();
1125 * Returns the offset, measured in minutes, for the local time zone
1126 * relative to UTC that is appropriate for the time represented by
1127 * this <code>Date</code> object.
1129 * For example, in Massachusetts, five time zones west of Greenwich:
1131 * new Date(96, 1, 14).getTimezoneOffset() returns 300</pre></blockquote>
1132 * because on February 14, 1996, standard time (Eastern Standard Time)
1133 * is in use, which is offset five hours from UTC; but:
1135 * new Date(96, 5, 1).getTimezoneOffset() returns 240</pre></blockquote>
1136 * because on June 1, 1996, daylight saving time (Eastern Daylight Time)
1137 * is in use, which is offset only four hours from UTC.<p>
1138 * This method produces the same result as if it computed:
1140 * (this.getTime() - UTC(this.getYear(),
1144 * this.getMinutes(),
1145 * this.getSeconds())) / (60 * 1000)
1146 * </pre></blockquote>
1148 * @return the time-zone offset, in minutes, for the current time zone.
1149 * @see java.util.Calendar#ZONE_OFFSET
1150 * @see java.util.Calendar#DST_OFFSET
1151 * @see java.util.TimeZone#getDefault
1152 * @deprecated As of JDK version 1.1,
1153 * replaced by <code>-(Calendar.get(Calendar.ZONE_OFFSET) +
1154 * Calendar.get(Calendar.DST_OFFSET)) / (60 * 1000)</code>.
1157 public int getTimezoneOffset() {
1159 if (cdate == null) {
1160 TimeZone tz = TimeZone.getDefaultRef();
1161 zoneOffset = tz.getOffset(fastTime);
1164 zoneOffset = cdate.getZoneOffset();
1166 return -zoneOffset/60000; // convert to minutes
1169 private final BaseCalendar.Datum getCalendarDate() {
1170 if (cdate == null) {
1171 // BaseCalendar cal = getCalendarSystem(fastTime);
1172 // cdate = (BaseCalendar.Datum) cal.getCalendarDate(fastTime,
1173 // TimeZone.getDefaultRef());
1178 private final BaseCalendar.Datum normalize() {
1179 if (cdate == null) {
1180 // BaseCalendar cal = getCalendarSystem(fastTime);
1181 // cdate = (BaseCalendar.Datum) cal.getCalendarDate(fastTime,
1182 // TimeZone.getDefaultRef());
1186 // Normalize cdate with the TimeZone in cdate first. This is
1187 // required for the compatible behavior.
1188 if (!cdate.isNormalized()) {
1189 cdate = normalize(cdate);
1192 // If the default TimeZone has changed, then recalculate the
1193 // fields with the new TimeZone.
1194 TimeZone tz = TimeZone.getDefaultRef();
1195 if (tz != cdate.getZone()) {
1196 // cdate.setZone(tz);
1197 // CalendarSystem cal = getCalendarSystem(cdate);
1198 // cal.getCalendarDate(fastTime, cdate);
1203 // fastTime and the returned data are in sync upon return.
1204 private final BaseCalendar.Datum normalize(BaseCalendar.Datum date) {
1205 int y = date.getNormalizedYear();
1206 int m = date.getMonth();
1207 int d = date.getDayOfMonth();
1208 int hh = date.getHours();
1209 int mm = date.getMinutes();
1210 int ss = date.getSeconds();
1211 int ms = date.getMillis();
1212 TimeZone tz = date.getZone();
1214 // If the specified year can't be handled using a long value
1215 // in milliseconds, GregorianCalendar is used for full
1216 // compatibility with underflow and overflow. This is required
1217 // by some JCK tests. The limits are based max year values -
1218 // years that can be represented by max values of d, hh, mm,
1219 // ss and ms. Also, let GregorianCalendar handle the default
1220 // cutover year so that we don't need to worry about the
1222 // if (y == 1582 || y > 280000000 || y < -280000000) {
1223 // if (tz == null) {
1224 // tz = TimeZone.getTimeZone("GMT");
1226 // GregorianCalendar gc = new GregorianCalendar(tz);
1228 // gc.set(gc.MILLISECOND, ms);
1229 // gc.set(y, m-1, d, hh, mm, ss);
1230 // fastTime = gc.getTimeInMillis();
1231 // BaseCalendar cal = getCalendarSystem(fastTime);
1232 // date = (BaseCalendar.Datum) cal.getCalendarDate(fastTime, tz);
1236 BaseCalendar cal = getCalendarSystem(y);
1237 if (cal != getCalendarSystem(date)) {
1238 date = (BaseCalendar.Datum) cal.newCalendarDate(tz);
1239 date.setNormalizedDate(y, m, d).setTimeOfDay(hh, mm, ss, ms);
1241 // Perform the GregorianCalendar-style normalization.
1242 fastTime = cal.getTime(date);
1244 // In case the normalized date requires the other calendar
1245 // system, we need to recalculate it using the other one.
1246 BaseCalendar ncal = getCalendarSystem(fastTime);
1248 date = (BaseCalendar.Datum) ncal.newCalendarDate(tz);
1249 date.setNormalizedDate(y, m, d).setTimeOfDay(hh, mm, ss, ms);
1250 fastTime = ncal.getTime(date);
1256 * Returns the Gregorian or Julian calendar system to use with the
1257 * given date. Use Gregorian from October 15, 1582.
1259 * @param year normalized calendar year (not -1900)
1260 * @return the CalendarSystem to use for the specified date
1262 private static final BaseCalendar getCalendarSystem(int year) {
1266 return getJulianCalendar();
1269 private static final BaseCalendar getCalendarSystem(long utc) {
1270 // Quickly check if the time stamp given by `utc' is the Epoch
1271 // or later. If it's before 1970, we convert the cutover to
1272 // local time to compare.
1274 // || utc >= GregorianCalendar.DEFAULT_GREGORIAN_CUTOVER
1275 // - TimeZone.getDefaultRef().getOffset(utc)) {
1278 // return getJulianCalendar();
1281 private static final BaseCalendar getCalendarSystem(BaseCalendar.Datum cdate) {
1285 if (cdate.getEra() != null) {
1291 synchronized private static final BaseCalendar getJulianCalendar() {
1293 // jcal = (BaseCalendar) CalendarSystem.forName("julian");
1299 * Save the state of this object to a stream (i.e., serialize it).
1301 * @serialData The value returned by <code>getTime()</code>
1302 * is emitted (long). This represents the offset from
1303 * January 1, 1970, 00:00:00 GMT in milliseconds.
1305 private void writeObject(ObjectOutputStream s)
1308 s.writeLong(getTimeImpl());
1312 * Reconstitute this object from a stream (i.e., deserialize it).
1314 private void readObject(ObjectInputStream s)
1315 throws IOException, ClassNotFoundException
1317 fastTime = s.readLong();
1320 static final class BaseCalendar {
1321 Datum newCalendarDate(TimeZone t) {
1325 Datum getNthDayOfWeek(int a, int b, Datum c) {
1329 Datum getCalendarDate() {
1333 int getTime(Datum udate) {
1337 int getMonthLength(Datum cdate) {
1341 void getCalendarDate(long l, Datum cdate) {
1344 static class Datum implements Cloneable {
1345 public Datum clone() {
1349 Datum setNormalizedDate(int y, int i, int date) {
1353 void setTimeOfDay(int hrs, int min, int sec, int i) {
1360 void setDate(int year, int i, int mday) {
1363 void setNormalizedYear(int i) {
1370 int getNormalizedYear() {
1374 void setMonth(int i) {
1377 int getDayOfMonth() {
1381 void setDayOfMonth(int date) {
1384 int getDayOfWeek() {
1392 void setHours(int hours) {
1399 void setMinutes(int minutes) {
1406 void setSeconds(int seconds) {
1409 boolean isNormalized() {
1421 TimeZone getZone() {
1422 return TimeZone.NO_TIMEZONE;
1425 int getZoneOffset() {