Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.base/share/classes/java/util/Date.java
41152 views
1
/*
2
* Copyright (c) 1994, 2019, 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} represents a specific instant
45
* in time, with millisecond precision.
46
* <p>
47
* Prior to JDK&nbsp;1.1, the class {@code Date} 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} class should be used to convert between dates and time
53
* fields and the {@code DateFormat} class should be used to format and
54
* parse date strings.
55
* The corresponding methods in {@code Date} are deprecated.
56
* <p>
57
* Although the {@code Date} 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 United States Naval Observatory (USNO):
86
* <blockquote><pre>
87
* <a href="https://www.usno.navy.mil/USNO">https://www.usno.navy.mil/USNO</a>
88
* </pre></blockquote>
89
* <p>
90
* and the material regarding "Systems of Time" at:
91
* <blockquote><pre>
92
* <a href="https://www.usno.navy.mil/USNO/time/master-clock/systems-of-time">https://www.usno.navy.mil/USNO/time/master-clock/systems-of-time</a>
93
* </pre></blockquote>
94
* <p>
95
* which has descriptions of various different time systems including
96
* UT, UT1, and UTC.
97
* <p>
98
* In all methods of class {@code Date} that accept or return
99
* year, month, date, hours, minutes, and seconds values, the
100
* following representations are used:
101
* <ul>
102
* <li>A year <i>y</i> is represented by the integer
103
* <i>y</i>&nbsp;{@code - 1900}.
104
* <li>A month is represented by an integer from 0 to 11; 0 is January,
105
* 1 is February, and so forth; thus 11 is December.
106
* <li>A date (day of month) is represented by an integer from 1 to 31
107
* in the usual manner.
108
* <li>An hour is represented by an integer from 0 to 23. Thus, the hour
109
* from midnight to 1 a.m. is hour 0, and the hour from noon to 1
110
* p.m. is hour 12.
111
* <li>A minute is represented by an integer from 0 to 59 in the usual manner.
112
* <li>A second is represented by an integer from 0 to 61; the values 60 and
113
* 61 occur only for leap seconds and even then only in Java
114
* implementations that actually track leap seconds correctly. Because
115
* of the manner in which leap seconds are currently introduced, it is
116
* extremely unlikely that two leap seconds will occur in the same
117
* minute, but this specification follows the date and time conventions
118
* for ISO C.
119
* </ul>
120
* <p>
121
* In all cases, arguments given to methods for these purposes need
122
* not fall within the indicated ranges; for example, a date may be
123
* specified as January 32 and is interpreted as meaning February 1.
124
*
125
* @author James Gosling
126
* @author Arthur van Hoff
127
* @author Alan Liu
128
* @see java.text.DateFormat
129
* @see java.util.Calendar
130
* @see java.util.TimeZone
131
* @since 1.0
132
*/
133
public class Date
134
implements java.io.Serializable, Cloneable, Comparable<Date>
135
{
136
private static final BaseCalendar gcal =
137
CalendarSystem.getGregorianCalendar();
138
private static BaseCalendar jcal;
139
140
private transient long fastTime;
141
142
/*
143
* If cdate is null, then fastTime indicates the time in millis.
144
* If cdate.isNormalized() is true, then fastTime and cdate are in
145
* synch. Otherwise, fastTime is ignored, and cdate indicates the
146
* time.
147
*/
148
private transient BaseCalendar.Date cdate;
149
150
// Initialized just before the value is used. See parse().
151
private static int defaultCenturyStart;
152
153
/* use serialVersionUID from modified java.util.Date for
154
* interoperability with JDK1.1. The Date was modified to write
155
* and read only the UTC time.
156
*/
157
@java.io.Serial
158
private static final long serialVersionUID = 7523967970034938905L;
159
160
/**
161
* Allocates a {@code Date} object and initializes it so that
162
* it represents the time at which it was allocated, measured to the
163
* nearest millisecond.
164
*
165
* @see java.lang.System#currentTimeMillis()
166
*/
167
public Date() {
168
this(System.currentTimeMillis());
169
}
170
171
/**
172
* Allocates a {@code Date} object and initializes it to
173
* represent the specified number of milliseconds since the
174
* standard base time known as "the epoch", namely January 1,
175
* 1970, 00:00:00 GMT.
176
*
177
* @param date the milliseconds since January 1, 1970, 00:00:00 GMT.
178
* @see java.lang.System#currentTimeMillis()
179
*/
180
public Date(long date) {
181
fastTime = date;
182
}
183
184
/**
185
* Allocates a {@code Date} object and initializes it so that
186
* it represents midnight, local time, at the beginning of the day
187
* specified by the {@code year}, {@code month}, and
188
* {@code date} arguments.
189
*
190
* @param year the year minus 1900.
191
* @param month the month between 0-11.
192
* @param date the day of the month between 1-31.
193
* @see java.util.Calendar
194
* @deprecated As of JDK version 1.1,
195
* replaced by {@code Calendar.set(year + 1900, month, date)}
196
* or {@code GregorianCalendar(year + 1900, month, date)}.
197
*/
198
@Deprecated
199
public Date(int year, int month, int date) {
200
this(year, month, date, 0, 0, 0);
201
}
202
203
/**
204
* Allocates a {@code Date} object and initializes it so that
205
* it represents the instant at the start of the minute specified by
206
* the {@code year}, {@code month}, {@code date},
207
* {@code hrs}, and {@code min} arguments, in the local
208
* time zone.
209
*
210
* @param year the year minus 1900.
211
* @param month the month between 0-11.
212
* @param date the day of the month between 1-31.
213
* @param hrs the hours between 0-23.
214
* @param min the minutes between 0-59.
215
* @see java.util.Calendar
216
* @deprecated As of JDK version 1.1,
217
* replaced by {@code Calendar.set(year + 1900, month, date, hrs, min)}
218
* or {@code GregorianCalendar(year + 1900, month, date, hrs, min)}.
219
*/
220
@Deprecated
221
public Date(int year, int month, int date, int hrs, int min) {
222
this(year, month, date, hrs, min, 0);
223
}
224
225
/**
226
* Allocates a {@code Date} object and initializes it so that
227
* it represents the instant at the start of the second specified
228
* by the {@code year}, {@code month}, {@code date},
229
* {@code hrs}, {@code min}, and {@code sec} arguments,
230
* in the local time zone.
231
*
232
* @param year the year minus 1900.
233
* @param month the month between 0-11.
234
* @param date the day of the month between 1-31.
235
* @param hrs the hours between 0-23.
236
* @param min the minutes between 0-59.
237
* @param sec the seconds between 0-59.
238
* @see java.util.Calendar
239
* @deprecated As of JDK version 1.1,
240
* replaced by {@code Calendar.set(year + 1900, month, date, hrs, min, sec)}
241
* or {@code GregorianCalendar(year + 1900, month, date, hrs, min, sec)}.
242
*/
243
@Deprecated
244
public Date(int year, int month, int date, int hrs, int min, int sec) {
245
int y = year + 1900;
246
// month is 0-based. So we have to normalize month to support Long.MAX_VALUE.
247
if (month >= 12) {
248
y += month / 12;
249
month %= 12;
250
} else if (month < 0) {
251
y += CalendarUtils.floorDivide(month, 12);
252
month = CalendarUtils.mod(month, 12);
253
}
254
BaseCalendar cal = getCalendarSystem(y);
255
cdate = (BaseCalendar.Date) cal.newCalendarDate(TimeZone.getDefaultRef());
256
cdate.setNormalizedDate(y, month + 1, date).setTimeOfDay(hrs, min, sec, 0);
257
getTimeImpl();
258
cdate = null;
259
}
260
261
/**
262
* Allocates a {@code Date} object and initializes it so that
263
* it represents the date and time indicated by the string
264
* {@code s}, which is interpreted as if by the
265
* {@link Date#parse} method.
266
*
267
* @param s a string representation of the date.
268
* @see java.text.DateFormat
269
* @see java.util.Date#parse(java.lang.String)
270
* @deprecated As of JDK version 1.1,
271
* replaced by {@code DateFormat.parse(String s)}.
272
*/
273
@Deprecated
274
public Date(String s) {
275
this(parse(s));
276
}
277
278
/**
279
* Return a copy of this object.
280
*/
281
public Object clone() {
282
Date d = null;
283
try {
284
d = (Date)super.clone();
285
if (cdate != null) {
286
d.cdate = (BaseCalendar.Date) cdate.clone();
287
}
288
} catch (CloneNotSupportedException e) {} // Won't happen
289
return d;
290
}
291
292
/**
293
* Determines the date and time based on the arguments. The
294
* arguments are interpreted as a year, month, day of the month,
295
* hour of the day, minute within the hour, and second within the
296
* minute, exactly as for the {@code Date} constructor with six
297
* arguments, except that the arguments are interpreted relative
298
* to UTC rather than to the local time zone. The time indicated is
299
* returned represented as the distance, measured in milliseconds,
300
* of that time from the epoch (00:00:00 GMT on January 1, 1970).
301
*
302
* @param year the year minus 1900.
303
* @param month the month between 0-11.
304
* @param date the day of the month between 1-31.
305
* @param hrs the hours between 0-23.
306
* @param min the minutes between 0-59.
307
* @param sec the seconds between 0-59.
308
* @return the number of milliseconds since January 1, 1970, 00:00:00 GMT for
309
* the date and time specified by the arguments.
310
* @see java.util.Calendar
311
* @deprecated As of JDK version 1.1,
312
* replaced by {@code Calendar.set(year + 1900, month, date, hrs, min, sec)}
313
* or {@code GregorianCalendar(year + 1900, month, date, hrs, min, sec)}, using a UTC
314
* {@code TimeZone}, followed by {@code Calendar.getTime().getTime()}.
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 {@code s} 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
* {@code IllegalArgumentException} 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 {@code s} is processed from left to right, looking for
357
* data of interest. Any material in {@code s} that is within the
358
* ASCII parenthesis characters {@code (} and {@code )} is ignored.
359
* Parentheses may be nested. Otherwise, the only characters permitted
360
* within {@code s} 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 {@code +} or {@code -} 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 {@code -} means a westward offset. Time zone offsets
374
* are always relative to UTC (Greenwich). Thus, for example,
375
* {@code -5} occurring in the string would mean "five hours west
376
* of Greenwich" and {@code +0430} would mean "four hours and
377
* thirty minutes east of Greenwich." It is permitted for the
378
* string to specify {@code GMT}, {@code UT}, or {@code UTC}
379
* redundantly-for example, {@code GMT-5} or {@code utc+0430}.
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 {@code 0}
403
* to {@code 11}), 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 {@code AM}, ignoring case, is ignored (but
413
* the parse fails if an hour has not been recognized or is less
414
* than {@code 1} or greater than {@code 12}).
415
* <li>A word that matches {@code PM}, ignoring case, adds {@code 12}
416
* to the hour (but the parse fails if an hour has not been
417
* recognized or is less than {@code 1} or greater than {@code 12}).
418
* <li>Any word that matches any prefix of {@code SUNDAY, MONDAY, TUESDAY,
419
* WEDNESDAY, THURSDAY, FRIDAY}, or {@code SATURDAY}, ignoring
420
* case, is ignored. For example, {@code sat, Friday, TUE}, and
421
* {@code Thurs} are ignored.
422
* <li>Otherwise, any word that matches any prefix of {@code JANUARY,
423
* FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, AUGUST, SEPTEMBER,
424
* OCTOBER, NOVEMBER}, or {@code DECEMBER}, ignoring case, and
425
* considering them in the order given here, is recognized as
426
* specifying a month and is converted to a number ({@code 0} to
427
* {@code 11}). For example, {@code aug, Sept, april}, and
428
* {@code NOV} are recognized as months. So is {@code Ma}, which
429
* is recognized as {@code MARCH}, not {@code MAY}.
430
* <li>Any word that matches {@code GMT, UT}, or {@code UTC}, ignoring
431
* case, is treated as referring to UTC.
432
* <li>Any word that matches {@code EST, CST, MST}, or {@code PST},
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 {@code EDT, CDT,
436
* MDT}, or {@code PDT}, 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)}.
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 static final 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 static final 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} 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}.
648
*/
649
@Deprecated
650
public int getYear() {
651
return normalize().getYear() - 1900;
652
}
653
654
/**
655
* Sets the year of this {@code Date} object to be the specified
656
* value plus 1900. This {@code Date} 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)}.
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 {@code Date} object.
677
* The value returned is between {@code 0} and {@code 11},
678
* with the value {@code 0} 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)}.
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
* {@code Date} 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)}.
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 {@code Date} object.
723
* The value returned is between {@code 1} and {@code 31}
724
* representing the day of the month that contains or begins with the
725
* instant in time represented by this {@code Date} 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)}.
732
*/
733
@Deprecated
734
public int getDate() {
735
return normalize().getDayOfMonth();
736
}
737
738
/**
739
* Sets the day of the month of this {@code Date} object to the
740
* specified value. This {@code Date} object is modified so that
741
* it represents a point in time within the specified day of the
742
* month, with the year, month, hour, minute, and second the same
743
* as before, as interpreted in the local time zone. If the date
744
* was April 30, for example, and the date is set to 31, then it
745
* will be treated as if it were on May 1, because April has only
746
* 30 days.
747
*
748
* @param date the day of the month value between 1-31.
749
* @see java.util.Calendar
750
* @deprecated As of JDK version 1.1,
751
* replaced by {@code Calendar.set(Calendar.DAY_OF_MONTH, int date)}.
752
*/
753
@Deprecated
754
public void setDate(int date) {
755
getCalendarDate().setDayOfMonth(date);
756
}
757
758
/**
759
* Returns the day of the week represented by this date. The
760
* returned value ({@code 0} = Sunday, {@code 1} = Monday,
761
* {@code 2} = Tuesday, {@code 3} = Wednesday, {@code 4} =
762
* Thursday, {@code 5} = Friday, {@code 6} = Saturday)
763
* represents the day of the week that contains or begins with
764
* the instant in time represented by this {@code Date} object,
765
* as interpreted in the local time zone.
766
*
767
* @return the day of the week represented by this date.
768
* @see java.util.Calendar
769
* @deprecated As of JDK version 1.1,
770
* replaced by {@code Calendar.get(Calendar.DAY_OF_WEEK)}.
771
*/
772
@Deprecated
773
public int getDay() {
774
return normalize().getDayOfWeek() - BaseCalendar.SUNDAY;
775
}
776
777
/**
778
* Returns the hour represented by this {@code Date} object. The
779
* returned value is a number ({@code 0} through {@code 23})
780
* representing the hour within the day that contains or begins
781
* with the instant in time represented by this {@code Date}
782
* object, as interpreted in the local time zone.
783
*
784
* @return the hour represented by this date.
785
* @see java.util.Calendar
786
* @deprecated As of JDK version 1.1,
787
* replaced by {@code Calendar.get(Calendar.HOUR_OF_DAY)}.
788
*/
789
@Deprecated
790
public int getHours() {
791
return normalize().getHours();
792
}
793
794
/**
795
* Sets the hour of this {@code Date} object to the specified value.
796
* This {@code Date} object is modified so that it represents a point
797
* in time within the specified hour of the day, with the year, month,
798
* date, minute, and second the same as before, as interpreted in the
799
* local time zone.
800
*
801
* @param hours the hour value.
802
* @see java.util.Calendar
803
* @deprecated As of JDK version 1.1,
804
* replaced by {@code Calendar.set(Calendar.HOUR_OF_DAY, int hours)}.
805
*/
806
@Deprecated
807
public void setHours(int hours) {
808
getCalendarDate().setHours(hours);
809
}
810
811
/**
812
* Returns the number of minutes past the hour represented by this date,
813
* as interpreted in the local time zone.
814
* The value returned is between {@code 0} and {@code 59}.
815
*
816
* @return the number of minutes past the hour represented by this date.
817
* @see java.util.Calendar
818
* @deprecated As of JDK version 1.1,
819
* replaced by {@code Calendar.get(Calendar.MINUTE)}.
820
*/
821
@Deprecated
822
public int getMinutes() {
823
return normalize().getMinutes();
824
}
825
826
/**
827
* Sets the minutes of this {@code Date} object to the specified value.
828
* This {@code Date} object is modified so that it represents a point
829
* in time within the specified minute of the hour, with the year, month,
830
* date, hour, and second the same as before, as interpreted in the
831
* local time zone.
832
*
833
* @param minutes the value of the minutes.
834
* @see java.util.Calendar
835
* @deprecated As of JDK version 1.1,
836
* replaced by {@code Calendar.set(Calendar.MINUTE, int minutes)}.
837
*/
838
@Deprecated
839
public void setMinutes(int minutes) {
840
getCalendarDate().setMinutes(minutes);
841
}
842
843
/**
844
* Returns the number of seconds past the minute represented by this date.
845
* The value returned is between {@code 0} and {@code 61}. The
846
* values {@code 60} and {@code 61} can only occur on those
847
* Java Virtual Machines that take leap seconds into account.
848
*
849
* @return the number of seconds past the minute represented by this date.
850
* @see java.util.Calendar
851
* @deprecated As of JDK version 1.1,
852
* replaced by {@code Calendar.get(Calendar.SECOND)}.
853
*/
854
@Deprecated
855
public int getSeconds() {
856
return normalize().getSeconds();
857
}
858
859
/**
860
* Sets the seconds of this {@code Date} to the specified value.
861
* This {@code Date} object is modified so that it represents a
862
* point in time within the specified second of the minute, with
863
* the year, month, date, hour, and minute the same as before, as
864
* interpreted in the local time zone.
865
*
866
* @param seconds the seconds value.
867
* @see java.util.Calendar
868
* @deprecated As of JDK version 1.1,
869
* replaced by {@code Calendar.set(Calendar.SECOND, int seconds)}.
870
*/
871
@Deprecated
872
public void setSeconds(int seconds) {
873
getCalendarDate().setSeconds(seconds);
874
}
875
876
/**
877
* Returns the number of milliseconds since January 1, 1970, 00:00:00 GMT
878
* represented by this {@code Date} object.
879
*
880
* @return the number of milliseconds since January 1, 1970, 00:00:00 GMT
881
* represented by this date.
882
*/
883
public long getTime() {
884
return getTimeImpl();
885
}
886
887
private final long getTimeImpl() {
888
if (cdate != null && !cdate.isNormalized()) {
889
normalize();
890
}
891
return fastTime;
892
}
893
894
/**
895
* Sets this {@code Date} object to represent a point in time that is
896
* {@code time} milliseconds after January 1, 1970 00:00:00 GMT.
897
*
898
* @param time the number of milliseconds.
899
*/
900
public void setTime(long time) {
901
fastTime = time;
902
cdate = null;
903
}
904
905
/**
906
* Tests if this date is before the specified date.
907
*
908
* @param when a date.
909
* @return {@code true} if and only if the instant of time
910
* represented by this {@code Date} object is strictly
911
* earlier than the instant represented by {@code when};
912
* {@code false} otherwise.
913
* @throws NullPointerException if {@code when} is null.
914
*/
915
public boolean before(Date when) {
916
return getMillisOf(this) < getMillisOf(when);
917
}
918
919
/**
920
* Tests if this date is after the specified date.
921
*
922
* @param when a date.
923
* @return {@code true} if and only if the instant represented
924
* by this {@code Date} object is strictly later than the
925
* instant represented by {@code when};
926
* {@code false} otherwise.
927
* @throws NullPointerException if {@code when} is null.
928
*/
929
public boolean after(Date when) {
930
return getMillisOf(this) > getMillisOf(when);
931
}
932
933
/**
934
* Compares two dates for equality.
935
* The result is {@code true} if and only if the argument is
936
* not {@code null} and is a {@code Date} object that
937
* represents the same point in time, to the millisecond, as this object.
938
* <p>
939
* Thus, two {@code Date} objects are equal if and only if the
940
* {@code getTime} method returns the same {@code long}
941
* value for both.
942
*
943
* @param obj the object to compare with.
944
* @return {@code true} if the objects are the same;
945
* {@code false} otherwise.
946
* @see java.util.Date#getTime()
947
*/
948
public boolean equals(Object obj) {
949
return obj instanceof Date && getTime() == ((Date) obj).getTime();
950
}
951
952
/**
953
* Returns the millisecond value of this {@code Date} object
954
* without affecting its internal state.
955
*/
956
static final long getMillisOf(Date date) {
957
if (date.getClass() != Date.class) {
958
return date.getTime();
959
}
960
if (date.cdate == null || date.cdate.isNormalized()) {
961
return date.fastTime;
962
}
963
BaseCalendar.Date d = (BaseCalendar.Date) date.cdate.clone();
964
return gcal.getTime(d);
965
}
966
967
/**
968
* Compares two Dates for ordering.
969
*
970
* @param anotherDate the {@code Date} to be compared.
971
* @return the value {@code 0} if the argument Date is equal to
972
* this Date; a value less than {@code 0} if this Date
973
* is before the Date argument; and a value greater than
974
* {@code 0} if this Date is after the Date argument.
975
* @since 1.2
976
* @throws NullPointerException if {@code anotherDate} is null.
977
*/
978
public int compareTo(Date anotherDate) {
979
long thisTime = getMillisOf(this);
980
long anotherTime = getMillisOf(anotherDate);
981
return (thisTime<anotherTime ? -1 : (thisTime==anotherTime ? 0 : 1));
982
}
983
984
/**
985
* Returns a hash code value for this object. The result is the
986
* exclusive OR of the two halves of the primitive {@code long}
987
* value returned by the {@link Date#getTime}
988
* method. That is, the hash code is the value of the expression:
989
* <blockquote><pre>{@code
990
* (int)(this.getTime()^(this.getTime() >>> 32))
991
* }</pre></blockquote>
992
*
993
* @return a hash code value for this object.
994
*/
995
public int hashCode() {
996
long ht = this.getTime();
997
return (int) ht ^ (int) (ht >> 32);
998
}
999
1000
/**
1001
* Converts this {@code Date} object to a {@code String}
1002
* of the form:
1003
* <blockquote><pre>
1004
* dow mon dd hh:mm:ss zzz yyyy</pre></blockquote>
1005
* where:<ul>
1006
* <li>{@code dow} is the day of the week ({@code Sun, Mon, Tue, Wed,
1007
* Thu, Fri, Sat}).
1008
* <li>{@code mon} is the month ({@code Jan, Feb, Mar, Apr, May, Jun,
1009
* Jul, Aug, Sep, Oct, Nov, Dec}).
1010
* <li>{@code dd} is the day of the month ({@code 01} through
1011
* {@code 31}), as two decimal digits.
1012
* <li>{@code hh} is the hour of the day ({@code 00} through
1013
* {@code 23}), as two decimal digits.
1014
* <li>{@code mm} is the minute within the hour ({@code 00} through
1015
* {@code 59}), as two decimal digits.
1016
* <li>{@code ss} is the second within the minute ({@code 00} through
1017
* {@code 61}, as two decimal digits.
1018
* <li>{@code zzz} is the time zone (and may reflect daylight saving
1019
* time). Standard time zone abbreviations include those
1020
* recognized by the method {@code parse}. If time zone
1021
* information is not available, then {@code zzz} is empty -
1022
* that is, it consists of no characters at all.
1023
* <li>{@code yyyy} is the year, as four decimal digits.
1024
* </ul>
1025
*
1026
* @return a string representation of this date.
1027
* @see java.util.Date#toLocaleString()
1028
* @see java.util.Date#toGMTString()
1029
*/
1030
public String toString() {
1031
// "EEE MMM dd HH:mm:ss zzz yyyy";
1032
BaseCalendar.Date date = normalize();
1033
StringBuilder sb = new StringBuilder(28);
1034
int index = date.getDayOfWeek();
1035
if (index == BaseCalendar.SUNDAY) {
1036
index = 8;
1037
}
1038
convertToAbbr(sb, wtb[index]).append(' '); // EEE
1039
convertToAbbr(sb, wtb[date.getMonth() - 1 + 2 + 7]).append(' '); // MMM
1040
CalendarUtils.sprintf0d(sb, date.getDayOfMonth(), 2).append(' '); // dd
1041
1042
CalendarUtils.sprintf0d(sb, date.getHours(), 2).append(':'); // HH
1043
CalendarUtils.sprintf0d(sb, date.getMinutes(), 2).append(':'); // mm
1044
CalendarUtils.sprintf0d(sb, date.getSeconds(), 2).append(' '); // ss
1045
TimeZone zi = date.getZone();
1046
if (zi != null) {
1047
sb.append(zi.getDisplayName(date.isDaylightTime(), TimeZone.SHORT, Locale.US)); // zzz
1048
} else {
1049
sb.append("GMT");
1050
}
1051
sb.append(' ').append(date.getYear()); // yyyy
1052
return sb.toString();
1053
}
1054
1055
/**
1056
* Converts the given name to its 3-letter abbreviation (e.g.,
1057
* "monday" -> "Mon") and stored the abbreviation in the given
1058
* {@code StringBuilder}.
1059
*/
1060
private static final StringBuilder convertToAbbr(StringBuilder sb, String name) {
1061
sb.append(Character.toUpperCase(name.charAt(0)));
1062
sb.append(name.charAt(1)).append(name.charAt(2));
1063
return sb;
1064
}
1065
1066
/**
1067
* Creates a string representation of this {@code Date} object in an
1068
* implementation-dependent form. The intent is that the form should
1069
* be familiar to the user of the Java application, wherever it may
1070
* happen to be running. The intent is comparable to that of the
1071
* "{@code %c}" format supported by the {@code strftime()}
1072
* function of ISO&nbsp;C.
1073
*
1074
* @return a string representation of this date, using the locale
1075
* conventions.
1076
* @see java.text.DateFormat
1077
* @see java.util.Date#toString()
1078
* @see java.util.Date#toGMTString()
1079
* @deprecated As of JDK version 1.1,
1080
* replaced by {@code DateFormat.format(Date date)}.
1081
*/
1082
@Deprecated
1083
public String toLocaleString() {
1084
DateFormat formatter = DateFormat.getDateTimeInstance();
1085
return formatter.format(this);
1086
}
1087
1088
/**
1089
* Creates a string representation of this {@code Date} object of
1090
* the form:
1091
* <blockquote><pre>
1092
* d mon yyyy hh:mm:ss GMT</pre></blockquote>
1093
* where:<ul>
1094
* <li><i>d</i> is the day of the month ({@code 1} through {@code 31}),
1095
* as one or two decimal digits.
1096
* <li><i>mon</i> is the month ({@code Jan, Feb, Mar, Apr, May, Jun, Jul,
1097
* Aug, Sep, Oct, Nov, Dec}).
1098
* <li><i>yyyy</i> is the year, as four decimal digits.
1099
* <li><i>hh</i> is the hour of the day ({@code 00} through {@code 23}),
1100
* as two decimal digits.
1101
* <li><i>mm</i> is the minute within the hour ({@code 00} through
1102
* {@code 59}), as two decimal digits.
1103
* <li><i>ss</i> is the second within the minute ({@code 00} through
1104
* {@code 61}), as two decimal digits.
1105
* <li><i>GMT</i> is exactly the ASCII letters "{@code GMT}" to indicate
1106
* Greenwich Mean Time.
1107
* </ul><p>
1108
* The result does not depend on the local time zone.
1109
*
1110
* @return a string representation of this date, using the Internet GMT
1111
* conventions.
1112
* @see java.text.DateFormat
1113
* @see java.util.Date#toString()
1114
* @see java.util.Date#toLocaleString()
1115
* @deprecated As of JDK version 1.1,
1116
* replaced by {@code DateFormat.format(Date date)}, using a
1117
* GMT {@code TimeZone}.
1118
*/
1119
@Deprecated
1120
public String toGMTString() {
1121
// d MMM yyyy HH:mm:ss 'GMT'
1122
long t = getTime();
1123
BaseCalendar cal = getCalendarSystem(t);
1124
BaseCalendar.Date date =
1125
(BaseCalendar.Date) cal.getCalendarDate(getTime(), (TimeZone)null);
1126
StringBuilder sb = new StringBuilder(32);
1127
CalendarUtils.sprintf0d(sb, date.getDayOfMonth(), 1).append(' '); // d
1128
convertToAbbr(sb, wtb[date.getMonth() - 1 + 2 + 7]).append(' '); // MMM
1129
sb.append(date.getYear()).append(' '); // yyyy
1130
CalendarUtils.sprintf0d(sb, date.getHours(), 2).append(':'); // HH
1131
CalendarUtils.sprintf0d(sb, date.getMinutes(), 2).append(':'); // mm
1132
CalendarUtils.sprintf0d(sb, date.getSeconds(), 2); // ss
1133
sb.append(" GMT"); // ' GMT'
1134
return sb.toString();
1135
}
1136
1137
/**
1138
* Returns the offset, measured in minutes, for the local time zone
1139
* relative to UTC that is appropriate for the time represented by
1140
* this {@code Date} object.
1141
* <p>
1142
* For example, in Massachusetts, five time zones west of Greenwich:
1143
* <blockquote><pre>
1144
* new Date(96, 1, 14).getTimezoneOffset() returns 300</pre></blockquote>
1145
* because on February 14, 1996, standard time (Eastern Standard Time)
1146
* is in use, which is offset five hours from UTC; but:
1147
* <blockquote><pre>
1148
* new Date(96, 5, 1).getTimezoneOffset() returns 240</pre></blockquote>
1149
* because on June 1, 1996, daylight saving time (Eastern Daylight Time)
1150
* is in use, which is offset only four hours from UTC.<p>
1151
* This method produces the same result as if it computed:
1152
* <blockquote><pre>
1153
* (this.getTime() - UTC(this.getYear(),
1154
* this.getMonth(),
1155
* this.getDate(),
1156
* this.getHours(),
1157
* this.getMinutes(),
1158
* this.getSeconds())) / (60 * 1000)
1159
* </pre></blockquote>
1160
*
1161
* @return the time-zone offset, in minutes, for the current time zone.
1162
* @see java.util.Calendar#ZONE_OFFSET
1163
* @see java.util.Calendar#DST_OFFSET
1164
* @see java.util.TimeZone#getDefault
1165
* @deprecated As of JDK version 1.1,
1166
* replaced by {@code -(Calendar.get(Calendar.ZONE_OFFSET) +
1167
* Calendar.get(Calendar.DST_OFFSET)) / (60 * 1000)}.
1168
*/
1169
@Deprecated
1170
public int getTimezoneOffset() {
1171
int zoneOffset;
1172
if (cdate == null) {
1173
TimeZone tz = TimeZone.getDefaultRef();
1174
if (tz instanceof ZoneInfo) {
1175
zoneOffset = ((ZoneInfo)tz).getOffsets(fastTime, null);
1176
} else {
1177
zoneOffset = tz.getOffset(fastTime);
1178
}
1179
} else {
1180
normalize();
1181
zoneOffset = cdate.getZoneOffset();
1182
}
1183
return -zoneOffset/60000; // convert to minutes
1184
}
1185
1186
private final BaseCalendar.Date getCalendarDate() {
1187
if (cdate == null) {
1188
BaseCalendar cal = getCalendarSystem(fastTime);
1189
cdate = (BaseCalendar.Date) cal.getCalendarDate(fastTime,
1190
TimeZone.getDefaultRef());
1191
}
1192
return cdate;
1193
}
1194
1195
private final BaseCalendar.Date normalize() {
1196
if (cdate == null) {
1197
BaseCalendar cal = getCalendarSystem(fastTime);
1198
cdate = (BaseCalendar.Date) cal.getCalendarDate(fastTime,
1199
TimeZone.getDefaultRef());
1200
return cdate;
1201
}
1202
1203
// Normalize cdate with the TimeZone in cdate first. This is
1204
// required for the compatible behavior.
1205
if (!cdate.isNormalized()) {
1206
cdate = normalize(cdate);
1207
}
1208
1209
// If the default TimeZone has changed, then recalculate the
1210
// fields with the new TimeZone.
1211
TimeZone tz = TimeZone.getDefaultRef();
1212
if (tz != cdate.getZone()) {
1213
cdate.setZone(tz);
1214
CalendarSystem cal = getCalendarSystem(cdate);
1215
cal.getCalendarDate(fastTime, cdate);
1216
}
1217
return cdate;
1218
}
1219
1220
// fastTime and the returned data are in sync upon return.
1221
private final BaseCalendar.Date normalize(BaseCalendar.Date date) {
1222
int y = date.getNormalizedYear();
1223
int m = date.getMonth();
1224
int d = date.getDayOfMonth();
1225
int hh = date.getHours();
1226
int mm = date.getMinutes();
1227
int ss = date.getSeconds();
1228
int ms = date.getMillis();
1229
TimeZone tz = date.getZone();
1230
1231
// If the specified year can't be handled using a long value
1232
// in milliseconds, GregorianCalendar is used for full
1233
// compatibility with underflow and overflow. This is required
1234
// by some JCK tests. The limits are based max year values -
1235
// years that can be represented by max values of d, hh, mm,
1236
// ss and ms. Also, let GregorianCalendar handle the default
1237
// cutover year so that we don't need to worry about the
1238
// transition here.
1239
if (y == 1582 || y > 280000000 || y < -280000000) {
1240
if (tz == null) {
1241
tz = TimeZone.getTimeZone("GMT");
1242
}
1243
GregorianCalendar gc = new GregorianCalendar(tz);
1244
gc.clear();
1245
gc.set(GregorianCalendar.MILLISECOND, ms);
1246
gc.set(y, m-1, d, hh, mm, ss);
1247
fastTime = gc.getTimeInMillis();
1248
BaseCalendar cal = getCalendarSystem(fastTime);
1249
date = (BaseCalendar.Date) cal.getCalendarDate(fastTime, tz);
1250
return date;
1251
}
1252
1253
BaseCalendar cal = getCalendarSystem(y);
1254
if (cal != getCalendarSystem(date)) {
1255
date = (BaseCalendar.Date) cal.newCalendarDate(tz);
1256
date.setNormalizedDate(y, m, d).setTimeOfDay(hh, mm, ss, ms);
1257
}
1258
// Perform the GregorianCalendar-style normalization.
1259
fastTime = cal.getTime(date);
1260
1261
// In case the normalized date requires the other calendar
1262
// system, we need to recalculate it using the other one.
1263
BaseCalendar ncal = getCalendarSystem(fastTime);
1264
if (ncal != cal) {
1265
date = (BaseCalendar.Date) ncal.newCalendarDate(tz);
1266
date.setNormalizedDate(y, m, d).setTimeOfDay(hh, mm, ss, ms);
1267
fastTime = ncal.getTime(date);
1268
}
1269
return date;
1270
}
1271
1272
/**
1273
* Returns the Gregorian or Julian calendar system to use with the
1274
* given date. Use Gregorian from October 15, 1582.
1275
*
1276
* @param year normalized calendar year (not -1900)
1277
* @return the CalendarSystem to use for the specified date
1278
*/
1279
private static final BaseCalendar getCalendarSystem(int year) {
1280
if (year >= 1582) {
1281
return gcal;
1282
}
1283
return getJulianCalendar();
1284
}
1285
1286
private static final BaseCalendar getCalendarSystem(long utc) {
1287
// Quickly check if the time stamp given by `utc' is the Epoch
1288
// or later. If it's before 1970, we convert the cutover to
1289
// local time to compare.
1290
if (utc >= 0
1291
|| utc >= GregorianCalendar.DEFAULT_GREGORIAN_CUTOVER
1292
- TimeZone.getDefaultRef().getOffset(utc)) {
1293
return gcal;
1294
}
1295
return getJulianCalendar();
1296
}
1297
1298
private static final BaseCalendar getCalendarSystem(BaseCalendar.Date cdate) {
1299
if (jcal == null) {
1300
return gcal;
1301
}
1302
if (cdate.getEra() != null) {
1303
return jcal;
1304
}
1305
return gcal;
1306
}
1307
1308
private static final synchronized BaseCalendar getJulianCalendar() {
1309
if (jcal == null) {
1310
jcal = (BaseCalendar) CalendarSystem.forName("julian");
1311
}
1312
return jcal;
1313
}
1314
1315
/**
1316
* Save the state of this object to a stream (i.e., serialize it).
1317
*
1318
* @serialData The value returned by {@code getTime()}
1319
* is emitted (long). This represents the offset from
1320
* January 1, 1970, 00:00:00 GMT in milliseconds.
1321
*/
1322
@java.io.Serial
1323
private void writeObject(ObjectOutputStream s)
1324
throws IOException
1325
{
1326
s.defaultWriteObject();
1327
s.writeLong(getTimeImpl());
1328
}
1329
1330
/**
1331
* Reconstitute this object from a stream (i.e., deserialize it).
1332
*/
1333
@java.io.Serial
1334
private void readObject(ObjectInputStream s)
1335
throws IOException, ClassNotFoundException
1336
{
1337
s.defaultReadObject();
1338
fastTime = s.readLong();
1339
}
1340
1341
/**
1342
* Obtains an instance of {@code Date} from an {@code Instant} object.
1343
* <p>
1344
* {@code Instant} uses a precision of nanoseconds, whereas {@code Date}
1345
* uses a precision of milliseconds. The conversion will truncate any
1346
* excess precision information as though the amount in nanoseconds was
1347
* subject to integer division by one million.
1348
* <p>
1349
* {@code Instant} can store points on the time-line further in the future
1350
* and further in the past than {@code Date}. In this scenario, this method
1351
* will throw an exception.
1352
*
1353
* @param instant the instant to convert
1354
* @return a {@code Date} representing the same point on the time-line as
1355
* the provided instant
1356
* @throws NullPointerException if {@code instant} is null.
1357
* @throws IllegalArgumentException if the instant is too large to
1358
* represent as a {@code Date}
1359
* @since 1.8
1360
*/
1361
public static Date from(Instant instant) {
1362
try {
1363
return new Date(instant.toEpochMilli());
1364
} catch (ArithmeticException ex) {
1365
throw new IllegalArgumentException(ex);
1366
}
1367
}
1368
1369
/**
1370
* Converts this {@code Date} object to an {@code Instant}.
1371
* <p>
1372
* The conversion creates an {@code Instant} that represents the same
1373
* point on the time-line as this {@code Date}.
1374
*
1375
* @return an instant representing the same point on the time-line as
1376
* this {@code Date} object
1377
* @since 1.8
1378
*/
1379
public Instant toInstant() {
1380
return Instant.ofEpochMilli(getTime());
1381
}
1382
}
1383
1384