jtulach@1334: /* jtulach@1334: * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved. jtulach@1334: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. jtulach@1334: * jtulach@1334: * This code is free software; you can redistribute it and/or modify it jtulach@1334: * under the terms of the GNU General Public License version 2 only, as jtulach@1334: * published by the Free Software Foundation. Oracle designates this jtulach@1334: * particular file as subject to the "Classpath" exception as provided jtulach@1334: * by Oracle in the LICENSE file that accompanied this code. jtulach@1334: * jtulach@1334: * This code is distributed in the hope that it will be useful, but WITHOUT jtulach@1334: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or jtulach@1334: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License jtulach@1334: * version 2 for more details (a copy is included in the LICENSE file that jtulach@1334: * accompanied this code). jtulach@1334: * jtulach@1334: * You should have received a copy of the GNU General Public License version jtulach@1334: * 2 along with this work; if not, write to the Free Software Foundation, jtulach@1334: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. jtulach@1334: * jtulach@1334: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA jtulach@1334: * or visit www.oracle.com if you need additional information or have any jtulach@1334: * questions. jtulach@1334: */ jtulach@1334: jtulach@1334: package java.util; jtulach@1334: jtulach@1334: import java.text.DateFormat; jtulach@1334: import java.io.IOException; jtulach@1334: import java.io.ObjectOutputStream; jtulach@1334: import java.io.ObjectInputStream; jtulach@1334: import java.lang.ref.SoftReference; jtulach@1334: import sun.util.calendar.BaseCalendar; jtulach@1334: import sun.util.calendar.CalendarDate; jtulach@1334: import sun.util.calendar.CalendarSystem; jtulach@1334: import sun.util.calendar.CalendarUtils; jtulach@1334: import sun.util.calendar.Era; jtulach@1334: import sun.util.calendar.Gregorian; jtulach@1334: import sun.util.calendar.ZoneInfo; jtulach@1334: jtulach@1334: /** jtulach@1334: * The class Date represents a specific instant jtulach@1334: * in time, with millisecond precision. jtulach@1334: *

jtulach@1334: * Prior to JDK 1.1, the class Date had two additional jtulach@1334: * functions. It allowed the interpretation of dates as year, month, day, hour, jtulach@1334: * minute, and second values. It also allowed the formatting and parsing jtulach@1334: * of date strings. Unfortunately, the API for these functions was not jtulach@1334: * amenable to internationalization. As of JDK 1.1, the jtulach@1334: * Calendar class should be used to convert between dates and time jtulach@1334: * fields and the DateFormat class should be used to format and jtulach@1334: * parse date strings. jtulach@1334: * The corresponding methods in Date are deprecated. jtulach@1334: *

jtulach@1334: * Although the Date class is intended to reflect jtulach@1334: * coordinated universal time (UTC), it may not do so exactly, jtulach@1334: * depending on the host environment of the Java Virtual Machine. jtulach@1334: * Nearly all modern operating systems assume that 1 day = jtulach@1334: * 24 × 60 × 60 = 86400 seconds jtulach@1334: * in all cases. In UTC, however, about once every year or two there jtulach@1334: * is an extra second, called a "leap second." The leap jtulach@1334: * second is always added as the last second of the day, and always jtulach@1334: * on December 31 or June 30. For example, the last minute of the jtulach@1334: * year 1995 was 61 seconds long, thanks to an added leap second. jtulach@1334: * Most computer clocks are not accurate enough to be able to reflect jtulach@1334: * the leap-second distinction. jtulach@1334: *

jtulach@1334: * Some computer standards are defined in terms of Greenwich mean jtulach@1334: * time (GMT), which is equivalent to universal time (UT). GMT is jtulach@1334: * the "civil" name for the standard; UT is the jtulach@1334: * "scientific" name for the same standard. The jtulach@1334: * distinction between UTC and UT is that UTC is based on an atomic jtulach@1334: * clock and UT is based on astronomical observations, which for all jtulach@1334: * practical purposes is an invisibly fine hair to split. Because the jtulach@1334: * earth's rotation is not uniform (it slows down and speeds up jtulach@1334: * in complicated ways), UT does not always flow uniformly. Leap jtulach@1334: * seconds are introduced as needed into UTC so as to keep UTC within jtulach@1334: * 0.9 seconds of UT1, which is a version of UT with certain jtulach@1334: * corrections applied. There are other time and date systems as jtulach@1334: * well; for example, the time scale used by the satellite-based jtulach@1334: * global positioning system (GPS) is synchronized to UTC but is jtulach@1334: * not adjusted for leap seconds. An interesting source of jtulach@1334: * further information is the U.S. Naval Observatory, particularly jtulach@1334: * the Directorate of Time at: jtulach@1334: *

jtulach@1334:  *     http://tycho.usno.navy.mil
jtulach@1334:  * 
jtulach@1334: *

jtulach@1334: * and their definitions of "Systems of Time" at: jtulach@1334: *

jtulach@1334:  *     http://tycho.usno.navy.mil/systime.html
jtulach@1334:  * 
jtulach@1334: *

jtulach@1334: * In all methods of class Date that accept or return jtulach@1334: * year, month, date, hours, minutes, and seconds values, the jtulach@1334: * following representations are used: jtulach@1334: *

jtulach@1334: *

jtulach@1334: * In all cases, arguments given to methods for these purposes need jtulach@1334: * not fall within the indicated ranges; for example, a date may be jtulach@1334: * specified as January 32 and is interpreted as meaning February 1. jtulach@1334: * jtulach@1334: * @author James Gosling jtulach@1334: * @author Arthur van Hoff jtulach@1334: * @author Alan Liu jtulach@1334: * @see java.text.DateFormat jtulach@1334: * @see java.util.Calendar jtulach@1334: * @see java.util.TimeZone jtulach@1334: * @since JDK1.0 jtulach@1334: */ jtulach@1334: public class Date jtulach@1334: implements java.io.Serializable, Cloneable, Comparable jtulach@1334: { jtulach@1334: private static final BaseCalendar gcal = jtulach@1334: CalendarSystem.getGregorianCalendar(); jtulach@1334: private static BaseCalendar jcal; jtulach@1334: jtulach@1334: private transient long fastTime; jtulach@1334: jtulach@1334: /* jtulach@1334: * If cdate is null, then fastTime indicates the time in millis. jtulach@1334: * If cdate.isNormalized() is true, then fastTime and cdate are in jtulach@1334: * synch. Otherwise, fastTime is ignored, and cdate indicates the jtulach@1334: * time. jtulach@1334: */ jtulach@1334: private transient BaseCalendar.Date cdate; jtulach@1334: jtulach@1334: // Initialized just before the value is used. See parse(). jtulach@1334: private static int defaultCenturyStart; jtulach@1334: jtulach@1334: /* use serialVersionUID from modified java.util.Date for jtulach@1334: * interoperability with JDK1.1. The Date was modified to write jtulach@1334: * and read only the UTC time. jtulach@1334: */ jtulach@1334: private static final long serialVersionUID = 7523967970034938905L; jtulach@1334: jtulach@1334: /** jtulach@1334: * Allocates a Date object and initializes it so that jtulach@1334: * it represents the time at which it was allocated, measured to the jtulach@1334: * nearest millisecond. jtulach@1334: * jtulach@1334: * @see java.lang.System#currentTimeMillis() jtulach@1334: */ jtulach@1334: public Date() { jtulach@1334: this(System.currentTimeMillis()); jtulach@1334: } jtulach@1334: jtulach@1334: /** jtulach@1334: * Allocates a Date object and initializes it to jtulach@1334: * represent the specified number of milliseconds since the jtulach@1334: * standard base time known as "the epoch", namely January 1, jtulach@1334: * 1970, 00:00:00 GMT. jtulach@1334: * jtulach@1334: * @param date the milliseconds since January 1, 1970, 00:00:00 GMT. jtulach@1334: * @see java.lang.System#currentTimeMillis() jtulach@1334: */ jtulach@1334: public Date(long date) { jtulach@1334: fastTime = date; jtulach@1334: } jtulach@1334: jtulach@1334: /** jtulach@1334: * Allocates a Date object and initializes it so that jtulach@1334: * it represents midnight, local time, at the beginning of the day jtulach@1334: * specified by the year, month, and jtulach@1334: * date arguments. jtulach@1334: * jtulach@1334: * @param year the year minus 1900. jtulach@1334: * @param month the month between 0-11. jtulach@1334: * @param date the day of the month between 1-31. jtulach@1334: * @see java.util.Calendar jtulach@1334: * @deprecated As of JDK version 1.1, jtulach@1334: * replaced by Calendar.set(year + 1900, month, date) jtulach@1334: * or GregorianCalendar(year + 1900, month, date). jtulach@1334: */ jtulach@1334: @Deprecated jtulach@1334: public Date(int year, int month, int date) { jtulach@1334: this(year, month, date, 0, 0, 0); jtulach@1334: } jtulach@1334: jtulach@1334: /** jtulach@1334: * Allocates a Date object and initializes it so that jtulach@1334: * it represents the instant at the start of the minute specified by jtulach@1334: * the year, month, date, jtulach@1334: * hrs, and min arguments, in the local jtulach@1334: * time zone. jtulach@1334: * jtulach@1334: * @param year the year minus 1900. jtulach@1334: * @param month the month between 0-11. jtulach@1334: * @param date the day of the month between 1-31. jtulach@1334: * @param hrs the hours between 0-23. jtulach@1334: * @param min the minutes between 0-59. jtulach@1334: * @see java.util.Calendar jtulach@1334: * @deprecated As of JDK version 1.1, jtulach@1334: * replaced by Calendar.set(year + 1900, month, date, jtulach@1334: * hrs, min) or GregorianCalendar(year + 1900, jtulach@1334: * month, date, hrs, min). jtulach@1334: */ jtulach@1334: @Deprecated jtulach@1334: public Date(int year, int month, int date, int hrs, int min) { jtulach@1334: this(year, month, date, hrs, min, 0); jtulach@1334: } jtulach@1334: jtulach@1334: /** jtulach@1334: * Allocates a Date object and initializes it so that jtulach@1334: * it represents the instant at the start of the second specified jtulach@1334: * by the year, month, date, jtulach@1334: * hrs, min, and sec arguments, jtulach@1334: * in the local time zone. jtulach@1334: * jtulach@1334: * @param year the year minus 1900. jtulach@1334: * @param month the month between 0-11. jtulach@1334: * @param date the day of the month between 1-31. jtulach@1334: * @param hrs the hours between 0-23. jtulach@1334: * @param min the minutes between 0-59. jtulach@1334: * @param sec the seconds between 0-59. jtulach@1334: * @see java.util.Calendar jtulach@1334: * @deprecated As of JDK version 1.1, jtulach@1334: * replaced by Calendar.set(year + 1900, month, date, jtulach@1334: * hrs, min, sec) or GregorianCalendar(year + 1900, jtulach@1334: * month, date, hrs, min, sec). jtulach@1334: */ jtulach@1334: @Deprecated jtulach@1334: public Date(int year, int month, int date, int hrs, int min, int sec) { jtulach@1334: int y = year + 1900; jtulach@1334: // month is 0-based. So we have to normalize month to support Long.MAX_VALUE. jtulach@1334: if (month >= 12) { jtulach@1334: y += month / 12; jtulach@1334: month %= 12; jtulach@1334: } else if (month < 0) { jtulach@1334: y += CalendarUtils.floorDivide(month, 12); jtulach@1334: month = CalendarUtils.mod(month, 12); jtulach@1334: } jtulach@1334: BaseCalendar cal = getCalendarSystem(y); jtulach@1334: cdate = (BaseCalendar.Date) cal.newCalendarDate(TimeZone.getDefaultRef()); jtulach@1334: cdate.setNormalizedDate(y, month + 1, date).setTimeOfDay(hrs, min, sec, 0); jtulach@1334: getTimeImpl(); jtulach@1334: cdate = null; jtulach@1334: } jtulach@1334: jtulach@1334: /** jtulach@1334: * Allocates a Date object and initializes it so that jtulach@1334: * it represents the date and time indicated by the string jtulach@1334: * s, which is interpreted as if by the jtulach@1334: * {@link Date#parse} method. jtulach@1334: * jtulach@1334: * @param s a string representation of the date. jtulach@1334: * @see java.text.DateFormat jtulach@1334: * @see java.util.Date#parse(java.lang.String) jtulach@1334: * @deprecated As of JDK version 1.1, jtulach@1334: * replaced by DateFormat.parse(String s). jtulach@1334: */ jtulach@1334: @Deprecated jtulach@1334: public Date(String s) { jtulach@1334: this(parse(s)); jtulach@1334: } jtulach@1334: jtulach@1334: /** jtulach@1334: * Return a copy of this object. jtulach@1334: */ jtulach@1334: public Object clone() { jtulach@1334: Date d = null; jtulach@1334: try { jtulach@1334: d = (Date)super.clone(); jtulach@1334: if (cdate != null) { jtulach@1334: d.cdate = (BaseCalendar.Date) cdate.clone(); jtulach@1334: } jtulach@1334: } catch (CloneNotSupportedException e) {} // Won't happen jtulach@1334: return d; jtulach@1334: } jtulach@1334: jtulach@1334: /** jtulach@1334: * Determines the date and time based on the arguments. The jtulach@1334: * arguments are interpreted as a year, month, day of the month, jtulach@1334: * hour of the day, minute within the hour, and second within the jtulach@1334: * minute, exactly as for the Date constructor with six jtulach@1334: * arguments, except that the arguments are interpreted relative jtulach@1334: * to UTC rather than to the local time zone. The time indicated is jtulach@1334: * returned represented as the distance, measured in milliseconds, jtulach@1334: * of that time from the epoch (00:00:00 GMT on January 1, 1970). jtulach@1334: * jtulach@1334: * @param year the year minus 1900. jtulach@1334: * @param month the month between 0-11. jtulach@1334: * @param date the day of the month between 1-31. jtulach@1334: * @param hrs the hours between 0-23. jtulach@1334: * @param min the minutes between 0-59. jtulach@1334: * @param sec the seconds between 0-59. jtulach@1334: * @return the number of milliseconds since January 1, 1970, 00:00:00 GMT for jtulach@1334: * the date and time specified by the arguments. jtulach@1334: * @see java.util.Calendar jtulach@1334: * @deprecated As of JDK version 1.1, jtulach@1334: * replaced by Calendar.set(year + 1900, month, date, jtulach@1334: * hrs, min, sec) or GregorianCalendar(year + 1900, jtulach@1334: * month, date, hrs, min, sec), using a UTC jtulach@1334: * TimeZone, followed by Calendar.getTime().getTime(). jtulach@1334: */ jtulach@1334: @Deprecated jtulach@1334: public static long UTC(int year, int month, int date, jtulach@1334: int hrs, int min, int sec) { jtulach@1334: int y = year + 1900; jtulach@1334: // month is 0-based. So we have to normalize month to support Long.MAX_VALUE. jtulach@1334: if (month >= 12) { jtulach@1334: y += month / 12; jtulach@1334: month %= 12; jtulach@1334: } else if (month < 0) { jtulach@1334: y += CalendarUtils.floorDivide(month, 12); jtulach@1334: month = CalendarUtils.mod(month, 12); jtulach@1334: } jtulach@1334: int m = month + 1; jtulach@1334: BaseCalendar cal = getCalendarSystem(y); jtulach@1334: BaseCalendar.Date udate = (BaseCalendar.Date) cal.newCalendarDate(null); jtulach@1334: udate.setNormalizedDate(y, m, date).setTimeOfDay(hrs, min, sec, 0); jtulach@1334: jtulach@1334: // Use a Date instance to perform normalization. Its fastTime jtulach@1334: // is the UTC value after the normalization. jtulach@1334: Date d = new Date(0); jtulach@1334: d.normalize(udate); jtulach@1334: return d.fastTime; jtulach@1334: } jtulach@1334: jtulach@1334: /** jtulach@1334: * Attempts to interpret the string s as a representation jtulach@1334: * of a date and time. If the attempt is successful, the time jtulach@1334: * indicated is returned represented as the distance, measured in jtulach@1334: * milliseconds, of that time from the epoch (00:00:00 GMT on jtulach@1334: * January 1, 1970). If the attempt fails, an jtulach@1334: * IllegalArgumentException is thrown. jtulach@1334: *

jtulach@1334: * It accepts many syntaxes; in particular, it recognizes the IETF jtulach@1334: * standard date syntax: "Sat, 12 Aug 1995 13:30:00 GMT". It also jtulach@1334: * understands the continental U.S. time-zone abbreviations, but for jtulach@1334: * general use, a time-zone offset should be used: "Sat, 12 Aug 1995 jtulach@1334: * 13:30:00 GMT+0430" (4 hours, 30 minutes west of the Greenwich jtulach@1334: * meridian). If no time zone is specified, the local time zone is jtulach@1334: * assumed. GMT and UTC are considered equivalent. jtulach@1334: *

jtulach@1334: * The string s is processed from left to right, looking for jtulach@1334: * data of interest. Any material in s that is within the jtulach@1334: * ASCII parenthesis characters ( and ) is ignored. jtulach@1334: * Parentheses may be nested. Otherwise, the only characters permitted jtulach@1334: * within s are these ASCII characters: jtulach@1334: *

jtulach@1334:      * abcdefghijklmnopqrstuvwxyz
jtulach@1334:      * ABCDEFGHIJKLMNOPQRSTUVWXYZ
jtulach@1334:      * 0123456789,+-:/
jtulach@1334: * and whitespace characters.

jtulach@1334: * A consecutive sequence of decimal digits is treated as a decimal jtulach@1334: * number:

jtulach@1334: * A consecutive sequence of letters is regarded as a word and treated jtulach@1334: * as follows:

jtulach@1334: * Once the entire string s has been scanned, it is converted to a time jtulach@1334: * result in one of two ways. If a time zone or time-zone offset has been jtulach@1334: * recognized, then the year, month, day of month, hour, minute, and jtulach@1334: * second are interpreted in UTC and then the time-zone offset is jtulach@1334: * applied. Otherwise, the year, month, day of month, hour, minute, and jtulach@1334: * second are interpreted in the local time zone. jtulach@1334: * jtulach@1334: * @param s a string to be parsed as a date. jtulach@1334: * @return the number of milliseconds since January 1, 1970, 00:00:00 GMT jtulach@1334: * represented by the string argument. jtulach@1334: * @see java.text.DateFormat jtulach@1334: * @deprecated As of JDK version 1.1, jtulach@1334: * replaced by DateFormat.parse(String s). jtulach@1334: */ jtulach@1334: @Deprecated jtulach@1334: public static long parse(String s) { jtulach@1334: int year = Integer.MIN_VALUE; jtulach@1334: int mon = -1; jtulach@1334: int mday = -1; jtulach@1334: int hour = -1; jtulach@1334: int min = -1; jtulach@1334: int sec = -1; jtulach@1334: int millis = -1; jtulach@1334: int c = -1; jtulach@1334: int i = 0; jtulach@1334: int n = -1; jtulach@1334: int wst = -1; jtulach@1334: int tzoffset = -1; jtulach@1334: int prevc = 0; jtulach@1334: syntax: jtulach@1334: { jtulach@1334: if (s == null) jtulach@1334: break syntax; jtulach@1334: int limit = s.length(); jtulach@1334: while (i < limit) { jtulach@1334: c = s.charAt(i); jtulach@1334: i++; jtulach@1334: if (c <= ' ' || c == ',') jtulach@1334: continue; jtulach@1334: if (c == '(') { // skip comments jtulach@1334: int depth = 1; jtulach@1334: while (i < limit) { jtulach@1334: c = s.charAt(i); jtulach@1334: i++; jtulach@1334: if (c == '(') depth++; jtulach@1334: else if (c == ')') jtulach@1334: if (--depth <= 0) jtulach@1334: break; jtulach@1334: } jtulach@1334: continue; jtulach@1334: } jtulach@1334: if ('0' <= c && c <= '9') { jtulach@1334: n = c - '0'; jtulach@1334: while (i < limit && '0' <= (c = s.charAt(i)) && c <= '9') { jtulach@1334: n = n * 10 + c - '0'; jtulach@1334: i++; jtulach@1334: } jtulach@1334: if (prevc == '+' || prevc == '-' && year != Integer.MIN_VALUE) { jtulach@1334: // timezone offset jtulach@1334: if (n < 24) jtulach@1334: n = n * 60; // EG. "GMT-3" jtulach@1334: else jtulach@1334: n = n % 100 + n / 100 * 60; // eg "GMT-0430" jtulach@1334: if (prevc == '+') // plus means east of GMT jtulach@1334: n = -n; jtulach@1334: if (tzoffset != 0 && tzoffset != -1) jtulach@1334: break syntax; jtulach@1334: tzoffset = n; jtulach@1334: } else if (n >= 70) jtulach@1334: if (year != Integer.MIN_VALUE) jtulach@1334: break syntax; jtulach@1334: else if (c <= ' ' || c == ',' || c == '/' || i >= limit) jtulach@1334: // year = n < 1900 ? n : n - 1900; jtulach@1334: year = n; jtulach@1334: else jtulach@1334: break syntax; jtulach@1334: else if (c == ':') jtulach@1334: if (hour < 0) jtulach@1334: hour = (byte) n; jtulach@1334: else if (min < 0) jtulach@1334: min = (byte) n; jtulach@1334: else jtulach@1334: break syntax; jtulach@1334: else if (c == '/') jtulach@1334: if (mon < 0) jtulach@1334: mon = (byte) (n - 1); jtulach@1334: else if (mday < 0) jtulach@1334: mday = (byte) n; jtulach@1334: else jtulach@1334: break syntax; jtulach@1334: else if (i < limit && c != ',' && c > ' ' && c != '-') jtulach@1334: break syntax; jtulach@1334: else if (hour >= 0 && min < 0) jtulach@1334: min = (byte) n; jtulach@1334: else if (min >= 0 && sec < 0) jtulach@1334: sec = (byte) n; jtulach@1334: else if (mday < 0) jtulach@1334: mday = (byte) n; jtulach@1334: // Handle two-digit years < 70 (70-99 handled above). jtulach@1334: else if (year == Integer.MIN_VALUE && mon >= 0 && mday >= 0) jtulach@1334: year = n; jtulach@1334: else jtulach@1334: break syntax; jtulach@1334: prevc = 0; jtulach@1334: } else if (c == '/' || c == ':' || c == '+' || c == '-') jtulach@1334: prevc = c; jtulach@1334: else { jtulach@1334: int st = i - 1; jtulach@1334: while (i < limit) { jtulach@1334: c = s.charAt(i); jtulach@1334: if (!('A' <= c && c <= 'Z' || 'a' <= c && c <= 'z')) jtulach@1334: break; jtulach@1334: i++; jtulach@1334: } jtulach@1334: if (i <= st + 1) jtulach@1334: break syntax; jtulach@1334: int k; jtulach@1334: for (k = wtb.length; --k >= 0;) jtulach@1334: if (wtb[k].regionMatches(true, 0, s, st, i - st)) { jtulach@1334: int action = ttb[k]; jtulach@1334: if (action != 0) { jtulach@1334: if (action == 1) { // pm jtulach@1334: if (hour > 12 || hour < 1) jtulach@1334: break syntax; jtulach@1334: else if (hour < 12) jtulach@1334: hour += 12; jtulach@1334: } else if (action == 14) { // am jtulach@1334: if (hour > 12 || hour < 1) jtulach@1334: break syntax; jtulach@1334: else if (hour == 12) jtulach@1334: hour = 0; jtulach@1334: } else if (action <= 13) { // month! jtulach@1334: if (mon < 0) jtulach@1334: mon = (byte) (action - 2); jtulach@1334: else jtulach@1334: break syntax; jtulach@1334: } else { jtulach@1334: tzoffset = action - 10000; jtulach@1334: } jtulach@1334: } jtulach@1334: break; jtulach@1334: } jtulach@1334: if (k < 0) jtulach@1334: break syntax; jtulach@1334: prevc = 0; jtulach@1334: } jtulach@1334: } jtulach@1334: if (year == Integer.MIN_VALUE || mon < 0 || mday < 0) jtulach@1334: break syntax; jtulach@1334: // Parse 2-digit years within the correct default century. jtulach@1334: if (year < 100) { jtulach@1334: synchronized (Date.class) { jtulach@1334: if (defaultCenturyStart == 0) { jtulach@1334: defaultCenturyStart = gcal.getCalendarDate().getYear() - 80; jtulach@1334: } jtulach@1334: } jtulach@1334: year += (defaultCenturyStart / 100) * 100; jtulach@1334: if (year < defaultCenturyStart) year += 100; jtulach@1334: } jtulach@1334: if (sec < 0) jtulach@1334: sec = 0; jtulach@1334: if (min < 0) jtulach@1334: min = 0; jtulach@1334: if (hour < 0) jtulach@1334: hour = 0; jtulach@1334: BaseCalendar cal = getCalendarSystem(year); jtulach@1334: if (tzoffset == -1) { // no time zone specified, have to use local jtulach@1334: BaseCalendar.Date ldate = (BaseCalendar.Date) cal.newCalendarDate(TimeZone.getDefaultRef()); jtulach@1334: ldate.setDate(year, mon + 1, mday); jtulach@1334: ldate.setTimeOfDay(hour, min, sec, 0); jtulach@1334: return cal.getTime(ldate); jtulach@1334: } jtulach@1334: BaseCalendar.Date udate = (BaseCalendar.Date) cal.newCalendarDate(null); // no time zone jtulach@1334: udate.setDate(year, mon + 1, mday); jtulach@1334: udate.setTimeOfDay(hour, min, sec, 0); jtulach@1334: return cal.getTime(udate) + tzoffset * (60 * 1000); jtulach@1334: } jtulach@1334: // syntax error jtulach@1334: throw new IllegalArgumentException(); jtulach@1334: } jtulach@1334: private final static String wtb[] = { jtulach@1334: "am", "pm", jtulach@1334: "monday", "tuesday", "wednesday", "thursday", "friday", jtulach@1334: "saturday", "sunday", jtulach@1334: "january", "february", "march", "april", "may", "june", jtulach@1334: "july", "august", "september", "october", "november", "december", jtulach@1334: "gmt", "ut", "utc", "est", "edt", "cst", "cdt", jtulach@1334: "mst", "mdt", "pst", "pdt" jtulach@1334: }; jtulach@1334: private final static int ttb[] = { jtulach@1334: 14, 1, 0, 0, 0, 0, 0, 0, 0, jtulach@1334: 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, jtulach@1334: 10000 + 0, 10000 + 0, 10000 + 0, // GMT/UT/UTC jtulach@1334: 10000 + 5 * 60, 10000 + 4 * 60, // EST/EDT jtulach@1334: 10000 + 6 * 60, 10000 + 5 * 60, // CST/CDT jtulach@1334: 10000 + 7 * 60, 10000 + 6 * 60, // MST/MDT jtulach@1334: 10000 + 8 * 60, 10000 + 7 * 60 // PST/PDT jtulach@1334: }; jtulach@1334: jtulach@1334: /** jtulach@1334: * Returns a value that is the result of subtracting 1900 from the jtulach@1334: * year that contains or begins with the instant in time represented jtulach@1334: * by this Date object, as interpreted in the local jtulach@1334: * time zone. jtulach@1334: * jtulach@1334: * @return the year represented by this date, minus 1900. jtulach@1334: * @see java.util.Calendar jtulach@1334: * @deprecated As of JDK version 1.1, jtulach@1334: * replaced by Calendar.get(Calendar.YEAR) - 1900. jtulach@1334: */ jtulach@1334: @Deprecated jtulach@1334: public int getYear() { jtulach@1334: return normalize().getYear() - 1900; jtulach@1334: } jtulach@1334: jtulach@1334: /** jtulach@1334: * Sets the year of this Date object to be the specified jtulach@1334: * value plus 1900. This Date object is modified so jtulach@1334: * that it represents a point in time within the specified year, jtulach@1334: * with the month, date, hour, minute, and second the same as jtulach@1334: * before, as interpreted in the local time zone. (Of course, if jtulach@1334: * the date was February 29, for example, and the year is set to a jtulach@1334: * non-leap year, then the new date will be treated as if it were jtulach@1334: * on March 1.) jtulach@1334: * jtulach@1334: * @param year the year value. jtulach@1334: * @see java.util.Calendar jtulach@1334: * @deprecated As of JDK version 1.1, jtulach@1334: * replaced by Calendar.set(Calendar.YEAR, year + 1900). jtulach@1334: */ jtulach@1334: @Deprecated jtulach@1334: public void setYear(int year) { jtulach@1334: getCalendarDate().setNormalizedYear(year + 1900); jtulach@1334: } jtulach@1334: jtulach@1334: /** jtulach@1334: * Returns a number representing the month that contains or begins jtulach@1334: * with the instant in time represented by this Date object. jtulach@1334: * The value returned is between 0 and 11, jtulach@1334: * with the value 0 representing January. jtulach@1334: * jtulach@1334: * @return the month represented by this date. jtulach@1334: * @see java.util.Calendar jtulach@1334: * @deprecated As of JDK version 1.1, jtulach@1334: * replaced by Calendar.get(Calendar.MONTH). jtulach@1334: */ jtulach@1334: @Deprecated jtulach@1334: public int getMonth() { jtulach@1334: return normalize().getMonth() - 1; // adjust 1-based to 0-based jtulach@1334: } jtulach@1334: jtulach@1334: /** jtulach@1334: * Sets the month of this date to the specified value. This jtulach@1334: * Date object is modified so that it represents a point jtulach@1334: * in time within the specified month, with the year, date, hour, jtulach@1334: * minute, and second the same as before, as interpreted in the jtulach@1334: * local time zone. If the date was October 31, for example, and jtulach@1334: * the month is set to June, then the new date will be treated as jtulach@1334: * if it were on July 1, because June has only 30 days. jtulach@1334: * jtulach@1334: * @param month the month value between 0-11. jtulach@1334: * @see java.util.Calendar jtulach@1334: * @deprecated As of JDK version 1.1, jtulach@1334: * replaced by Calendar.set(Calendar.MONTH, int month). jtulach@1334: */ jtulach@1334: @Deprecated jtulach@1334: public void setMonth(int month) { jtulach@1334: int y = 0; jtulach@1334: if (month >= 12) { jtulach@1334: y = month / 12; jtulach@1334: month %= 12; jtulach@1334: } else if (month < 0) { jtulach@1334: y = CalendarUtils.floorDivide(month, 12); jtulach@1334: month = CalendarUtils.mod(month, 12); jtulach@1334: } jtulach@1334: BaseCalendar.Date d = getCalendarDate(); jtulach@1334: if (y != 0) { jtulach@1334: d.setNormalizedYear(d.getNormalizedYear() + y); jtulach@1334: } jtulach@1334: d.setMonth(month + 1); // adjust 0-based to 1-based month numbering jtulach@1334: } jtulach@1334: jtulach@1334: /** jtulach@1334: * Returns the day of the month represented by this Date object. jtulach@1334: * The value returned is between 1 and 31 jtulach@1334: * representing the day of the month that contains or begins with the jtulach@1334: * instant in time represented by this Date object, as jtulach@1334: * interpreted in the local time zone. jtulach@1334: * jtulach@1334: * @return the day of the month represented by this date. jtulach@1334: * @see java.util.Calendar jtulach@1334: * @deprecated As of JDK version 1.1, jtulach@1334: * replaced by Calendar.get(Calendar.DAY_OF_MONTH). jtulach@1334: * @deprecated jtulach@1334: */ jtulach@1334: @Deprecated jtulach@1334: public int getDate() { jtulach@1334: return normalize().getDayOfMonth(); jtulach@1334: } jtulach@1334: jtulach@1334: /** jtulach@1334: * Sets the day of the month of this Date object to the jtulach@1334: * specified value. This Date object is modified so that jtulach@1334: * it represents a point in time within the specified day of the jtulach@1334: * month, with the year, month, hour, minute, and second the same jtulach@1334: * as before, as interpreted in the local time zone. If the date jtulach@1334: * was April 30, for example, and the date is set to 31, then it jtulach@1334: * will be treated as if it were on May 1, because April has only jtulach@1334: * 30 days. jtulach@1334: * jtulach@1334: * @param date the day of the month value between 1-31. jtulach@1334: * @see java.util.Calendar jtulach@1334: * @deprecated As of JDK version 1.1, jtulach@1334: * replaced by Calendar.set(Calendar.DAY_OF_MONTH, int date). jtulach@1334: */ jtulach@1334: @Deprecated jtulach@1334: public void setDate(int date) { jtulach@1334: getCalendarDate().setDayOfMonth(date); jtulach@1334: } jtulach@1334: jtulach@1334: /** jtulach@1334: * Returns the day of the week represented by this date. The jtulach@1334: * returned value (0 = Sunday, 1 = Monday, jtulach@1334: * 2 = Tuesday, 3 = Wednesday, 4 = jtulach@1334: * Thursday, 5 = Friday, 6 = Saturday) jtulach@1334: * represents the day of the week that contains or begins with jtulach@1334: * the instant in time represented by this Date object, jtulach@1334: * as interpreted in the local time zone. jtulach@1334: * jtulach@1334: * @return the day of the week represented by this date. jtulach@1334: * @see java.util.Calendar jtulach@1334: * @deprecated As of JDK version 1.1, jtulach@1334: * replaced by Calendar.get(Calendar.DAY_OF_WEEK). jtulach@1334: */ jtulach@1334: @Deprecated jtulach@1334: public int getDay() { jtulach@1334: return normalize().getDayOfWeek() - gcal.SUNDAY; jtulach@1334: } jtulach@1334: jtulach@1334: /** jtulach@1334: * Returns the hour represented by this Date object. The jtulach@1334: * returned value is a number (0 through 23) jtulach@1334: * representing the hour within the day that contains or begins jtulach@1334: * with the instant in time represented by this Date jtulach@1334: * object, as interpreted in the local time zone. jtulach@1334: * jtulach@1334: * @return the hour represented by this date. jtulach@1334: * @see java.util.Calendar jtulach@1334: * @deprecated As of JDK version 1.1, jtulach@1334: * replaced by Calendar.get(Calendar.HOUR_OF_DAY). jtulach@1334: */ jtulach@1334: @Deprecated jtulach@1334: public int getHours() { jtulach@1334: return normalize().getHours(); jtulach@1334: } jtulach@1334: jtulach@1334: /** jtulach@1334: * Sets the hour of this Date object to the specified value. jtulach@1334: * This Date object is modified so that it represents a point jtulach@1334: * in time within the specified hour of the day, with the year, month, jtulach@1334: * date, minute, and second the same as before, as interpreted in the jtulach@1334: * local time zone. jtulach@1334: * jtulach@1334: * @param hours the hour value. jtulach@1334: * @see java.util.Calendar jtulach@1334: * @deprecated As of JDK version 1.1, jtulach@1334: * replaced by Calendar.set(Calendar.HOUR_OF_DAY, int hours). jtulach@1334: */ jtulach@1334: @Deprecated jtulach@1334: public void setHours(int hours) { jtulach@1334: getCalendarDate().setHours(hours); jtulach@1334: } jtulach@1334: jtulach@1334: /** jtulach@1334: * Returns the number of minutes past the hour represented by this date, jtulach@1334: * as interpreted in the local time zone. jtulach@1334: * The value returned is between 0 and 59. jtulach@1334: * jtulach@1334: * @return the number of minutes past the hour represented by this date. jtulach@1334: * @see java.util.Calendar jtulach@1334: * @deprecated As of JDK version 1.1, jtulach@1334: * replaced by Calendar.get(Calendar.MINUTE). jtulach@1334: */ jtulach@1334: @Deprecated jtulach@1334: public int getMinutes() { jtulach@1334: return normalize().getMinutes(); jtulach@1334: } jtulach@1334: jtulach@1334: /** jtulach@1334: * Sets the minutes of this Date object to the specified value. jtulach@1334: * This Date object is modified so that it represents a point jtulach@1334: * in time within the specified minute of the hour, with the year, month, jtulach@1334: * date, hour, and second the same as before, as interpreted in the jtulach@1334: * local time zone. jtulach@1334: * jtulach@1334: * @param minutes the value of the minutes. jtulach@1334: * @see java.util.Calendar jtulach@1334: * @deprecated As of JDK version 1.1, jtulach@1334: * replaced by Calendar.set(Calendar.MINUTE, int minutes). jtulach@1334: */ jtulach@1334: @Deprecated jtulach@1334: public void setMinutes(int minutes) { jtulach@1334: getCalendarDate().setMinutes(minutes); jtulach@1334: } jtulach@1334: jtulach@1334: /** jtulach@1334: * Returns the number of seconds past the minute represented by this date. jtulach@1334: * The value returned is between 0 and 61. The jtulach@1334: * values 60 and 61 can only occur on those jtulach@1334: * Java Virtual Machines that take leap seconds into account. jtulach@1334: * jtulach@1334: * @return the number of seconds past the minute represented by this date. jtulach@1334: * @see java.util.Calendar jtulach@1334: * @deprecated As of JDK version 1.1, jtulach@1334: * replaced by Calendar.get(Calendar.SECOND). jtulach@1334: */ jtulach@1334: @Deprecated jtulach@1334: public int getSeconds() { jtulach@1334: return normalize().getSeconds(); jtulach@1334: } jtulach@1334: jtulach@1334: /** jtulach@1334: * Sets the seconds of this Date to the specified value. jtulach@1334: * This Date object is modified so that it represents a jtulach@1334: * point in time within the specified second of the minute, with jtulach@1334: * the year, month, date, hour, and minute the same as before, as jtulach@1334: * interpreted in the local time zone. jtulach@1334: * jtulach@1334: * @param seconds the seconds value. jtulach@1334: * @see java.util.Calendar jtulach@1334: * @deprecated As of JDK version 1.1, jtulach@1334: * replaced by Calendar.set(Calendar.SECOND, int seconds). jtulach@1334: */ jtulach@1334: @Deprecated jtulach@1334: public void setSeconds(int seconds) { jtulach@1334: getCalendarDate().setSeconds(seconds); jtulach@1334: } jtulach@1334: jtulach@1334: /** jtulach@1334: * Returns the number of milliseconds since January 1, 1970, 00:00:00 GMT jtulach@1334: * represented by this Date object. jtulach@1334: * jtulach@1334: * @return the number of milliseconds since January 1, 1970, 00:00:00 GMT jtulach@1334: * represented by this date. jtulach@1334: */ jtulach@1334: public long getTime() { jtulach@1334: return getTimeImpl(); jtulach@1334: } jtulach@1334: jtulach@1334: private final long getTimeImpl() { jtulach@1334: if (cdate != null && !cdate.isNormalized()) { jtulach@1334: normalize(); jtulach@1334: } jtulach@1334: return fastTime; jtulach@1334: } jtulach@1334: jtulach@1334: /** jtulach@1334: * Sets this Date object to represent a point in time that is jtulach@1334: * time milliseconds after January 1, 1970 00:00:00 GMT. jtulach@1334: * jtulach@1334: * @param time the number of milliseconds. jtulach@1334: */ jtulach@1334: public void setTime(long time) { jtulach@1334: fastTime = time; jtulach@1334: cdate = null; jtulach@1334: } jtulach@1334: jtulach@1334: /** jtulach@1334: * Tests if this date is before the specified date. jtulach@1334: * jtulach@1334: * @param when a date. jtulach@1334: * @return true if and only if the instant of time jtulach@1334: * represented by this Date object is strictly jtulach@1334: * earlier than the instant represented by when; jtulach@1334: * false otherwise. jtulach@1334: * @exception NullPointerException if when is null. jtulach@1334: */ jtulach@1334: public boolean before(Date when) { jtulach@1334: return getMillisOf(this) < getMillisOf(when); jtulach@1334: } jtulach@1334: jtulach@1334: /** jtulach@1334: * Tests if this date is after the specified date. jtulach@1334: * jtulach@1334: * @param when a date. jtulach@1334: * @return true if and only if the instant represented jtulach@1334: * by this Date object is strictly later than the jtulach@1334: * instant represented by when; jtulach@1334: * false otherwise. jtulach@1334: * @exception NullPointerException if when is null. jtulach@1334: */ jtulach@1334: public boolean after(Date when) { jtulach@1334: return getMillisOf(this) > getMillisOf(when); jtulach@1334: } jtulach@1334: jtulach@1334: /** jtulach@1334: * Compares two dates for equality. jtulach@1334: * The result is true if and only if the argument is jtulach@1334: * not null and is a Date object that jtulach@1334: * represents the same point in time, to the millisecond, as this object. jtulach@1334: *

jtulach@1334: * Thus, two Date objects are equal if and only if the jtulach@1334: * getTime method returns the same long jtulach@1334: * value for both. jtulach@1334: * jtulach@1334: * @param obj the object to compare with. jtulach@1334: * @return true if the objects are the same; jtulach@1334: * false otherwise. jtulach@1334: * @see java.util.Date#getTime() jtulach@1334: */ jtulach@1334: public boolean equals(Object obj) { jtulach@1334: return obj instanceof Date && getTime() == ((Date) obj).getTime(); jtulach@1334: } jtulach@1334: jtulach@1334: /** jtulach@1334: * Returns the millisecond value of this Date object jtulach@1334: * without affecting its internal state. jtulach@1334: */ jtulach@1334: static final long getMillisOf(Date date) { jtulach@1334: if (date.cdate == null || date.cdate.isNormalized()) { jtulach@1334: return date.fastTime; jtulach@1334: } jtulach@1334: BaseCalendar.Date d = (BaseCalendar.Date) date.cdate.clone(); jtulach@1334: return gcal.getTime(d); jtulach@1334: } jtulach@1334: jtulach@1334: /** jtulach@1334: * Compares two Dates for ordering. jtulach@1334: * jtulach@1334: * @param anotherDate the Date to be compared. jtulach@1334: * @return the value 0 if the argument Date is equal to jtulach@1334: * this Date; a value less than 0 if this Date jtulach@1334: * is before the Date argument; and a value greater than jtulach@1334: * 0 if this Date is after the Date argument. jtulach@1334: * @since 1.2 jtulach@1334: * @exception NullPointerException if anotherDate is null. jtulach@1334: */ jtulach@1334: public int compareTo(Date anotherDate) { jtulach@1334: long thisTime = getMillisOf(this); jtulach@1334: long anotherTime = getMillisOf(anotherDate); jtulach@1334: return (thisTimelong jtulach@1334: * value returned by the {@link Date#getTime} jtulach@1334: * method. That is, the hash code is the value of the expression: jtulach@1334: *

jtulach@1334:      * (int)(this.getTime()^(this.getTime() >>> 32))
jtulach@1334: * jtulach@1334: * @return a hash code value for this object. jtulach@1334: */ jtulach@1334: public int hashCode() { jtulach@1334: long ht = this.getTime(); jtulach@1334: return (int) ht ^ (int) (ht >> 32); jtulach@1334: } jtulach@1334: jtulach@1334: /** jtulach@1334: * Converts this Date object to a String jtulach@1334: * of the form: jtulach@1334: *
jtulach@1334:      * dow mon dd hh:mm:ss zzz yyyy
jtulach@1334: * where: jtulach@1334: * jtulach@1334: * @return a string representation of this date. jtulach@1334: * @see java.util.Date#toLocaleString() jtulach@1334: * @see java.util.Date#toGMTString() jtulach@1334: */ jtulach@1334: public String toString() { jtulach@1334: // "EEE MMM dd HH:mm:ss zzz yyyy"; jtulach@1334: BaseCalendar.Date date = normalize(); jtulach@1334: StringBuilder sb = new StringBuilder(28); jtulach@1334: int index = date.getDayOfWeek(); jtulach@1334: if (index == gcal.SUNDAY) { jtulach@1334: index = 8; jtulach@1334: } jtulach@1334: convertToAbbr(sb, wtb[index]).append(' '); // EEE jtulach@1334: convertToAbbr(sb, wtb[date.getMonth() - 1 + 2 + 7]).append(' '); // MMM jtulach@1334: CalendarUtils.sprintf0d(sb, date.getDayOfMonth(), 2).append(' '); // dd jtulach@1334: jtulach@1334: CalendarUtils.sprintf0d(sb, date.getHours(), 2).append(':'); // HH jtulach@1334: CalendarUtils.sprintf0d(sb, date.getMinutes(), 2).append(':'); // mm jtulach@1334: CalendarUtils.sprintf0d(sb, date.getSeconds(), 2).append(' '); // ss jtulach@1334: TimeZone zi = date.getZone(); jtulach@1334: if (zi != null) { jtulach@1334: sb.append(zi.getDisplayName(date.isDaylightTime(), zi.SHORT, Locale.US)); // zzz jtulach@1334: } else { jtulach@1334: sb.append("GMT"); jtulach@1334: } jtulach@1334: sb.append(' ').append(date.getYear()); // yyyy jtulach@1334: return sb.toString(); jtulach@1334: } jtulach@1334: jtulach@1334: /** jtulach@1334: * Converts the given name to its 3-letter abbreviation (e.g., jtulach@1334: * "monday" -> "Mon") and stored the abbreviation in the given jtulach@1334: * StringBuilder. jtulach@1334: */ jtulach@1334: private static final StringBuilder convertToAbbr(StringBuilder sb, String name) { jtulach@1334: sb.append(Character.toUpperCase(name.charAt(0))); jtulach@1334: sb.append(name.charAt(1)).append(name.charAt(2)); jtulach@1334: return sb; jtulach@1334: } jtulach@1334: jtulach@1334: /** jtulach@1334: * Creates a string representation of this Date object in an jtulach@1334: * implementation-dependent form. The intent is that the form should jtulach@1334: * be familiar to the user of the Java application, wherever it may jtulach@1334: * happen to be running. The intent is comparable to that of the jtulach@1334: * "%c" format supported by the strftime() jtulach@1334: * function of ISO C. jtulach@1334: * jtulach@1334: * @return a string representation of this date, using the locale jtulach@1334: * conventions. jtulach@1334: * @see java.text.DateFormat jtulach@1334: * @see java.util.Date#toString() jtulach@1334: * @see java.util.Date#toGMTString() jtulach@1334: * @deprecated As of JDK version 1.1, jtulach@1334: * replaced by DateFormat.format(Date date). jtulach@1334: */ jtulach@1334: @Deprecated jtulach@1334: public String toLocaleString() { jtulach@1334: DateFormat formatter = DateFormat.getDateTimeInstance(); jtulach@1334: return formatter.format(this); jtulach@1334: } jtulach@1334: jtulach@1334: /** jtulach@1334: * Creates a string representation of this Date object of jtulach@1334: * the form: jtulach@1334: * jtulach@1334: * d mon yyyy hh:mm:ss GMT jtulach@1334: * where:

jtulach@1334: * The result does not depend on the local time zone. jtulach@1334: * jtulach@1334: * @return a string representation of this date, using the Internet GMT jtulach@1334: * conventions. jtulach@1334: * @see java.text.DateFormat jtulach@1334: * @see java.util.Date#toString() jtulach@1334: * @see java.util.Date#toLocaleString() jtulach@1334: * @deprecated As of JDK version 1.1, jtulach@1334: * replaced by DateFormat.format(Date date), using a jtulach@1334: * GMT TimeZone. jtulach@1334: */ jtulach@1334: @Deprecated jtulach@1334: public String toGMTString() { jtulach@1334: // d MMM yyyy HH:mm:ss 'GMT' jtulach@1334: long t = getTime(); jtulach@1334: BaseCalendar cal = getCalendarSystem(t); jtulach@1334: BaseCalendar.Date date = jtulach@1334: (BaseCalendar.Date) cal.getCalendarDate(getTime(), (TimeZone)null); jtulach@1334: StringBuilder sb = new StringBuilder(32); jtulach@1334: CalendarUtils.sprintf0d(sb, date.getDayOfMonth(), 1).append(' '); // d jtulach@1334: convertToAbbr(sb, wtb[date.getMonth() - 1 + 2 + 7]).append(' '); // MMM jtulach@1334: sb.append(date.getYear()).append(' '); // yyyy jtulach@1334: CalendarUtils.sprintf0d(sb, date.getHours(), 2).append(':'); // HH jtulach@1334: CalendarUtils.sprintf0d(sb, date.getMinutes(), 2).append(':'); // mm jtulach@1334: CalendarUtils.sprintf0d(sb, date.getSeconds(), 2); // ss jtulach@1334: sb.append(" GMT"); // ' GMT' jtulach@1334: return sb.toString(); jtulach@1334: } jtulach@1334: jtulach@1334: /** jtulach@1334: * Returns the offset, measured in minutes, for the local time zone jtulach@1334: * relative to UTC that is appropriate for the time represented by jtulach@1334: * this Date object. jtulach@1334: *

jtulach@1334: * For example, in Massachusetts, five time zones west of Greenwich: jtulach@1334: *

jtulach@1334:      * new Date(96, 1, 14).getTimezoneOffset() returns 300
jtulach@1334: * because on February 14, 1996, standard time (Eastern Standard Time) jtulach@1334: * is in use, which is offset five hours from UTC; but: jtulach@1334: *
jtulach@1334:      * new Date(96, 5, 1).getTimezoneOffset() returns 240
jtulach@1334: * because on June 1, 1996, daylight saving time (Eastern Daylight Time) jtulach@1334: * is in use, which is offset only four hours from UTC.

jtulach@1334: * This method produces the same result as if it computed: jtulach@1334: *

jtulach@1334:      * (this.getTime() - UTC(this.getYear(),
jtulach@1334:      *                       this.getMonth(),
jtulach@1334:      *                       this.getDate(),
jtulach@1334:      *                       this.getHours(),
jtulach@1334:      *                       this.getMinutes(),
jtulach@1334:      *                       this.getSeconds())) / (60 * 1000)
jtulach@1334:      * 
jtulach@1334: * jtulach@1334: * @return the time-zone offset, in minutes, for the current time zone. jtulach@1334: * @see java.util.Calendar#ZONE_OFFSET jtulach@1334: * @see java.util.Calendar#DST_OFFSET jtulach@1334: * @see java.util.TimeZone#getDefault jtulach@1334: * @deprecated As of JDK version 1.1, jtulach@1334: * replaced by -(Calendar.get(Calendar.ZONE_OFFSET) + jtulach@1334: * Calendar.get(Calendar.DST_OFFSET)) / (60 * 1000). jtulach@1334: */ jtulach@1334: @Deprecated jtulach@1334: public int getTimezoneOffset() { jtulach@1334: int zoneOffset; jtulach@1334: if (cdate == null) { jtulach@1334: TimeZone tz = TimeZone.getDefaultRef(); jtulach@1334: if (tz instanceof ZoneInfo) { jtulach@1334: zoneOffset = ((ZoneInfo)tz).getOffsets(fastTime, null); jtulach@1334: } else { jtulach@1334: zoneOffset = tz.getOffset(fastTime); jtulach@1334: } jtulach@1334: } else { jtulach@1334: normalize(); jtulach@1334: zoneOffset = cdate.getZoneOffset(); jtulach@1334: } jtulach@1334: return -zoneOffset/60000; // convert to minutes jtulach@1334: } jtulach@1334: jtulach@1334: private final BaseCalendar.Date getCalendarDate() { jtulach@1334: if (cdate == null) { jtulach@1334: BaseCalendar cal = getCalendarSystem(fastTime); jtulach@1334: cdate = (BaseCalendar.Date) cal.getCalendarDate(fastTime, jtulach@1334: TimeZone.getDefaultRef()); jtulach@1334: } jtulach@1334: return cdate; jtulach@1334: } jtulach@1334: jtulach@1334: private final BaseCalendar.Date normalize() { jtulach@1334: if (cdate == null) { jtulach@1334: BaseCalendar cal = getCalendarSystem(fastTime); jtulach@1334: cdate = (BaseCalendar.Date) cal.getCalendarDate(fastTime, jtulach@1334: TimeZone.getDefaultRef()); jtulach@1334: return cdate; jtulach@1334: } jtulach@1334: jtulach@1334: // Normalize cdate with the TimeZone in cdate first. This is jtulach@1334: // required for the compatible behavior. jtulach@1334: if (!cdate.isNormalized()) { jtulach@1334: cdate = normalize(cdate); jtulach@1334: } jtulach@1334: jtulach@1334: // If the default TimeZone has changed, then recalculate the jtulach@1334: // fields with the new TimeZone. jtulach@1334: TimeZone tz = TimeZone.getDefaultRef(); jtulach@1334: if (tz != cdate.getZone()) { jtulach@1334: cdate.setZone(tz); jtulach@1334: CalendarSystem cal = getCalendarSystem(cdate); jtulach@1334: cal.getCalendarDate(fastTime, cdate); jtulach@1334: } jtulach@1334: return cdate; jtulach@1334: } jtulach@1334: jtulach@1334: // fastTime and the returned data are in sync upon return. jtulach@1334: private final BaseCalendar.Date normalize(BaseCalendar.Date date) { jtulach@1334: int y = date.getNormalizedYear(); jtulach@1334: int m = date.getMonth(); jtulach@1334: int d = date.getDayOfMonth(); jtulach@1334: int hh = date.getHours(); jtulach@1334: int mm = date.getMinutes(); jtulach@1334: int ss = date.getSeconds(); jtulach@1334: int ms = date.getMillis(); jtulach@1334: TimeZone tz = date.getZone(); jtulach@1334: jtulach@1334: // If the specified year can't be handled using a long value jtulach@1334: // in milliseconds, GregorianCalendar is used for full jtulach@1334: // compatibility with underflow and overflow. This is required jtulach@1334: // by some JCK tests. The limits are based max year values - jtulach@1334: // years that can be represented by max values of d, hh, mm, jtulach@1334: // ss and ms. Also, let GregorianCalendar handle the default jtulach@1334: // cutover year so that we don't need to worry about the jtulach@1334: // transition here. jtulach@1334: if (y == 1582 || y > 280000000 || y < -280000000) { jtulach@1334: if (tz == null) { jtulach@1334: tz = TimeZone.getTimeZone("GMT"); jtulach@1334: } jtulach@1334: GregorianCalendar gc = new GregorianCalendar(tz); jtulach@1334: gc.clear(); jtulach@1334: gc.set(gc.MILLISECOND, ms); jtulach@1334: gc.set(y, m-1, d, hh, mm, ss); jtulach@1334: fastTime = gc.getTimeInMillis(); jtulach@1334: BaseCalendar cal = getCalendarSystem(fastTime); jtulach@1334: date = (BaseCalendar.Date) cal.getCalendarDate(fastTime, tz); jtulach@1334: return date; jtulach@1334: } jtulach@1334: jtulach@1334: BaseCalendar cal = getCalendarSystem(y); jtulach@1334: if (cal != getCalendarSystem(date)) { jtulach@1334: date = (BaseCalendar.Date) cal.newCalendarDate(tz); jtulach@1334: date.setNormalizedDate(y, m, d).setTimeOfDay(hh, mm, ss, ms); jtulach@1334: } jtulach@1334: // Perform the GregorianCalendar-style normalization. jtulach@1334: fastTime = cal.getTime(date); jtulach@1334: jtulach@1334: // In case the normalized date requires the other calendar jtulach@1334: // system, we need to recalculate it using the other one. jtulach@1334: BaseCalendar ncal = getCalendarSystem(fastTime); jtulach@1334: if (ncal != cal) { jtulach@1334: date = (BaseCalendar.Date) ncal.newCalendarDate(tz); jtulach@1334: date.setNormalizedDate(y, m, d).setTimeOfDay(hh, mm, ss, ms); jtulach@1334: fastTime = ncal.getTime(date); jtulach@1334: } jtulach@1334: return date; jtulach@1334: } jtulach@1334: jtulach@1334: /** jtulach@1334: * Returns the Gregorian or Julian calendar system to use with the jtulach@1334: * given date. Use Gregorian from October 15, 1582. jtulach@1334: * jtulach@1334: * @param year normalized calendar year (not -1900) jtulach@1334: * @return the CalendarSystem to use for the specified date jtulach@1334: */ jtulach@1334: private static final BaseCalendar getCalendarSystem(int year) { jtulach@1334: if (year >= 1582) { jtulach@1334: return gcal; jtulach@1334: } jtulach@1334: return getJulianCalendar(); jtulach@1334: } jtulach@1334: jtulach@1334: private static final BaseCalendar getCalendarSystem(long utc) { jtulach@1334: // Quickly check if the time stamp given by `utc' is the Epoch jtulach@1334: // or later. If it's before 1970, we convert the cutover to jtulach@1334: // local time to compare. jtulach@1334: if (utc >= 0 jtulach@1334: || utc >= GregorianCalendar.DEFAULT_GREGORIAN_CUTOVER jtulach@1334: - TimeZone.getDefaultRef().getOffset(utc)) { jtulach@1334: return gcal; jtulach@1334: } jtulach@1334: return getJulianCalendar(); jtulach@1334: } jtulach@1334: jtulach@1334: private static final BaseCalendar getCalendarSystem(BaseCalendar.Date cdate) { jtulach@1334: if (jcal == null) { jtulach@1334: return gcal; jtulach@1334: } jtulach@1334: if (cdate.getEra() != null) { jtulach@1334: return jcal; jtulach@1334: } jtulach@1334: return gcal; jtulach@1334: } jtulach@1334: jtulach@1334: synchronized private static final BaseCalendar getJulianCalendar() { jtulach@1334: if (jcal == null) { jtulach@1334: jcal = (BaseCalendar) CalendarSystem.forName("julian"); jtulach@1334: } jtulach@1334: return jcal; jtulach@1334: } jtulach@1334: jtulach@1334: /** jtulach@1334: * Save the state of this object to a stream (i.e., serialize it). jtulach@1334: * jtulach@1334: * @serialData The value returned by getTime() jtulach@1334: * is emitted (long). This represents the offset from jtulach@1334: * January 1, 1970, 00:00:00 GMT in milliseconds. jtulach@1334: */ jtulach@1334: private void writeObject(ObjectOutputStream s) jtulach@1334: throws IOException jtulach@1334: { jtulach@1334: s.writeLong(getTimeImpl()); jtulach@1334: } jtulach@1334: jtulach@1334: /** jtulach@1334: * Reconstitute this object from a stream (i.e., deserialize it). jtulach@1334: */ jtulach@1334: private void readObject(ObjectInputStream s) jtulach@1334: throws IOException, ClassNotFoundException jtulach@1334: { jtulach@1334: fastTime = s.readLong(); jtulach@1334: } jtulach@1334: }