1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/rt/emul/compact/src/main/java/java/util/Date.java Thu Oct 03 15:40:35 2013 +0200
1.3 @@ -0,0 +1,1331 @@
1.4 +/*
1.5 + * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved.
1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
1.7 + *
1.8 + * This code is free software; you can redistribute it and/or modify it
1.9 + * under the terms of the GNU General Public License version 2 only, as
1.10 + * published by the Free Software Foundation. Oracle designates this
1.11 + * particular file as subject to the "Classpath" exception as provided
1.12 + * by Oracle in the LICENSE file that accompanied this code.
1.13 + *
1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1.17 + * version 2 for more details (a copy is included in the LICENSE file that
1.18 + * accompanied this code).
1.19 + *
1.20 + * You should have received a copy of the GNU General Public License version
1.21 + * 2 along with this work; if not, write to the Free Software Foundation,
1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1.23 + *
1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
1.25 + * or visit www.oracle.com if you need additional information or have any
1.26 + * questions.
1.27 + */
1.28 +
1.29 +package java.util;
1.30 +
1.31 +import java.text.DateFormat;
1.32 +import java.io.IOException;
1.33 +import java.io.ObjectOutputStream;
1.34 +import java.io.ObjectInputStream;
1.35 +import java.lang.ref.SoftReference;
1.36 +import sun.util.calendar.BaseCalendar;
1.37 +import sun.util.calendar.CalendarDate;
1.38 +import sun.util.calendar.CalendarSystem;
1.39 +import sun.util.calendar.CalendarUtils;
1.40 +import sun.util.calendar.Era;
1.41 +import sun.util.calendar.Gregorian;
1.42 +import sun.util.calendar.ZoneInfo;
1.43 +
1.44 +/**
1.45 + * The class <code>Date</code> represents a specific instant
1.46 + * in time, with millisecond precision.
1.47 + * <p>
1.48 + * Prior to JDK 1.1, the class <code>Date</code> had two additional
1.49 + * functions. It allowed the interpretation of dates as year, month, day, hour,
1.50 + * minute, and second values. It also allowed the formatting and parsing
1.51 + * of date strings. Unfortunately, the API for these functions was not
1.52 + * amenable to internationalization. As of JDK 1.1, the
1.53 + * <code>Calendar</code> class should be used to convert between dates and time
1.54 + * fields and the <code>DateFormat</code> class should be used to format and
1.55 + * parse date strings.
1.56 + * The corresponding methods in <code>Date</code> are deprecated.
1.57 + * <p>
1.58 + * Although the <code>Date</code> class is intended to reflect
1.59 + * coordinated universal time (UTC), it may not do so exactly,
1.60 + * depending on the host environment of the Java Virtual Machine.
1.61 + * Nearly all modern operating systems assume that 1 day =
1.62 + * 24 × 60 × 60 = 86400 seconds
1.63 + * in all cases. In UTC, however, about once every year or two there
1.64 + * is an extra second, called a "leap second." The leap
1.65 + * second is always added as the last second of the day, and always
1.66 + * on December 31 or June 30. For example, the last minute of the
1.67 + * year 1995 was 61 seconds long, thanks to an added leap second.
1.68 + * Most computer clocks are not accurate enough to be able to reflect
1.69 + * the leap-second distinction.
1.70 + * <p>
1.71 + * Some computer standards are defined in terms of Greenwich mean
1.72 + * time (GMT), which is equivalent to universal time (UT). GMT is
1.73 + * the "civil" name for the standard; UT is the
1.74 + * "scientific" name for the same standard. The
1.75 + * distinction between UTC and UT is that UTC is based on an atomic
1.76 + * clock and UT is based on astronomical observations, which for all
1.77 + * practical purposes is an invisibly fine hair to split. Because the
1.78 + * earth's rotation is not uniform (it slows down and speeds up
1.79 + * in complicated ways), UT does not always flow uniformly. Leap
1.80 + * seconds are introduced as needed into UTC so as to keep UTC within
1.81 + * 0.9 seconds of UT1, which is a version of UT with certain
1.82 + * corrections applied. There are other time and date systems as
1.83 + * well; for example, the time scale used by the satellite-based
1.84 + * global positioning system (GPS) is synchronized to UTC but is
1.85 + * <i>not</i> adjusted for leap seconds. An interesting source of
1.86 + * further information is the U.S. Naval Observatory, particularly
1.87 + * the Directorate of Time at:
1.88 + * <blockquote><pre>
1.89 + * <a href=http://tycho.usno.navy.mil>http://tycho.usno.navy.mil</a>
1.90 + * </pre></blockquote>
1.91 + * <p>
1.92 + * and their definitions of "Systems of Time" at:
1.93 + * <blockquote><pre>
1.94 + * <a href=http://tycho.usno.navy.mil/systime.html>http://tycho.usno.navy.mil/systime.html</a>
1.95 + * </pre></blockquote>
1.96 + * <p>
1.97 + * In all methods of class <code>Date</code> that accept or return
1.98 + * year, month, date, hours, minutes, and seconds values, the
1.99 + * following representations are used:
1.100 + * <ul>
1.101 + * <li>A year <i>y</i> is represented by the integer
1.102 + * <i>y</i> <code>- 1900</code>.
1.103 + * <li>A month is represented by an integer from 0 to 11; 0 is January,
1.104 + * 1 is February, and so forth; thus 11 is December.
1.105 + * <li>A date (day of month) is represented by an integer from 1 to 31
1.106 + * in the usual manner.
1.107 + * <li>An hour is represented by an integer from 0 to 23. Thus, the hour
1.108 + * from midnight to 1 a.m. is hour 0, and the hour from noon to 1
1.109 + * p.m. is hour 12.
1.110 + * <li>A minute is represented by an integer from 0 to 59 in the usual manner.
1.111 + * <li>A second is represented by an integer from 0 to 61; the values 60 and
1.112 + * 61 occur only for leap seconds and even then only in Java
1.113 + * implementations that actually track leap seconds correctly. Because
1.114 + * of the manner in which leap seconds are currently introduced, it is
1.115 + * extremely unlikely that two leap seconds will occur in the same
1.116 + * minute, but this specification follows the date and time conventions
1.117 + * for ISO C.
1.118 + * </ul>
1.119 + * <p>
1.120 + * In all cases, arguments given to methods for these purposes need
1.121 + * not fall within the indicated ranges; for example, a date may be
1.122 + * specified as January 32 and is interpreted as meaning February 1.
1.123 + *
1.124 + * @author James Gosling
1.125 + * @author Arthur van Hoff
1.126 + * @author Alan Liu
1.127 + * @see java.text.DateFormat
1.128 + * @see java.util.Calendar
1.129 + * @see java.util.TimeZone
1.130 + * @since JDK1.0
1.131 + */
1.132 +public class Date
1.133 + implements java.io.Serializable, Cloneable, Comparable<Date>
1.134 +{
1.135 + private static final BaseCalendar gcal =
1.136 + CalendarSystem.getGregorianCalendar();
1.137 + private static BaseCalendar jcal;
1.138 +
1.139 + private transient long fastTime;
1.140 +
1.141 + /*
1.142 + * If cdate is null, then fastTime indicates the time in millis.
1.143 + * If cdate.isNormalized() is true, then fastTime and cdate are in
1.144 + * synch. Otherwise, fastTime is ignored, and cdate indicates the
1.145 + * time.
1.146 + */
1.147 + private transient BaseCalendar.Date cdate;
1.148 +
1.149 + // Initialized just before the value is used. See parse().
1.150 + private static int defaultCenturyStart;
1.151 +
1.152 + /* use serialVersionUID from modified java.util.Date for
1.153 + * interoperability with JDK1.1. The Date was modified to write
1.154 + * and read only the UTC time.
1.155 + */
1.156 + private static final long serialVersionUID = 7523967970034938905L;
1.157 +
1.158 + /**
1.159 + * Allocates a <code>Date</code> object and initializes it so that
1.160 + * it represents the time at which it was allocated, measured to the
1.161 + * nearest millisecond.
1.162 + *
1.163 + * @see java.lang.System#currentTimeMillis()
1.164 + */
1.165 + public Date() {
1.166 + this(System.currentTimeMillis());
1.167 + }
1.168 +
1.169 + /**
1.170 + * Allocates a <code>Date</code> object and initializes it to
1.171 + * represent the specified number of milliseconds since the
1.172 + * standard base time known as "the epoch", namely January 1,
1.173 + * 1970, 00:00:00 GMT.
1.174 + *
1.175 + * @param date the milliseconds since January 1, 1970, 00:00:00 GMT.
1.176 + * @see java.lang.System#currentTimeMillis()
1.177 + */
1.178 + public Date(long date) {
1.179 + fastTime = date;
1.180 + }
1.181 +
1.182 + /**
1.183 + * Allocates a <code>Date</code> object and initializes it so that
1.184 + * it represents midnight, local time, at the beginning of the day
1.185 + * specified by the <code>year</code>, <code>month</code>, and
1.186 + * <code>date</code> arguments.
1.187 + *
1.188 + * @param year the year minus 1900.
1.189 + * @param month the month between 0-11.
1.190 + * @param date the day of the month between 1-31.
1.191 + * @see java.util.Calendar
1.192 + * @deprecated As of JDK version 1.1,
1.193 + * replaced by <code>Calendar.set(year + 1900, month, date)</code>
1.194 + * or <code>GregorianCalendar(year + 1900, month, date)</code>.
1.195 + */
1.196 + @Deprecated
1.197 + public Date(int year, int month, int date) {
1.198 + this(year, month, date, 0, 0, 0);
1.199 + }
1.200 +
1.201 + /**
1.202 + * Allocates a <code>Date</code> object and initializes it so that
1.203 + * it represents the instant at the start of the minute specified by
1.204 + * the <code>year</code>, <code>month</code>, <code>date</code>,
1.205 + * <code>hrs</code>, and <code>min</code> arguments, in the local
1.206 + * time zone.
1.207 + *
1.208 + * @param year the year minus 1900.
1.209 + * @param month the month between 0-11.
1.210 + * @param date the day of the month between 1-31.
1.211 + * @param hrs the hours between 0-23.
1.212 + * @param min the minutes between 0-59.
1.213 + * @see java.util.Calendar
1.214 + * @deprecated As of JDK version 1.1,
1.215 + * replaced by <code>Calendar.set(year + 1900, month, date,
1.216 + * hrs, min)</code> or <code>GregorianCalendar(year + 1900,
1.217 + * month, date, hrs, min)</code>.
1.218 + */
1.219 + @Deprecated
1.220 + public Date(int year, int month, int date, int hrs, int min) {
1.221 + this(year, month, date, hrs, min, 0);
1.222 + }
1.223 +
1.224 + /**
1.225 + * Allocates a <code>Date</code> object and initializes it so that
1.226 + * it represents the instant at the start of the second specified
1.227 + * by the <code>year</code>, <code>month</code>, <code>date</code>,
1.228 + * <code>hrs</code>, <code>min</code>, and <code>sec</code> arguments,
1.229 + * in the local time zone.
1.230 + *
1.231 + * @param year the year minus 1900.
1.232 + * @param month the month between 0-11.
1.233 + * @param date the day of the month between 1-31.
1.234 + * @param hrs the hours between 0-23.
1.235 + * @param min the minutes between 0-59.
1.236 + * @param sec the seconds between 0-59.
1.237 + * @see java.util.Calendar
1.238 + * @deprecated As of JDK version 1.1,
1.239 + * replaced by <code>Calendar.set(year + 1900, month, date,
1.240 + * hrs, min, sec)</code> or <code>GregorianCalendar(year + 1900,
1.241 + * month, date, hrs, min, sec)</code>.
1.242 + */
1.243 + @Deprecated
1.244 + public Date(int year, int month, int date, int hrs, int min, int sec) {
1.245 + int y = year + 1900;
1.246 + // month is 0-based. So we have to normalize month to support Long.MAX_VALUE.
1.247 + if (month >= 12) {
1.248 + y += month / 12;
1.249 + month %= 12;
1.250 + } else if (month < 0) {
1.251 + y += CalendarUtils.floorDivide(month, 12);
1.252 + month = CalendarUtils.mod(month, 12);
1.253 + }
1.254 + BaseCalendar cal = getCalendarSystem(y);
1.255 + cdate = (BaseCalendar.Date) cal.newCalendarDate(TimeZone.getDefaultRef());
1.256 + cdate.setNormalizedDate(y, month + 1, date).setTimeOfDay(hrs, min, sec, 0);
1.257 + getTimeImpl();
1.258 + cdate = null;
1.259 + }
1.260 +
1.261 + /**
1.262 + * Allocates a <code>Date</code> object and initializes it so that
1.263 + * it represents the date and time indicated by the string
1.264 + * <code>s</code>, which is interpreted as if by the
1.265 + * {@link Date#parse} method.
1.266 + *
1.267 + * @param s a string representation of the date.
1.268 + * @see java.text.DateFormat
1.269 + * @see java.util.Date#parse(java.lang.String)
1.270 + * @deprecated As of JDK version 1.1,
1.271 + * replaced by <code>DateFormat.parse(String s)</code>.
1.272 + */
1.273 + @Deprecated
1.274 + public Date(String s) {
1.275 + this(parse(s));
1.276 + }
1.277 +
1.278 + /**
1.279 + * Return a copy of this object.
1.280 + */
1.281 + public Object clone() {
1.282 + Date d = null;
1.283 + try {
1.284 + d = (Date)super.clone();
1.285 + if (cdate != null) {
1.286 + d.cdate = (BaseCalendar.Date) cdate.clone();
1.287 + }
1.288 + } catch (CloneNotSupportedException e) {} // Won't happen
1.289 + return d;
1.290 + }
1.291 +
1.292 + /**
1.293 + * Determines the date and time based on the arguments. The
1.294 + * arguments are interpreted as a year, month, day of the month,
1.295 + * hour of the day, minute within the hour, and second within the
1.296 + * minute, exactly as for the <tt>Date</tt> constructor with six
1.297 + * arguments, except that the arguments are interpreted relative
1.298 + * to UTC rather than to the local time zone. The time indicated is
1.299 + * returned represented as the distance, measured in milliseconds,
1.300 + * of that time from the epoch (00:00:00 GMT on January 1, 1970).
1.301 + *
1.302 + * @param year the year minus 1900.
1.303 + * @param month the month between 0-11.
1.304 + * @param date the day of the month between 1-31.
1.305 + * @param hrs the hours between 0-23.
1.306 + * @param min the minutes between 0-59.
1.307 + * @param sec the seconds between 0-59.
1.308 + * @return the number of milliseconds since January 1, 1970, 00:00:00 GMT for
1.309 + * the date and time specified by the arguments.
1.310 + * @see java.util.Calendar
1.311 + * @deprecated As of JDK version 1.1,
1.312 + * replaced by <code>Calendar.set(year + 1900, month, date,
1.313 + * hrs, min, sec)</code> or <code>GregorianCalendar(year + 1900,
1.314 + * month, date, hrs, min, sec)</code>, using a UTC
1.315 + * <code>TimeZone</code>, followed by <code>Calendar.getTime().getTime()</code>.
1.316 + */
1.317 + @Deprecated
1.318 + public static long UTC(int year, int month, int date,
1.319 + int hrs, int min, int sec) {
1.320 + int y = year + 1900;
1.321 + // month is 0-based. So we have to normalize month to support Long.MAX_VALUE.
1.322 + if (month >= 12) {
1.323 + y += month / 12;
1.324 + month %= 12;
1.325 + } else if (month < 0) {
1.326 + y += CalendarUtils.floorDivide(month, 12);
1.327 + month = CalendarUtils.mod(month, 12);
1.328 + }
1.329 + int m = month + 1;
1.330 + BaseCalendar cal = getCalendarSystem(y);
1.331 + BaseCalendar.Date udate = (BaseCalendar.Date) cal.newCalendarDate(null);
1.332 + udate.setNormalizedDate(y, m, date).setTimeOfDay(hrs, min, sec, 0);
1.333 +
1.334 + // Use a Date instance to perform normalization. Its fastTime
1.335 + // is the UTC value after the normalization.
1.336 + Date d = new Date(0);
1.337 + d.normalize(udate);
1.338 + return d.fastTime;
1.339 + }
1.340 +
1.341 + /**
1.342 + * Attempts to interpret the string <tt>s</tt> as a representation
1.343 + * of a date and time. If the attempt is successful, the time
1.344 + * indicated is returned represented as the distance, measured in
1.345 + * milliseconds, of that time from the epoch (00:00:00 GMT on
1.346 + * January 1, 1970). If the attempt fails, an
1.347 + * <tt>IllegalArgumentException</tt> is thrown.
1.348 + * <p>
1.349 + * It accepts many syntaxes; in particular, it recognizes the IETF
1.350 + * standard date syntax: "Sat, 12 Aug 1995 13:30:00 GMT". It also
1.351 + * understands the continental U.S. time-zone abbreviations, but for
1.352 + * general use, a time-zone offset should be used: "Sat, 12 Aug 1995
1.353 + * 13:30:00 GMT+0430" (4 hours, 30 minutes west of the Greenwich
1.354 + * meridian). If no time zone is specified, the local time zone is
1.355 + * assumed. GMT and UTC are considered equivalent.
1.356 + * <p>
1.357 + * The string <tt>s</tt> is processed from left to right, looking for
1.358 + * data of interest. Any material in <tt>s</tt> that is within the
1.359 + * ASCII parenthesis characters <tt>(</tt> and <tt>)</tt> is ignored.
1.360 + * Parentheses may be nested. Otherwise, the only characters permitted
1.361 + * within <tt>s</tt> are these ASCII characters:
1.362 + * <blockquote><pre>
1.363 + * abcdefghijklmnopqrstuvwxyz
1.364 + * ABCDEFGHIJKLMNOPQRSTUVWXYZ
1.365 + * 0123456789,+-:/</pre></blockquote>
1.366 + * and whitespace characters.<p>
1.367 + * A consecutive sequence of decimal digits is treated as a decimal
1.368 + * number:<ul>
1.369 + * <li>If a number is preceded by <tt>+</tt> or <tt>-</tt> and a year
1.370 + * has already been recognized, then the number is a time-zone
1.371 + * offset. If the number is less than 24, it is an offset measured
1.372 + * in hours. Otherwise, it is regarded as an offset in minutes,
1.373 + * expressed in 24-hour time format without punctuation. A
1.374 + * preceding <tt>-</tt> means a westward offset. Time zone offsets
1.375 + * are always relative to UTC (Greenwich). Thus, for example,
1.376 + * <tt>-5</tt> occurring in the string would mean "five hours west
1.377 + * of Greenwich" and <tt>+0430</tt> would mean "four hours and
1.378 + * thirty minutes east of Greenwich." It is permitted for the
1.379 + * string to specify <tt>GMT</tt>, <tt>UT</tt>, or <tt>UTC</tt>
1.380 + * redundantly-for example, <tt>GMT-5</tt> or <tt>utc+0430</tt>.
1.381 + * <li>The number is regarded as a year number if one of the
1.382 + * following conditions is true:
1.383 + * <ul>
1.384 + * <li>The number is equal to or greater than 70 and followed by a
1.385 + * space, comma, slash, or end of string
1.386 + * <li>The number is less than 70, and both a month and a day of
1.387 + * the month have already been recognized</li>
1.388 + * </ul>
1.389 + * If the recognized year number is less than 100, it is
1.390 + * interpreted as an abbreviated year relative to a century of
1.391 + * which dates are within 80 years before and 19 years after
1.392 + * the time when the Date class is initialized.
1.393 + * After adjusting the year number, 1900 is subtracted from
1.394 + * it. For example, if the current year is 1999 then years in
1.395 + * the range 19 to 99 are assumed to mean 1919 to 1999, while
1.396 + * years from 0 to 18 are assumed to mean 2000 to 2018. Note
1.397 + * that this is slightly different from the interpretation of
1.398 + * years less than 100 that is used in {@link java.text.SimpleDateFormat}.
1.399 + * <li>If the number is followed by a colon, it is regarded as an hour,
1.400 + * unless an hour has already been recognized, in which case it is
1.401 + * regarded as a minute.
1.402 + * <li>If the number is followed by a slash, it is regarded as a month
1.403 + * (it is decreased by 1 to produce a number in the range <tt>0</tt>
1.404 + * to <tt>11</tt>), unless a month has already been recognized, in
1.405 + * which case it is regarded as a day of the month.
1.406 + * <li>If the number is followed by whitespace, a comma, a hyphen, or
1.407 + * end of string, then if an hour has been recognized but not a
1.408 + * minute, it is regarded as a minute; otherwise, if a minute has
1.409 + * been recognized but not a second, it is regarded as a second;
1.410 + * otherwise, it is regarded as a day of the month. </ul><p>
1.411 + * A consecutive sequence of letters is regarded as a word and treated
1.412 + * as follows:<ul>
1.413 + * <li>A word that matches <tt>AM</tt>, ignoring case, is ignored (but
1.414 + * the parse fails if an hour has not been recognized or is less
1.415 + * than <tt>1</tt> or greater than <tt>12</tt>).
1.416 + * <li>A word that matches <tt>PM</tt>, ignoring case, adds <tt>12</tt>
1.417 + * to the hour (but the parse fails if an hour has not been
1.418 + * recognized or is less than <tt>1</tt> or greater than <tt>12</tt>).
1.419 + * <li>Any word that matches any prefix of <tt>SUNDAY, MONDAY, TUESDAY,
1.420 + * WEDNESDAY, THURSDAY, FRIDAY</tt>, or <tt>SATURDAY</tt>, ignoring
1.421 + * case, is ignored. For example, <tt>sat, Friday, TUE</tt>, and
1.422 + * <tt>Thurs</tt> are ignored.
1.423 + * <li>Otherwise, any word that matches any prefix of <tt>JANUARY,
1.424 + * FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, AUGUST, SEPTEMBER,
1.425 + * OCTOBER, NOVEMBER</tt>, or <tt>DECEMBER</tt>, ignoring case, and
1.426 + * considering them in the order given here, is recognized as
1.427 + * specifying a month and is converted to a number (<tt>0</tt> to
1.428 + * <tt>11</tt>). For example, <tt>aug, Sept, april</tt>, and
1.429 + * <tt>NOV</tt> are recognized as months. So is <tt>Ma</tt>, which
1.430 + * is recognized as <tt>MARCH</tt>, not <tt>MAY</tt>.
1.431 + * <li>Any word that matches <tt>GMT, UT</tt>, or <tt>UTC</tt>, ignoring
1.432 + * case, is treated as referring to UTC.
1.433 + * <li>Any word that matches <tt>EST, CST, MST</tt>, or <tt>PST</tt>,
1.434 + * ignoring case, is recognized as referring to the time zone in
1.435 + * North America that is five, six, seven, or eight hours west of
1.436 + * Greenwich, respectively. Any word that matches <tt>EDT, CDT,
1.437 + * MDT</tt>, or <tt>PDT</tt>, ignoring case, is recognized as
1.438 + * referring to the same time zone, respectively, during daylight
1.439 + * saving time.</ul><p>
1.440 + * Once the entire string s has been scanned, it is converted to a time
1.441 + * result in one of two ways. If a time zone or time-zone offset has been
1.442 + * recognized, then the year, month, day of month, hour, minute, and
1.443 + * second are interpreted in UTC and then the time-zone offset is
1.444 + * applied. Otherwise, the year, month, day of month, hour, minute, and
1.445 + * second are interpreted in the local time zone.
1.446 + *
1.447 + * @param s a string to be parsed as a date.
1.448 + * @return the number of milliseconds since January 1, 1970, 00:00:00 GMT
1.449 + * represented by the string argument.
1.450 + * @see java.text.DateFormat
1.451 + * @deprecated As of JDK version 1.1,
1.452 + * replaced by <code>DateFormat.parse(String s)</code>.
1.453 + */
1.454 + @Deprecated
1.455 + public static long parse(String s) {
1.456 + int year = Integer.MIN_VALUE;
1.457 + int mon = -1;
1.458 + int mday = -1;
1.459 + int hour = -1;
1.460 + int min = -1;
1.461 + int sec = -1;
1.462 + int millis = -1;
1.463 + int c = -1;
1.464 + int i = 0;
1.465 + int n = -1;
1.466 + int wst = -1;
1.467 + int tzoffset = -1;
1.468 + int prevc = 0;
1.469 + syntax:
1.470 + {
1.471 + if (s == null)
1.472 + break syntax;
1.473 + int limit = s.length();
1.474 + while (i < limit) {
1.475 + c = s.charAt(i);
1.476 + i++;
1.477 + if (c <= ' ' || c == ',')
1.478 + continue;
1.479 + if (c == '(') { // skip comments
1.480 + int depth = 1;
1.481 + while (i < limit) {
1.482 + c = s.charAt(i);
1.483 + i++;
1.484 + if (c == '(') depth++;
1.485 + else if (c == ')')
1.486 + if (--depth <= 0)
1.487 + break;
1.488 + }
1.489 + continue;
1.490 + }
1.491 + if ('0' <= c && c <= '9') {
1.492 + n = c - '0';
1.493 + while (i < limit && '0' <= (c = s.charAt(i)) && c <= '9') {
1.494 + n = n * 10 + c - '0';
1.495 + i++;
1.496 + }
1.497 + if (prevc == '+' || prevc == '-' && year != Integer.MIN_VALUE) {
1.498 + // timezone offset
1.499 + if (n < 24)
1.500 + n = n * 60; // EG. "GMT-3"
1.501 + else
1.502 + n = n % 100 + n / 100 * 60; // eg "GMT-0430"
1.503 + if (prevc == '+') // plus means east of GMT
1.504 + n = -n;
1.505 + if (tzoffset != 0 && tzoffset != -1)
1.506 + break syntax;
1.507 + tzoffset = n;
1.508 + } else if (n >= 70)
1.509 + if (year != Integer.MIN_VALUE)
1.510 + break syntax;
1.511 + else if (c <= ' ' || c == ',' || c == '/' || i >= limit)
1.512 + // year = n < 1900 ? n : n - 1900;
1.513 + year = n;
1.514 + else
1.515 + break syntax;
1.516 + else if (c == ':')
1.517 + if (hour < 0)
1.518 + hour = (byte) n;
1.519 + else if (min < 0)
1.520 + min = (byte) n;
1.521 + else
1.522 + break syntax;
1.523 + else if (c == '/')
1.524 + if (mon < 0)
1.525 + mon = (byte) (n - 1);
1.526 + else if (mday < 0)
1.527 + mday = (byte) n;
1.528 + else
1.529 + break syntax;
1.530 + else if (i < limit && c != ',' && c > ' ' && c != '-')
1.531 + break syntax;
1.532 + else if (hour >= 0 && min < 0)
1.533 + min = (byte) n;
1.534 + else if (min >= 0 && sec < 0)
1.535 + sec = (byte) n;
1.536 + else if (mday < 0)
1.537 + mday = (byte) n;
1.538 + // Handle two-digit years < 70 (70-99 handled above).
1.539 + else if (year == Integer.MIN_VALUE && mon >= 0 && mday >= 0)
1.540 + year = n;
1.541 + else
1.542 + break syntax;
1.543 + prevc = 0;
1.544 + } else if (c == '/' || c == ':' || c == '+' || c == '-')
1.545 + prevc = c;
1.546 + else {
1.547 + int st = i - 1;
1.548 + while (i < limit) {
1.549 + c = s.charAt(i);
1.550 + if (!('A' <= c && c <= 'Z' || 'a' <= c && c <= 'z'))
1.551 + break;
1.552 + i++;
1.553 + }
1.554 + if (i <= st + 1)
1.555 + break syntax;
1.556 + int k;
1.557 + for (k = wtb.length; --k >= 0;)
1.558 + if (wtb[k].regionMatches(true, 0, s, st, i - st)) {
1.559 + int action = ttb[k];
1.560 + if (action != 0) {
1.561 + if (action == 1) { // pm
1.562 + if (hour > 12 || hour < 1)
1.563 + break syntax;
1.564 + else if (hour < 12)
1.565 + hour += 12;
1.566 + } else if (action == 14) { // am
1.567 + if (hour > 12 || hour < 1)
1.568 + break syntax;
1.569 + else if (hour == 12)
1.570 + hour = 0;
1.571 + } else if (action <= 13) { // month!
1.572 + if (mon < 0)
1.573 + mon = (byte) (action - 2);
1.574 + else
1.575 + break syntax;
1.576 + } else {
1.577 + tzoffset = action - 10000;
1.578 + }
1.579 + }
1.580 + break;
1.581 + }
1.582 + if (k < 0)
1.583 + break syntax;
1.584 + prevc = 0;
1.585 + }
1.586 + }
1.587 + if (year == Integer.MIN_VALUE || mon < 0 || mday < 0)
1.588 + break syntax;
1.589 + // Parse 2-digit years within the correct default century.
1.590 + if (year < 100) {
1.591 + synchronized (Date.class) {
1.592 + if (defaultCenturyStart == 0) {
1.593 + defaultCenturyStart = gcal.getCalendarDate().getYear() - 80;
1.594 + }
1.595 + }
1.596 + year += (defaultCenturyStart / 100) * 100;
1.597 + if (year < defaultCenturyStart) year += 100;
1.598 + }
1.599 + if (sec < 0)
1.600 + sec = 0;
1.601 + if (min < 0)
1.602 + min = 0;
1.603 + if (hour < 0)
1.604 + hour = 0;
1.605 + BaseCalendar cal = getCalendarSystem(year);
1.606 + if (tzoffset == -1) { // no time zone specified, have to use local
1.607 + BaseCalendar.Date ldate = (BaseCalendar.Date) cal.newCalendarDate(TimeZone.getDefaultRef());
1.608 + ldate.setDate(year, mon + 1, mday);
1.609 + ldate.setTimeOfDay(hour, min, sec, 0);
1.610 + return cal.getTime(ldate);
1.611 + }
1.612 + BaseCalendar.Date udate = (BaseCalendar.Date) cal.newCalendarDate(null); // no time zone
1.613 + udate.setDate(year, mon + 1, mday);
1.614 + udate.setTimeOfDay(hour, min, sec, 0);
1.615 + return cal.getTime(udate) + tzoffset * (60 * 1000);
1.616 + }
1.617 + // syntax error
1.618 + throw new IllegalArgumentException();
1.619 + }
1.620 + private final static String wtb[] = {
1.621 + "am", "pm",
1.622 + "monday", "tuesday", "wednesday", "thursday", "friday",
1.623 + "saturday", "sunday",
1.624 + "january", "february", "march", "april", "may", "june",
1.625 + "july", "august", "september", "october", "november", "december",
1.626 + "gmt", "ut", "utc", "est", "edt", "cst", "cdt",
1.627 + "mst", "mdt", "pst", "pdt"
1.628 + };
1.629 + private final static int ttb[] = {
1.630 + 14, 1, 0, 0, 0, 0, 0, 0, 0,
1.631 + 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
1.632 + 10000 + 0, 10000 + 0, 10000 + 0, // GMT/UT/UTC
1.633 + 10000 + 5 * 60, 10000 + 4 * 60, // EST/EDT
1.634 + 10000 + 6 * 60, 10000 + 5 * 60, // CST/CDT
1.635 + 10000 + 7 * 60, 10000 + 6 * 60, // MST/MDT
1.636 + 10000 + 8 * 60, 10000 + 7 * 60 // PST/PDT
1.637 + };
1.638 +
1.639 + /**
1.640 + * Returns a value that is the result of subtracting 1900 from the
1.641 + * year that contains or begins with the instant in time represented
1.642 + * by this <code>Date</code> object, as interpreted in the local
1.643 + * time zone.
1.644 + *
1.645 + * @return the year represented by this date, minus 1900.
1.646 + * @see java.util.Calendar
1.647 + * @deprecated As of JDK version 1.1,
1.648 + * replaced by <code>Calendar.get(Calendar.YEAR) - 1900</code>.
1.649 + */
1.650 + @Deprecated
1.651 + public int getYear() {
1.652 + return normalize().getYear() - 1900;
1.653 + }
1.654 +
1.655 + /**
1.656 + * Sets the year of this <tt>Date</tt> object to be the specified
1.657 + * value plus 1900. This <code>Date</code> object is modified so
1.658 + * that it represents a point in time within the specified year,
1.659 + * with the month, date, hour, minute, and second the same as
1.660 + * before, as interpreted in the local time zone. (Of course, if
1.661 + * the date was February 29, for example, and the year is set to a
1.662 + * non-leap year, then the new date will be treated as if it were
1.663 + * on March 1.)
1.664 + *
1.665 + * @param year the year value.
1.666 + * @see java.util.Calendar
1.667 + * @deprecated As of JDK version 1.1,
1.668 + * replaced by <code>Calendar.set(Calendar.YEAR, year + 1900)</code>.
1.669 + */
1.670 + @Deprecated
1.671 + public void setYear(int year) {
1.672 + getCalendarDate().setNormalizedYear(year + 1900);
1.673 + }
1.674 +
1.675 + /**
1.676 + * Returns a number representing the month that contains or begins
1.677 + * with the instant in time represented by this <tt>Date</tt> object.
1.678 + * The value returned is between <code>0</code> and <code>11</code>,
1.679 + * with the value <code>0</code> representing January.
1.680 + *
1.681 + * @return the month represented by this date.
1.682 + * @see java.util.Calendar
1.683 + * @deprecated As of JDK version 1.1,
1.684 + * replaced by <code>Calendar.get(Calendar.MONTH)</code>.
1.685 + */
1.686 + @Deprecated
1.687 + public int getMonth() {
1.688 + return normalize().getMonth() - 1; // adjust 1-based to 0-based
1.689 + }
1.690 +
1.691 + /**
1.692 + * Sets the month of this date to the specified value. This
1.693 + * <tt>Date</tt> object is modified so that it represents a point
1.694 + * in time within the specified month, with the year, date, hour,
1.695 + * minute, and second the same as before, as interpreted in the
1.696 + * local time zone. If the date was October 31, for example, and
1.697 + * the month is set to June, then the new date will be treated as
1.698 + * if it were on July 1, because June has only 30 days.
1.699 + *
1.700 + * @param month the month value between 0-11.
1.701 + * @see java.util.Calendar
1.702 + * @deprecated As of JDK version 1.1,
1.703 + * replaced by <code>Calendar.set(Calendar.MONTH, int month)</code>.
1.704 + */
1.705 + @Deprecated
1.706 + public void setMonth(int month) {
1.707 + int y = 0;
1.708 + if (month >= 12) {
1.709 + y = month / 12;
1.710 + month %= 12;
1.711 + } else if (month < 0) {
1.712 + y = CalendarUtils.floorDivide(month, 12);
1.713 + month = CalendarUtils.mod(month, 12);
1.714 + }
1.715 + BaseCalendar.Date d = getCalendarDate();
1.716 + if (y != 0) {
1.717 + d.setNormalizedYear(d.getNormalizedYear() + y);
1.718 + }
1.719 + d.setMonth(month + 1); // adjust 0-based to 1-based month numbering
1.720 + }
1.721 +
1.722 + /**
1.723 + * Returns the day of the month represented by this <tt>Date</tt> object.
1.724 + * The value returned is between <code>1</code> and <code>31</code>
1.725 + * representing the day of the month that contains or begins with the
1.726 + * instant in time represented by this <tt>Date</tt> object, as
1.727 + * interpreted in the local time zone.
1.728 + *
1.729 + * @return the day of the month represented by this date.
1.730 + * @see java.util.Calendar
1.731 + * @deprecated As of JDK version 1.1,
1.732 + * replaced by <code>Calendar.get(Calendar.DAY_OF_MONTH)</code>.
1.733 + * @deprecated
1.734 + */
1.735 + @Deprecated
1.736 + public int getDate() {
1.737 + return normalize().getDayOfMonth();
1.738 + }
1.739 +
1.740 + /**
1.741 + * Sets the day of the month of this <tt>Date</tt> object to the
1.742 + * specified value. This <tt>Date</tt> object is modified so that
1.743 + * it represents a point in time within the specified day of the
1.744 + * month, with the year, month, hour, minute, and second the same
1.745 + * as before, as interpreted in the local time zone. If the date
1.746 + * was April 30, for example, and the date is set to 31, then it
1.747 + * will be treated as if it were on May 1, because April has only
1.748 + * 30 days.
1.749 + *
1.750 + * @param date the day of the month value between 1-31.
1.751 + * @see java.util.Calendar
1.752 + * @deprecated As of JDK version 1.1,
1.753 + * replaced by <code>Calendar.set(Calendar.DAY_OF_MONTH, int date)</code>.
1.754 + */
1.755 + @Deprecated
1.756 + public void setDate(int date) {
1.757 + getCalendarDate().setDayOfMonth(date);
1.758 + }
1.759 +
1.760 + /**
1.761 + * Returns the day of the week represented by this date. The
1.762 + * returned value (<tt>0</tt> = Sunday, <tt>1</tt> = Monday,
1.763 + * <tt>2</tt> = Tuesday, <tt>3</tt> = Wednesday, <tt>4</tt> =
1.764 + * Thursday, <tt>5</tt> = Friday, <tt>6</tt> = Saturday)
1.765 + * represents the day of the week that contains or begins with
1.766 + * the instant in time represented by this <tt>Date</tt> object,
1.767 + * as interpreted in the local time zone.
1.768 + *
1.769 + * @return the day of the week represented by this date.
1.770 + * @see java.util.Calendar
1.771 + * @deprecated As of JDK version 1.1,
1.772 + * replaced by <code>Calendar.get(Calendar.DAY_OF_WEEK)</code>.
1.773 + */
1.774 + @Deprecated
1.775 + public int getDay() {
1.776 + return normalize().getDayOfWeek() - gcal.SUNDAY;
1.777 + }
1.778 +
1.779 + /**
1.780 + * Returns the hour represented by this <tt>Date</tt> object. The
1.781 + * returned value is a number (<tt>0</tt> through <tt>23</tt>)
1.782 + * representing the hour within the day that contains or begins
1.783 + * with the instant in time represented by this <tt>Date</tt>
1.784 + * object, as interpreted in the local time zone.
1.785 + *
1.786 + * @return the hour represented by this date.
1.787 + * @see java.util.Calendar
1.788 + * @deprecated As of JDK version 1.1,
1.789 + * replaced by <code>Calendar.get(Calendar.HOUR_OF_DAY)</code>.
1.790 + */
1.791 + @Deprecated
1.792 + public int getHours() {
1.793 + return normalize().getHours();
1.794 + }
1.795 +
1.796 + /**
1.797 + * Sets the hour of this <tt>Date</tt> object to the specified value.
1.798 + * This <tt>Date</tt> object is modified so that it represents a point
1.799 + * in time within the specified hour of the day, with the year, month,
1.800 + * date, minute, and second the same as before, as interpreted in the
1.801 + * local time zone.
1.802 + *
1.803 + * @param hours the hour value.
1.804 + * @see java.util.Calendar
1.805 + * @deprecated As of JDK version 1.1,
1.806 + * replaced by <code>Calendar.set(Calendar.HOUR_OF_DAY, int hours)</code>.
1.807 + */
1.808 + @Deprecated
1.809 + public void setHours(int hours) {
1.810 + getCalendarDate().setHours(hours);
1.811 + }
1.812 +
1.813 + /**
1.814 + * Returns the number of minutes past the hour represented by this date,
1.815 + * as interpreted in the local time zone.
1.816 + * The value returned is between <code>0</code> and <code>59</code>.
1.817 + *
1.818 + * @return the number of minutes past the hour represented by this date.
1.819 + * @see java.util.Calendar
1.820 + * @deprecated As of JDK version 1.1,
1.821 + * replaced by <code>Calendar.get(Calendar.MINUTE)</code>.
1.822 + */
1.823 + @Deprecated
1.824 + public int getMinutes() {
1.825 + return normalize().getMinutes();
1.826 + }
1.827 +
1.828 + /**
1.829 + * Sets the minutes of this <tt>Date</tt> object to the specified value.
1.830 + * This <tt>Date</tt> object is modified so that it represents a point
1.831 + * in time within the specified minute of the hour, with the year, month,
1.832 + * date, hour, and second the same as before, as interpreted in the
1.833 + * local time zone.
1.834 + *
1.835 + * @param minutes the value of the minutes.
1.836 + * @see java.util.Calendar
1.837 + * @deprecated As of JDK version 1.1,
1.838 + * replaced by <code>Calendar.set(Calendar.MINUTE, int minutes)</code>.
1.839 + */
1.840 + @Deprecated
1.841 + public void setMinutes(int minutes) {
1.842 + getCalendarDate().setMinutes(minutes);
1.843 + }
1.844 +
1.845 + /**
1.846 + * Returns the number of seconds past the minute represented by this date.
1.847 + * The value returned is between <code>0</code> and <code>61</code>. The
1.848 + * values <code>60</code> and <code>61</code> can only occur on those
1.849 + * Java Virtual Machines that take leap seconds into account.
1.850 + *
1.851 + * @return the number of seconds past the minute represented by this date.
1.852 + * @see java.util.Calendar
1.853 + * @deprecated As of JDK version 1.1,
1.854 + * replaced by <code>Calendar.get(Calendar.SECOND)</code>.
1.855 + */
1.856 + @Deprecated
1.857 + public int getSeconds() {
1.858 + return normalize().getSeconds();
1.859 + }
1.860 +
1.861 + /**
1.862 + * Sets the seconds of this <tt>Date</tt> to the specified value.
1.863 + * This <tt>Date</tt> object is modified so that it represents a
1.864 + * point in time within the specified second of the minute, with
1.865 + * the year, month, date, hour, and minute the same as before, as
1.866 + * interpreted in the local time zone.
1.867 + *
1.868 + * @param seconds the seconds value.
1.869 + * @see java.util.Calendar
1.870 + * @deprecated As of JDK version 1.1,
1.871 + * replaced by <code>Calendar.set(Calendar.SECOND, int seconds)</code>.
1.872 + */
1.873 + @Deprecated
1.874 + public void setSeconds(int seconds) {
1.875 + getCalendarDate().setSeconds(seconds);
1.876 + }
1.877 +
1.878 + /**
1.879 + * Returns the number of milliseconds since January 1, 1970, 00:00:00 GMT
1.880 + * represented by this <tt>Date</tt> object.
1.881 + *
1.882 + * @return the number of milliseconds since January 1, 1970, 00:00:00 GMT
1.883 + * represented by this date.
1.884 + */
1.885 + public long getTime() {
1.886 + return getTimeImpl();
1.887 + }
1.888 +
1.889 + private final long getTimeImpl() {
1.890 + if (cdate != null && !cdate.isNormalized()) {
1.891 + normalize();
1.892 + }
1.893 + return fastTime;
1.894 + }
1.895 +
1.896 + /**
1.897 + * Sets this <code>Date</code> object to represent a point in time that is
1.898 + * <code>time</code> milliseconds after January 1, 1970 00:00:00 GMT.
1.899 + *
1.900 + * @param time the number of milliseconds.
1.901 + */
1.902 + public void setTime(long time) {
1.903 + fastTime = time;
1.904 + cdate = null;
1.905 + }
1.906 +
1.907 + /**
1.908 + * Tests if this date is before the specified date.
1.909 + *
1.910 + * @param when a date.
1.911 + * @return <code>true</code> if and only if the instant of time
1.912 + * represented by this <tt>Date</tt> object is strictly
1.913 + * earlier than the instant represented by <tt>when</tt>;
1.914 + * <code>false</code> otherwise.
1.915 + * @exception NullPointerException if <code>when</code> is null.
1.916 + */
1.917 + public boolean before(Date when) {
1.918 + return getMillisOf(this) < getMillisOf(when);
1.919 + }
1.920 +
1.921 + /**
1.922 + * Tests if this date is after the specified date.
1.923 + *
1.924 + * @param when a date.
1.925 + * @return <code>true</code> if and only if the instant represented
1.926 + * by this <tt>Date</tt> object is strictly later than the
1.927 + * instant represented by <tt>when</tt>;
1.928 + * <code>false</code> otherwise.
1.929 + * @exception NullPointerException if <code>when</code> is null.
1.930 + */
1.931 + public boolean after(Date when) {
1.932 + return getMillisOf(this) > getMillisOf(when);
1.933 + }
1.934 +
1.935 + /**
1.936 + * Compares two dates for equality.
1.937 + * The result is <code>true</code> if and only if the argument is
1.938 + * not <code>null</code> and is a <code>Date</code> object that
1.939 + * represents the same point in time, to the millisecond, as this object.
1.940 + * <p>
1.941 + * Thus, two <code>Date</code> objects are equal if and only if the
1.942 + * <code>getTime</code> method returns the same <code>long</code>
1.943 + * value for both.
1.944 + *
1.945 + * @param obj the object to compare with.
1.946 + * @return <code>true</code> if the objects are the same;
1.947 + * <code>false</code> otherwise.
1.948 + * @see java.util.Date#getTime()
1.949 + */
1.950 + public boolean equals(Object obj) {
1.951 + return obj instanceof Date && getTime() == ((Date) obj).getTime();
1.952 + }
1.953 +
1.954 + /**
1.955 + * Returns the millisecond value of this <code>Date</code> object
1.956 + * without affecting its internal state.
1.957 + */
1.958 + static final long getMillisOf(Date date) {
1.959 + if (date.cdate == null || date.cdate.isNormalized()) {
1.960 + return date.fastTime;
1.961 + }
1.962 + BaseCalendar.Date d = (BaseCalendar.Date) date.cdate.clone();
1.963 + return gcal.getTime(d);
1.964 + }
1.965 +
1.966 + /**
1.967 + * Compares two Dates for ordering.
1.968 + *
1.969 + * @param anotherDate the <code>Date</code> to be compared.
1.970 + * @return the value <code>0</code> if the argument Date is equal to
1.971 + * this Date; a value less than <code>0</code> if this Date
1.972 + * is before the Date argument; and a value greater than
1.973 + * <code>0</code> if this Date is after the Date argument.
1.974 + * @since 1.2
1.975 + * @exception NullPointerException if <code>anotherDate</code> is null.
1.976 + */
1.977 + public int compareTo(Date anotherDate) {
1.978 + long thisTime = getMillisOf(this);
1.979 + long anotherTime = getMillisOf(anotherDate);
1.980 + return (thisTime<anotherTime ? -1 : (thisTime==anotherTime ? 0 : 1));
1.981 + }
1.982 +
1.983 + /**
1.984 + * Returns a hash code value for this object. The result is the
1.985 + * exclusive OR of the two halves of the primitive <tt>long</tt>
1.986 + * value returned by the {@link Date#getTime}
1.987 + * method. That is, the hash code is the value of the expression:
1.988 + * <blockquote><pre>
1.989 + * (int)(this.getTime()^(this.getTime() >>> 32))</pre></blockquote>
1.990 + *
1.991 + * @return a hash code value for this object.
1.992 + */
1.993 + public int hashCode() {
1.994 + long ht = this.getTime();
1.995 + return (int) ht ^ (int) (ht >> 32);
1.996 + }
1.997 +
1.998 + /**
1.999 + * Converts this <code>Date</code> object to a <code>String</code>
1.1000 + * of the form:
1.1001 + * <blockquote><pre>
1.1002 + * dow mon dd hh:mm:ss zzz yyyy</pre></blockquote>
1.1003 + * where:<ul>
1.1004 + * <li><tt>dow</tt> is the day of the week (<tt>Sun, Mon, Tue, Wed,
1.1005 + * Thu, Fri, Sat</tt>).
1.1006 + * <li><tt>mon</tt> is the month (<tt>Jan, Feb, Mar, Apr, May, Jun,
1.1007 + * Jul, Aug, Sep, Oct, Nov, Dec</tt>).
1.1008 + * <li><tt>dd</tt> is the day of the month (<tt>01</tt> through
1.1009 + * <tt>31</tt>), as two decimal digits.
1.1010 + * <li><tt>hh</tt> is the hour of the day (<tt>00</tt> through
1.1011 + * <tt>23</tt>), as two decimal digits.
1.1012 + * <li><tt>mm</tt> is the minute within the hour (<tt>00</tt> through
1.1013 + * <tt>59</tt>), as two decimal digits.
1.1014 + * <li><tt>ss</tt> is the second within the minute (<tt>00</tt> through
1.1015 + * <tt>61</tt>, as two decimal digits.
1.1016 + * <li><tt>zzz</tt> is the time zone (and may reflect daylight saving
1.1017 + * time). Standard time zone abbreviations include those
1.1018 + * recognized by the method <tt>parse</tt>. If time zone
1.1019 + * information is not available, then <tt>zzz</tt> is empty -
1.1020 + * that is, it consists of no characters at all.
1.1021 + * <li><tt>yyyy</tt> is the year, as four decimal digits.
1.1022 + * </ul>
1.1023 + *
1.1024 + * @return a string representation of this date.
1.1025 + * @see java.util.Date#toLocaleString()
1.1026 + * @see java.util.Date#toGMTString()
1.1027 + */
1.1028 + public String toString() {
1.1029 + // "EEE MMM dd HH:mm:ss zzz yyyy";
1.1030 + BaseCalendar.Date date = normalize();
1.1031 + StringBuilder sb = new StringBuilder(28);
1.1032 + int index = date.getDayOfWeek();
1.1033 + if (index == gcal.SUNDAY) {
1.1034 + index = 8;
1.1035 + }
1.1036 + convertToAbbr(sb, wtb[index]).append(' '); // EEE
1.1037 + convertToAbbr(sb, wtb[date.getMonth() - 1 + 2 + 7]).append(' '); // MMM
1.1038 + CalendarUtils.sprintf0d(sb, date.getDayOfMonth(), 2).append(' '); // dd
1.1039 +
1.1040 + CalendarUtils.sprintf0d(sb, date.getHours(), 2).append(':'); // HH
1.1041 + CalendarUtils.sprintf0d(sb, date.getMinutes(), 2).append(':'); // mm
1.1042 + CalendarUtils.sprintf0d(sb, date.getSeconds(), 2).append(' '); // ss
1.1043 + TimeZone zi = date.getZone();
1.1044 + if (zi != null) {
1.1045 + sb.append(zi.getDisplayName(date.isDaylightTime(), zi.SHORT, Locale.US)); // zzz
1.1046 + } else {
1.1047 + sb.append("GMT");
1.1048 + }
1.1049 + sb.append(' ').append(date.getYear()); // yyyy
1.1050 + return sb.toString();
1.1051 + }
1.1052 +
1.1053 + /**
1.1054 + * Converts the given name to its 3-letter abbreviation (e.g.,
1.1055 + * "monday" -> "Mon") and stored the abbreviation in the given
1.1056 + * <code>StringBuilder</code>.
1.1057 + */
1.1058 + private static final StringBuilder convertToAbbr(StringBuilder sb, String name) {
1.1059 + sb.append(Character.toUpperCase(name.charAt(0)));
1.1060 + sb.append(name.charAt(1)).append(name.charAt(2));
1.1061 + return sb;
1.1062 + }
1.1063 +
1.1064 + /**
1.1065 + * Creates a string representation of this <tt>Date</tt> object in an
1.1066 + * implementation-dependent form. The intent is that the form should
1.1067 + * be familiar to the user of the Java application, wherever it may
1.1068 + * happen to be running. The intent is comparable to that of the
1.1069 + * "<code>%c</code>" format supported by the <code>strftime()</code>
1.1070 + * function of ISO C.
1.1071 + *
1.1072 + * @return a string representation of this date, using the locale
1.1073 + * conventions.
1.1074 + * @see java.text.DateFormat
1.1075 + * @see java.util.Date#toString()
1.1076 + * @see java.util.Date#toGMTString()
1.1077 + * @deprecated As of JDK version 1.1,
1.1078 + * replaced by <code>DateFormat.format(Date date)</code>.
1.1079 + */
1.1080 + @Deprecated
1.1081 + public String toLocaleString() {
1.1082 + DateFormat formatter = DateFormat.getDateTimeInstance();
1.1083 + return formatter.format(this);
1.1084 + }
1.1085 +
1.1086 + /**
1.1087 + * Creates a string representation of this <tt>Date</tt> object of
1.1088 + * the form:
1.1089 + * <blockquote<pre>
1.1090 + * d mon yyyy hh:mm:ss GMT</pre></blockquote>
1.1091 + * where:<ul>
1.1092 + * <li><i>d</i> is the day of the month (<tt>1</tt> through <tt>31</tt>),
1.1093 + * as one or two decimal digits.
1.1094 + * <li><i>mon</i> is the month (<tt>Jan, Feb, Mar, Apr, May, Jun, Jul,
1.1095 + * Aug, Sep, Oct, Nov, Dec</tt>).
1.1096 + * <li><i>yyyy</i> is the year, as four decimal digits.
1.1097 + * <li><i>hh</i> is the hour of the day (<tt>00</tt> through <tt>23</tt>),
1.1098 + * as two decimal digits.
1.1099 + * <li><i>mm</i> is the minute within the hour (<tt>00</tt> through
1.1100 + * <tt>59</tt>), as two decimal digits.
1.1101 + * <li><i>ss</i> is the second within the minute (<tt>00</tt> through
1.1102 + * <tt>61</tt>), as two decimal digits.
1.1103 + * <li><i>GMT</i> is exactly the ASCII letters "<tt>GMT</tt>" to indicate
1.1104 + * Greenwich Mean Time.
1.1105 + * </ul><p>
1.1106 + * The result does not depend on the local time zone.
1.1107 + *
1.1108 + * @return a string representation of this date, using the Internet GMT
1.1109 + * conventions.
1.1110 + * @see java.text.DateFormat
1.1111 + * @see java.util.Date#toString()
1.1112 + * @see java.util.Date#toLocaleString()
1.1113 + * @deprecated As of JDK version 1.1,
1.1114 + * replaced by <code>DateFormat.format(Date date)</code>, using a
1.1115 + * GMT <code>TimeZone</code>.
1.1116 + */
1.1117 + @Deprecated
1.1118 + public String toGMTString() {
1.1119 + // d MMM yyyy HH:mm:ss 'GMT'
1.1120 + long t = getTime();
1.1121 + BaseCalendar cal = getCalendarSystem(t);
1.1122 + BaseCalendar.Date date =
1.1123 + (BaseCalendar.Date) cal.getCalendarDate(getTime(), (TimeZone)null);
1.1124 + StringBuilder sb = new StringBuilder(32);
1.1125 + CalendarUtils.sprintf0d(sb, date.getDayOfMonth(), 1).append(' '); // d
1.1126 + convertToAbbr(sb, wtb[date.getMonth() - 1 + 2 + 7]).append(' '); // MMM
1.1127 + sb.append(date.getYear()).append(' '); // yyyy
1.1128 + CalendarUtils.sprintf0d(sb, date.getHours(), 2).append(':'); // HH
1.1129 + CalendarUtils.sprintf0d(sb, date.getMinutes(), 2).append(':'); // mm
1.1130 + CalendarUtils.sprintf0d(sb, date.getSeconds(), 2); // ss
1.1131 + sb.append(" GMT"); // ' GMT'
1.1132 + return sb.toString();
1.1133 + }
1.1134 +
1.1135 + /**
1.1136 + * Returns the offset, measured in minutes, for the local time zone
1.1137 + * relative to UTC that is appropriate for the time represented by
1.1138 + * this <code>Date</code> object.
1.1139 + * <p>
1.1140 + * For example, in Massachusetts, five time zones west of Greenwich:
1.1141 + * <blockquote><pre>
1.1142 + * new Date(96, 1, 14).getTimezoneOffset() returns 300</pre></blockquote>
1.1143 + * because on February 14, 1996, standard time (Eastern Standard Time)
1.1144 + * is in use, which is offset five hours from UTC; but:
1.1145 + * <blockquote><pre>
1.1146 + * new Date(96, 5, 1).getTimezoneOffset() returns 240</pre></blockquote>
1.1147 + * because on June 1, 1996, daylight saving time (Eastern Daylight Time)
1.1148 + * is in use, which is offset only four hours from UTC.<p>
1.1149 + * This method produces the same result as if it computed:
1.1150 + * <blockquote><pre>
1.1151 + * (this.getTime() - UTC(this.getYear(),
1.1152 + * this.getMonth(),
1.1153 + * this.getDate(),
1.1154 + * this.getHours(),
1.1155 + * this.getMinutes(),
1.1156 + * this.getSeconds())) / (60 * 1000)
1.1157 + * </pre></blockquote>
1.1158 + *
1.1159 + * @return the time-zone offset, in minutes, for the current time zone.
1.1160 + * @see java.util.Calendar#ZONE_OFFSET
1.1161 + * @see java.util.Calendar#DST_OFFSET
1.1162 + * @see java.util.TimeZone#getDefault
1.1163 + * @deprecated As of JDK version 1.1,
1.1164 + * replaced by <code>-(Calendar.get(Calendar.ZONE_OFFSET) +
1.1165 + * Calendar.get(Calendar.DST_OFFSET)) / (60 * 1000)</code>.
1.1166 + */
1.1167 + @Deprecated
1.1168 + public int getTimezoneOffset() {
1.1169 + int zoneOffset;
1.1170 + if (cdate == null) {
1.1171 + TimeZone tz = TimeZone.getDefaultRef();
1.1172 + if (tz instanceof ZoneInfo) {
1.1173 + zoneOffset = ((ZoneInfo)tz).getOffsets(fastTime, null);
1.1174 + } else {
1.1175 + zoneOffset = tz.getOffset(fastTime);
1.1176 + }
1.1177 + } else {
1.1178 + normalize();
1.1179 + zoneOffset = cdate.getZoneOffset();
1.1180 + }
1.1181 + return -zoneOffset/60000; // convert to minutes
1.1182 + }
1.1183 +
1.1184 + private final BaseCalendar.Date getCalendarDate() {
1.1185 + if (cdate == null) {
1.1186 + BaseCalendar cal = getCalendarSystem(fastTime);
1.1187 + cdate = (BaseCalendar.Date) cal.getCalendarDate(fastTime,
1.1188 + TimeZone.getDefaultRef());
1.1189 + }
1.1190 + return cdate;
1.1191 + }
1.1192 +
1.1193 + private final BaseCalendar.Date normalize() {
1.1194 + if (cdate == null) {
1.1195 + BaseCalendar cal = getCalendarSystem(fastTime);
1.1196 + cdate = (BaseCalendar.Date) cal.getCalendarDate(fastTime,
1.1197 + TimeZone.getDefaultRef());
1.1198 + return cdate;
1.1199 + }
1.1200 +
1.1201 + // Normalize cdate with the TimeZone in cdate first. This is
1.1202 + // required for the compatible behavior.
1.1203 + if (!cdate.isNormalized()) {
1.1204 + cdate = normalize(cdate);
1.1205 + }
1.1206 +
1.1207 + // If the default TimeZone has changed, then recalculate the
1.1208 + // fields with the new TimeZone.
1.1209 + TimeZone tz = TimeZone.getDefaultRef();
1.1210 + if (tz != cdate.getZone()) {
1.1211 + cdate.setZone(tz);
1.1212 + CalendarSystem cal = getCalendarSystem(cdate);
1.1213 + cal.getCalendarDate(fastTime, cdate);
1.1214 + }
1.1215 + return cdate;
1.1216 + }
1.1217 +
1.1218 + // fastTime and the returned data are in sync upon return.
1.1219 + private final BaseCalendar.Date normalize(BaseCalendar.Date date) {
1.1220 + int y = date.getNormalizedYear();
1.1221 + int m = date.getMonth();
1.1222 + int d = date.getDayOfMonth();
1.1223 + int hh = date.getHours();
1.1224 + int mm = date.getMinutes();
1.1225 + int ss = date.getSeconds();
1.1226 + int ms = date.getMillis();
1.1227 + TimeZone tz = date.getZone();
1.1228 +
1.1229 + // If the specified year can't be handled using a long value
1.1230 + // in milliseconds, GregorianCalendar is used for full
1.1231 + // compatibility with underflow and overflow. This is required
1.1232 + // by some JCK tests. The limits are based max year values -
1.1233 + // years that can be represented by max values of d, hh, mm,
1.1234 + // ss and ms. Also, let GregorianCalendar handle the default
1.1235 + // cutover year so that we don't need to worry about the
1.1236 + // transition here.
1.1237 + if (y == 1582 || y > 280000000 || y < -280000000) {
1.1238 + if (tz == null) {
1.1239 + tz = TimeZone.getTimeZone("GMT");
1.1240 + }
1.1241 + GregorianCalendar gc = new GregorianCalendar(tz);
1.1242 + gc.clear();
1.1243 + gc.set(gc.MILLISECOND, ms);
1.1244 + gc.set(y, m-1, d, hh, mm, ss);
1.1245 + fastTime = gc.getTimeInMillis();
1.1246 + BaseCalendar cal = getCalendarSystem(fastTime);
1.1247 + date = (BaseCalendar.Date) cal.getCalendarDate(fastTime, tz);
1.1248 + return date;
1.1249 + }
1.1250 +
1.1251 + BaseCalendar cal = getCalendarSystem(y);
1.1252 + if (cal != getCalendarSystem(date)) {
1.1253 + date = (BaseCalendar.Date) cal.newCalendarDate(tz);
1.1254 + date.setNormalizedDate(y, m, d).setTimeOfDay(hh, mm, ss, ms);
1.1255 + }
1.1256 + // Perform the GregorianCalendar-style normalization.
1.1257 + fastTime = cal.getTime(date);
1.1258 +
1.1259 + // In case the normalized date requires the other calendar
1.1260 + // system, we need to recalculate it using the other one.
1.1261 + BaseCalendar ncal = getCalendarSystem(fastTime);
1.1262 + if (ncal != cal) {
1.1263 + date = (BaseCalendar.Date) ncal.newCalendarDate(tz);
1.1264 + date.setNormalizedDate(y, m, d).setTimeOfDay(hh, mm, ss, ms);
1.1265 + fastTime = ncal.getTime(date);
1.1266 + }
1.1267 + return date;
1.1268 + }
1.1269 +
1.1270 + /**
1.1271 + * Returns the Gregorian or Julian calendar system to use with the
1.1272 + * given date. Use Gregorian from October 15, 1582.
1.1273 + *
1.1274 + * @param year normalized calendar year (not -1900)
1.1275 + * @return the CalendarSystem to use for the specified date
1.1276 + */
1.1277 + private static final BaseCalendar getCalendarSystem(int year) {
1.1278 + if (year >= 1582) {
1.1279 + return gcal;
1.1280 + }
1.1281 + return getJulianCalendar();
1.1282 + }
1.1283 +
1.1284 + private static final BaseCalendar getCalendarSystem(long utc) {
1.1285 + // Quickly check if the time stamp given by `utc' is the Epoch
1.1286 + // or later. If it's before 1970, we convert the cutover to
1.1287 + // local time to compare.
1.1288 + if (utc >= 0
1.1289 + || utc >= GregorianCalendar.DEFAULT_GREGORIAN_CUTOVER
1.1290 + - TimeZone.getDefaultRef().getOffset(utc)) {
1.1291 + return gcal;
1.1292 + }
1.1293 + return getJulianCalendar();
1.1294 + }
1.1295 +
1.1296 + private static final BaseCalendar getCalendarSystem(BaseCalendar.Date cdate) {
1.1297 + if (jcal == null) {
1.1298 + return gcal;
1.1299 + }
1.1300 + if (cdate.getEra() != null) {
1.1301 + return jcal;
1.1302 + }
1.1303 + return gcal;
1.1304 + }
1.1305 +
1.1306 + synchronized private static final BaseCalendar getJulianCalendar() {
1.1307 + if (jcal == null) {
1.1308 + jcal = (BaseCalendar) CalendarSystem.forName("julian");
1.1309 + }
1.1310 + return jcal;
1.1311 + }
1.1312 +
1.1313 + /**
1.1314 + * Save the state of this object to a stream (i.e., serialize it).
1.1315 + *
1.1316 + * @serialData The value returned by <code>getTime()</code>
1.1317 + * is emitted (long). This represents the offset from
1.1318 + * January 1, 1970, 00:00:00 GMT in milliseconds.
1.1319 + */
1.1320 + private void writeObject(ObjectOutputStream s)
1.1321 + throws IOException
1.1322 + {
1.1323 + s.writeLong(getTimeImpl());
1.1324 + }
1.1325 +
1.1326 + /**
1.1327 + * Reconstitute this object from a stream (i.e., deserialize it).
1.1328 + */
1.1329 + private void readObject(ObjectInputStream s)
1.1330 + throws IOException, ClassNotFoundException
1.1331 + {
1.1332 + fastTime = s.readLong();
1.1333 + }
1.1334 +}