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