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/time/LocalDate.java
38829 views
1
/*
2
* Copyright (c) 2012, 2015, 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
/*
27
* This file is available under and governed by the GNU General Public
28
* License version 2 only, as published by the Free Software Foundation.
29
* However, the following notice accompanied the original version of this
30
* file:
31
*
32
* Copyright (c) 2007-2012, Stephen Colebourne & Michael Nascimento Santos
33
*
34
* All rights reserved.
35
*
36
* Redistribution and use in source and binary forms, with or without
37
* modification, are permitted provided that the following conditions are met:
38
*
39
* * Redistributions of source code must retain the above copyright notice,
40
* this list of conditions and the following disclaimer.
41
*
42
* * Redistributions in binary form must reproduce the above copyright notice,
43
* this list of conditions and the following disclaimer in the documentation
44
* and/or other materials provided with the distribution.
45
*
46
* * Neither the name of JSR-310 nor the names of its contributors
47
* may be used to endorse or promote products derived from this software
48
* without specific prior written permission.
49
*
50
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
54
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
55
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
56
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
57
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
58
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
59
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
60
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61
*/
62
package java.time;
63
64
import static java.time.LocalTime.SECONDS_PER_DAY;
65
import static java.time.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH;
66
import static java.time.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR;
67
import static java.time.temporal.ChronoField.ALIGNED_WEEK_OF_MONTH;
68
import static java.time.temporal.ChronoField.ALIGNED_WEEK_OF_YEAR;
69
import static java.time.temporal.ChronoField.DAY_OF_MONTH;
70
import static java.time.temporal.ChronoField.DAY_OF_YEAR;
71
import static java.time.temporal.ChronoField.EPOCH_DAY;
72
import static java.time.temporal.ChronoField.ERA;
73
import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
74
import static java.time.temporal.ChronoField.PROLEPTIC_MONTH;
75
import static java.time.temporal.ChronoField.YEAR;
76
77
import java.io.DataInput;
78
import java.io.DataOutput;
79
import java.io.IOException;
80
import java.io.InvalidObjectException;
81
import java.io.ObjectInputStream;
82
import java.io.Serializable;
83
import java.time.chrono.ChronoLocalDate;
84
import java.time.chrono.Era;
85
import java.time.chrono.IsoChronology;
86
import java.time.format.DateTimeFormatter;
87
import java.time.format.DateTimeParseException;
88
import java.time.temporal.ChronoField;
89
import java.time.temporal.ChronoUnit;
90
import java.time.temporal.Temporal;
91
import java.time.temporal.TemporalAccessor;
92
import java.time.temporal.TemporalAdjuster;
93
import java.time.temporal.TemporalAmount;
94
import java.time.temporal.TemporalField;
95
import java.time.temporal.TemporalQueries;
96
import java.time.temporal.TemporalQuery;
97
import java.time.temporal.TemporalUnit;
98
import java.time.temporal.UnsupportedTemporalTypeException;
99
import java.time.temporal.ValueRange;
100
import java.time.zone.ZoneOffsetTransition;
101
import java.time.zone.ZoneRules;
102
import java.util.Objects;
103
104
/**
105
* A date without a time-zone in the ISO-8601 calendar system,
106
* such as {@code 2007-12-03}.
107
* <p>
108
* {@code LocalDate} is an immutable date-time object that represents a date,
109
* often viewed as year-month-day. Other date fields, such as day-of-year,
110
* day-of-week and week-of-year, can also be accessed.
111
* For example, the value "2nd October 2007" can be stored in a {@code LocalDate}.
112
* <p>
113
* This class does not store or represent a time or time-zone.
114
* Instead, it is a description of the date, as used for birthdays.
115
* It cannot represent an instant on the time-line without additional information
116
* such as an offset or time-zone.
117
* <p>
118
* The ISO-8601 calendar system is the modern civil calendar system used today
119
* in most of the world. It is equivalent to the proleptic Gregorian calendar
120
* system, in which today's rules for leap years are applied for all time.
121
* For most applications written today, the ISO-8601 rules are entirely suitable.
122
* However, any application that makes use of historical dates, and requires them
123
* to be accurate will find the ISO-8601 approach unsuitable.
124
*
125
* <p>
126
* This is a <a href="{@docRoot}/java/lang/doc-files/ValueBased.html">value-based</a>
127
* class; use of identity-sensitive operations (including reference equality
128
* ({@code ==}), identity hash code, or synchronization) on instances of
129
* {@code LocalDate} may have unpredictable results and should be avoided.
130
* The {@code equals} method should be used for comparisons.
131
*
132
* @implSpec
133
* This class is immutable and thread-safe.
134
*
135
* @since 1.8
136
*/
137
public final class LocalDate
138
implements Temporal, TemporalAdjuster, ChronoLocalDate, Serializable {
139
140
/**
141
* The minimum supported {@code LocalDate}, '-999999999-01-01'.
142
* This could be used by an application as a "far past" date.
143
*/
144
public static final LocalDate MIN = LocalDate.of(Year.MIN_VALUE, 1, 1);
145
/**
146
* The maximum supported {@code LocalDate}, '+999999999-12-31'.
147
* This could be used by an application as a "far future" date.
148
*/
149
public static final LocalDate MAX = LocalDate.of(Year.MAX_VALUE, 12, 31);
150
151
/**
152
* Serialization version.
153
*/
154
private static final long serialVersionUID = 2942565459149668126L;
155
/**
156
* The number of days in a 400 year cycle.
157
*/
158
private static final int DAYS_PER_CYCLE = 146097;
159
/**
160
* The number of days from year zero to year 1970.
161
* There are five 400 year cycles from year zero to 2000.
162
* There are 7 leap years from 1970 to 2000.
163
*/
164
static final long DAYS_0000_TO_1970 = (DAYS_PER_CYCLE * 5L) - (30L * 365L + 7L);
165
166
/**
167
* The year.
168
*/
169
private final int year;
170
/**
171
* The month-of-year.
172
*/
173
private final short month;
174
/**
175
* The day-of-month.
176
*/
177
private final short day;
178
179
//-----------------------------------------------------------------------
180
/**
181
* Obtains the current date from the system clock in the default time-zone.
182
* <p>
183
* This will query the {@link Clock#systemDefaultZone() system clock} in the default
184
* time-zone to obtain the current date.
185
* <p>
186
* Using this method will prevent the ability to use an alternate clock for testing
187
* because the clock is hard-coded.
188
*
189
* @return the current date using the system clock and default time-zone, not null
190
*/
191
public static LocalDate now() {
192
return now(Clock.systemDefaultZone());
193
}
194
195
/**
196
* Obtains the current date from the system clock in the specified time-zone.
197
* <p>
198
* This will query the {@link Clock#system(ZoneId) system clock} to obtain the current date.
199
* Specifying the time-zone avoids dependence on the default time-zone.
200
* <p>
201
* Using this method will prevent the ability to use an alternate clock for testing
202
* because the clock is hard-coded.
203
*
204
* @param zone the zone ID to use, not null
205
* @return the current date using the system clock, not null
206
*/
207
public static LocalDate now(ZoneId zone) {
208
return now(Clock.system(zone));
209
}
210
211
/**
212
* Obtains the current date from the specified clock.
213
* <p>
214
* This will query the specified clock to obtain the current date - today.
215
* Using this method allows the use of an alternate clock for testing.
216
* The alternate clock may be introduced using {@link Clock dependency injection}.
217
*
218
* @param clock the clock to use, not null
219
* @return the current date, not null
220
*/
221
public static LocalDate now(Clock clock) {
222
Objects.requireNonNull(clock, "clock");
223
// inline to avoid creating object and Instant checks
224
final Instant now = clock.instant(); // called once
225
ZoneOffset offset = clock.getZone().getRules().getOffset(now);
226
long epochSec = now.getEpochSecond() + offset.getTotalSeconds(); // overflow caught later
227
long epochDay = Math.floorDiv(epochSec, SECONDS_PER_DAY);
228
return LocalDate.ofEpochDay(epochDay);
229
}
230
231
//-----------------------------------------------------------------------
232
/**
233
* Obtains an instance of {@code LocalDate} from a year, month and day.
234
* <p>
235
* This returns a {@code LocalDate} with the specified year, month and day-of-month.
236
* The day must be valid for the year and month, otherwise an exception will be thrown.
237
*
238
* @param year the year to represent, from MIN_YEAR to MAX_YEAR
239
* @param month the month-of-year to represent, not null
240
* @param dayOfMonth the day-of-month to represent, from 1 to 31
241
* @return the local date, not null
242
* @throws DateTimeException if the value of any field is out of range,
243
* or if the day-of-month is invalid for the month-year
244
*/
245
public static LocalDate of(int year, Month month, int dayOfMonth) {
246
YEAR.checkValidValue(year);
247
Objects.requireNonNull(month, "month");
248
DAY_OF_MONTH.checkValidValue(dayOfMonth);
249
return create(year, month.getValue(), dayOfMonth);
250
}
251
252
/**
253
* Obtains an instance of {@code LocalDate} from a year, month and day.
254
* <p>
255
* This returns a {@code LocalDate} with the specified year, month and day-of-month.
256
* The day must be valid for the year and month, otherwise an exception will be thrown.
257
*
258
* @param year the year to represent, from MIN_YEAR to MAX_YEAR
259
* @param month the month-of-year to represent, from 1 (January) to 12 (December)
260
* @param dayOfMonth the day-of-month to represent, from 1 to 31
261
* @return the local date, not null
262
* @throws DateTimeException if the value of any field is out of range,
263
* or if the day-of-month is invalid for the month-year
264
*/
265
public static LocalDate of(int year, int month, int dayOfMonth) {
266
YEAR.checkValidValue(year);
267
MONTH_OF_YEAR.checkValidValue(month);
268
DAY_OF_MONTH.checkValidValue(dayOfMonth);
269
return create(year, month, dayOfMonth);
270
}
271
272
//-----------------------------------------------------------------------
273
/**
274
* Obtains an instance of {@code LocalDate} from a year and day-of-year.
275
* <p>
276
* This returns a {@code LocalDate} with the specified year and day-of-year.
277
* The day-of-year must be valid for the year, otherwise an exception will be thrown.
278
*
279
* @param year the year to represent, from MIN_YEAR to MAX_YEAR
280
* @param dayOfYear the day-of-year to represent, from 1 to 366
281
* @return the local date, not null
282
* @throws DateTimeException if the value of any field is out of range,
283
* or if the day-of-year is invalid for the year
284
*/
285
public static LocalDate ofYearDay(int year, int dayOfYear) {
286
YEAR.checkValidValue(year);
287
DAY_OF_YEAR.checkValidValue(dayOfYear);
288
boolean leap = IsoChronology.INSTANCE.isLeapYear(year);
289
if (dayOfYear == 366 && leap == false) {
290
throw new DateTimeException("Invalid date 'DayOfYear 366' as '" + year + "' is not a leap year");
291
}
292
Month moy = Month.of((dayOfYear - 1) / 31 + 1);
293
int monthEnd = moy.firstDayOfYear(leap) + moy.length(leap) - 1;
294
if (dayOfYear > monthEnd) {
295
moy = moy.plus(1);
296
}
297
int dom = dayOfYear - moy.firstDayOfYear(leap) + 1;
298
return new LocalDate(year, moy.getValue(), dom);
299
}
300
301
//-----------------------------------------------------------------------
302
/**
303
* Obtains an instance of {@code LocalDate} from the epoch day count.
304
* <p>
305
* This returns a {@code LocalDate} with the specified epoch-day.
306
* The {@link ChronoField#EPOCH_DAY EPOCH_DAY} is a simple incrementing count
307
* of days where day 0 is 1970-01-01. Negative numbers represent earlier days.
308
*
309
* @param epochDay the Epoch Day to convert, based on the epoch 1970-01-01
310
* @return the local date, not null
311
* @throws DateTimeException if the epoch day exceeds the supported date range
312
*/
313
public static LocalDate ofEpochDay(long epochDay) {
314
long zeroDay = epochDay + DAYS_0000_TO_1970;
315
// find the march-based year
316
zeroDay -= 60; // adjust to 0000-03-01 so leap day is at end of four year cycle
317
long adjust = 0;
318
if (zeroDay < 0) {
319
// adjust negative years to positive for calculation
320
long adjustCycles = (zeroDay + 1) / DAYS_PER_CYCLE - 1;
321
adjust = adjustCycles * 400;
322
zeroDay += -adjustCycles * DAYS_PER_CYCLE;
323
}
324
long yearEst = (400 * zeroDay + 591) / DAYS_PER_CYCLE;
325
long doyEst = zeroDay - (365 * yearEst + yearEst / 4 - yearEst / 100 + yearEst / 400);
326
if (doyEst < 0) {
327
// fix estimate
328
yearEst--;
329
doyEst = zeroDay - (365 * yearEst + yearEst / 4 - yearEst / 100 + yearEst / 400);
330
}
331
yearEst += adjust; // reset any negative year
332
int marchDoy0 = (int) doyEst;
333
334
// convert march-based values back to january-based
335
int marchMonth0 = (marchDoy0 * 5 + 2) / 153;
336
int month = (marchMonth0 + 2) % 12 + 1;
337
int dom = marchDoy0 - (marchMonth0 * 306 + 5) / 10 + 1;
338
yearEst += marchMonth0 / 10;
339
340
// check year now we are certain it is correct
341
int year = YEAR.checkValidIntValue(yearEst);
342
return new LocalDate(year, month, dom);
343
}
344
345
//-----------------------------------------------------------------------
346
/**
347
* Obtains an instance of {@code LocalDate} from a temporal object.
348
* <p>
349
* This obtains a local date based on the specified temporal.
350
* A {@code TemporalAccessor} represents an arbitrary set of date and time information,
351
* which this factory converts to an instance of {@code LocalDate}.
352
* <p>
353
* The conversion uses the {@link TemporalQueries#localDate()} query, which relies
354
* on extracting the {@link ChronoField#EPOCH_DAY EPOCH_DAY} field.
355
* <p>
356
* This method matches the signature of the functional interface {@link TemporalQuery}
357
* allowing it to be used as a query via method reference, {@code LocalDate::from}.
358
*
359
* @param temporal the temporal object to convert, not null
360
* @return the local date, not null
361
* @throws DateTimeException if unable to convert to a {@code LocalDate}
362
*/
363
public static LocalDate from(TemporalAccessor temporal) {
364
Objects.requireNonNull(temporal, "temporal");
365
LocalDate date = temporal.query(TemporalQueries.localDate());
366
if (date == null) {
367
throw new DateTimeException("Unable to obtain LocalDate from TemporalAccessor: " +
368
temporal + " of type " + temporal.getClass().getName());
369
}
370
return date;
371
}
372
373
//-----------------------------------------------------------------------
374
/**
375
* Obtains an instance of {@code LocalDate} from a text string such as {@code 2007-12-03}.
376
* <p>
377
* The string must represent a valid date and is parsed using
378
* {@link java.time.format.DateTimeFormatter#ISO_LOCAL_DATE}.
379
*
380
* @param text the text to parse such as "2007-12-03", not null
381
* @return the parsed local date, not null
382
* @throws DateTimeParseException if the text cannot be parsed
383
*/
384
public static LocalDate parse(CharSequence text) {
385
return parse(text, DateTimeFormatter.ISO_LOCAL_DATE);
386
}
387
388
/**
389
* Obtains an instance of {@code LocalDate} from a text string using a specific formatter.
390
* <p>
391
* The text is parsed using the formatter, returning a date.
392
*
393
* @param text the text to parse, not null
394
* @param formatter the formatter to use, not null
395
* @return the parsed local date, not null
396
* @throws DateTimeParseException if the text cannot be parsed
397
*/
398
public static LocalDate parse(CharSequence text, DateTimeFormatter formatter) {
399
Objects.requireNonNull(formatter, "formatter");
400
return formatter.parse(text, LocalDate::from);
401
}
402
403
//-----------------------------------------------------------------------
404
/**
405
* Creates a local date from the year, month and day fields.
406
*
407
* @param year the year to represent, validated from MIN_YEAR to MAX_YEAR
408
* @param month the month-of-year to represent, from 1 to 12, validated
409
* @param dayOfMonth the day-of-month to represent, validated from 1 to 31
410
* @return the local date, not null
411
* @throws DateTimeException if the day-of-month is invalid for the month-year
412
*/
413
private static LocalDate create(int year, int month, int dayOfMonth) {
414
if (dayOfMonth > 28) {
415
int dom = 31;
416
switch (month) {
417
case 2:
418
dom = (IsoChronology.INSTANCE.isLeapYear(year) ? 29 : 28);
419
break;
420
case 4:
421
case 6:
422
case 9:
423
case 11:
424
dom = 30;
425
break;
426
}
427
if (dayOfMonth > dom) {
428
if (dayOfMonth == 29) {
429
throw new DateTimeException("Invalid date 'February 29' as '" + year + "' is not a leap year");
430
} else {
431
throw new DateTimeException("Invalid date '" + Month.of(month).name() + " " + dayOfMonth + "'");
432
}
433
}
434
}
435
return new LocalDate(year, month, dayOfMonth);
436
}
437
438
/**
439
* Resolves the date, resolving days past the end of month.
440
*
441
* @param year the year to represent, validated from MIN_YEAR to MAX_YEAR
442
* @param month the month-of-year to represent, validated from 1 to 12
443
* @param day the day-of-month to represent, validated from 1 to 31
444
* @return the resolved date, not null
445
*/
446
private static LocalDate resolvePreviousValid(int year, int month, int day) {
447
switch (month) {
448
case 2:
449
day = Math.min(day, IsoChronology.INSTANCE.isLeapYear(year) ? 29 : 28);
450
break;
451
case 4:
452
case 6:
453
case 9:
454
case 11:
455
day = Math.min(day, 30);
456
break;
457
}
458
return new LocalDate(year, month, day);
459
}
460
461
/**
462
* Constructor, previously validated.
463
*
464
* @param year the year to represent, from MIN_YEAR to MAX_YEAR
465
* @param month the month-of-year to represent, not null
466
* @param dayOfMonth the day-of-month to represent, valid for year-month, from 1 to 31
467
*/
468
private LocalDate(int year, int month, int dayOfMonth) {
469
this.year = year;
470
this.month = (short) month;
471
this.day = (short) dayOfMonth;
472
}
473
474
//-----------------------------------------------------------------------
475
/**
476
* Checks if the specified field is supported.
477
* <p>
478
* This checks if this date can be queried for the specified field.
479
* If false, then calling the {@link #range(TemporalField) range},
480
* {@link #get(TemporalField) get} and {@link #with(TemporalField, long)}
481
* methods will throw an exception.
482
* <p>
483
* If the field is a {@link ChronoField} then the query is implemented here.
484
* The supported fields are:
485
* <ul>
486
* <li>{@code DAY_OF_WEEK}
487
* <li>{@code ALIGNED_DAY_OF_WEEK_IN_MONTH}
488
* <li>{@code ALIGNED_DAY_OF_WEEK_IN_YEAR}
489
* <li>{@code DAY_OF_MONTH}
490
* <li>{@code DAY_OF_YEAR}
491
* <li>{@code EPOCH_DAY}
492
* <li>{@code ALIGNED_WEEK_OF_MONTH}
493
* <li>{@code ALIGNED_WEEK_OF_YEAR}
494
* <li>{@code MONTH_OF_YEAR}
495
* <li>{@code PROLEPTIC_MONTH}
496
* <li>{@code YEAR_OF_ERA}
497
* <li>{@code YEAR}
498
* <li>{@code ERA}
499
* </ul>
500
* All other {@code ChronoField} instances will return false.
501
* <p>
502
* If the field is not a {@code ChronoField}, then the result of this method
503
* is obtained by invoking {@code TemporalField.isSupportedBy(TemporalAccessor)}
504
* passing {@code this} as the argument.
505
* Whether the field is supported is determined by the field.
506
*
507
* @param field the field to check, null returns false
508
* @return true if the field is supported on this date, false if not
509
*/
510
@Override // override for Javadoc
511
public boolean isSupported(TemporalField field) {
512
return ChronoLocalDate.super.isSupported(field);
513
}
514
515
/**
516
* Checks if the specified unit is supported.
517
* <p>
518
* This checks if the specified unit can be added to, or subtracted from, this date.
519
* If false, then calling the {@link #plus(long, TemporalUnit)} and
520
* {@link #minus(long, TemporalUnit) minus} methods will throw an exception.
521
* <p>
522
* If the unit is a {@link ChronoUnit} then the query is implemented here.
523
* The supported units are:
524
* <ul>
525
* <li>{@code DAYS}
526
* <li>{@code WEEKS}
527
* <li>{@code MONTHS}
528
* <li>{@code YEARS}
529
* <li>{@code DECADES}
530
* <li>{@code CENTURIES}
531
* <li>{@code MILLENNIA}
532
* <li>{@code ERAS}
533
* </ul>
534
* All other {@code ChronoUnit} instances will return false.
535
* <p>
536
* If the unit is not a {@code ChronoUnit}, then the result of this method
537
* is obtained by invoking {@code TemporalUnit.isSupportedBy(Temporal)}
538
* passing {@code this} as the argument.
539
* Whether the unit is supported is determined by the unit.
540
*
541
* @param unit the unit to check, null returns false
542
* @return true if the unit can be added/subtracted, false if not
543
*/
544
@Override // override for Javadoc
545
public boolean isSupported(TemporalUnit unit) {
546
return ChronoLocalDate.super.isSupported(unit);
547
}
548
549
//-----------------------------------------------------------------------
550
/**
551
* Gets the range of valid values for the specified field.
552
* <p>
553
* The range object expresses the minimum and maximum valid values for a field.
554
* This date is used to enhance the accuracy of the returned range.
555
* If it is not possible to return the range, because the field is not supported
556
* or for some other reason, an exception is thrown.
557
* <p>
558
* If the field is a {@link ChronoField} then the query is implemented here.
559
* The {@link #isSupported(TemporalField) supported fields} will return
560
* appropriate range instances.
561
* All other {@code ChronoField} instances will throw an {@code UnsupportedTemporalTypeException}.
562
* <p>
563
* If the field is not a {@code ChronoField}, then the result of this method
564
* is obtained by invoking {@code TemporalField.rangeRefinedBy(TemporalAccessor)}
565
* passing {@code this} as the argument.
566
* Whether the range can be obtained is determined by the field.
567
*
568
* @param field the field to query the range for, not null
569
* @return the range of valid values for the field, not null
570
* @throws DateTimeException if the range for the field cannot be obtained
571
* @throws UnsupportedTemporalTypeException if the field is not supported
572
*/
573
@Override
574
public ValueRange range(TemporalField field) {
575
if (field instanceof ChronoField) {
576
ChronoField f = (ChronoField) field;
577
if (f.isDateBased()) {
578
switch (f) {
579
case DAY_OF_MONTH: return ValueRange.of(1, lengthOfMonth());
580
case DAY_OF_YEAR: return ValueRange.of(1, lengthOfYear());
581
case ALIGNED_WEEK_OF_MONTH: return ValueRange.of(1, getMonth() == Month.FEBRUARY && isLeapYear() == false ? 4 : 5);
582
case YEAR_OF_ERA:
583
return (getYear() <= 0 ? ValueRange.of(1, Year.MAX_VALUE + 1) : ValueRange.of(1, Year.MAX_VALUE));
584
}
585
return field.range();
586
}
587
throw new UnsupportedTemporalTypeException("Unsupported field: " + field);
588
}
589
return field.rangeRefinedBy(this);
590
}
591
592
/**
593
* Gets the value of the specified field from this date as an {@code int}.
594
* <p>
595
* This queries this date for the value of the specified field.
596
* The returned value will always be within the valid range of values for the field.
597
* If it is not possible to return the value, because the field is not supported
598
* or for some other reason, an exception is thrown.
599
* <p>
600
* If the field is a {@link ChronoField} then the query is implemented here.
601
* The {@link #isSupported(TemporalField) supported fields} will return valid
602
* values based on this date, except {@code EPOCH_DAY} and {@code PROLEPTIC_MONTH}
603
* which are too large to fit in an {@code int} and throw a {@code DateTimeException}.
604
* All other {@code ChronoField} instances will throw an {@code UnsupportedTemporalTypeException}.
605
* <p>
606
* If the field is not a {@code ChronoField}, then the result of this method
607
* is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
608
* passing {@code this} as the argument. Whether the value can be obtained,
609
* and what the value represents, is determined by the field.
610
*
611
* @param field the field to get, not null
612
* @return the value for the field
613
* @throws DateTimeException if a value for the field cannot be obtained or
614
* the value is outside the range of valid values for the field
615
* @throws UnsupportedTemporalTypeException if the field is not supported or
616
* the range of values exceeds an {@code int}
617
* @throws ArithmeticException if numeric overflow occurs
618
*/
619
@Override // override for Javadoc and performance
620
public int get(TemporalField field) {
621
if (field instanceof ChronoField) {
622
return get0(field);
623
}
624
return ChronoLocalDate.super.get(field);
625
}
626
627
/**
628
* Gets the value of the specified field from this date as a {@code long}.
629
* <p>
630
* This queries this date for the value of the specified field.
631
* If it is not possible to return the value, because the field is not supported
632
* or for some other reason, an exception is thrown.
633
* <p>
634
* If the field is a {@link ChronoField} then the query is implemented here.
635
* The {@link #isSupported(TemporalField) supported fields} will return valid
636
* values based on this date.
637
* All other {@code ChronoField} instances will throw an {@code UnsupportedTemporalTypeException}.
638
* <p>
639
* If the field is not a {@code ChronoField}, then the result of this method
640
* is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
641
* passing {@code this} as the argument. Whether the value can be obtained,
642
* and what the value represents, is determined by the field.
643
*
644
* @param field the field to get, not null
645
* @return the value for the field
646
* @throws DateTimeException if a value for the field cannot be obtained
647
* @throws UnsupportedTemporalTypeException if the field is not supported
648
* @throws ArithmeticException if numeric overflow occurs
649
*/
650
@Override
651
public long getLong(TemporalField field) {
652
if (field instanceof ChronoField) {
653
if (field == EPOCH_DAY) {
654
return toEpochDay();
655
}
656
if (field == PROLEPTIC_MONTH) {
657
return getProlepticMonth();
658
}
659
return get0(field);
660
}
661
return field.getFrom(this);
662
}
663
664
private int get0(TemporalField field) {
665
switch ((ChronoField) field) {
666
case DAY_OF_WEEK: return getDayOfWeek().getValue();
667
case ALIGNED_DAY_OF_WEEK_IN_MONTH: return ((day - 1) % 7) + 1;
668
case ALIGNED_DAY_OF_WEEK_IN_YEAR: return ((getDayOfYear() - 1) % 7) + 1;
669
case DAY_OF_MONTH: return day;
670
case DAY_OF_YEAR: return getDayOfYear();
671
case EPOCH_DAY: throw new UnsupportedTemporalTypeException("Invalid field 'EpochDay' for get() method, use getLong() instead");
672
case ALIGNED_WEEK_OF_MONTH: return ((day - 1) / 7) + 1;
673
case ALIGNED_WEEK_OF_YEAR: return ((getDayOfYear() - 1) / 7) + 1;
674
case MONTH_OF_YEAR: return month;
675
case PROLEPTIC_MONTH: throw new UnsupportedTemporalTypeException("Invalid field 'ProlepticMonth' for get() method, use getLong() instead");
676
case YEAR_OF_ERA: return (year >= 1 ? year : 1 - year);
677
case YEAR: return year;
678
case ERA: return (year >= 1 ? 1 : 0);
679
}
680
throw new UnsupportedTemporalTypeException("Unsupported field: " + field);
681
}
682
683
private long getProlepticMonth() {
684
return (year * 12L + month - 1);
685
}
686
687
//-----------------------------------------------------------------------
688
/**
689
* Gets the chronology of this date, which is the ISO calendar system.
690
* <p>
691
* The {@code Chronology} represents the calendar system in use.
692
* The ISO-8601 calendar system is the modern civil calendar system used today
693
* in most of the world. It is equivalent to the proleptic Gregorian calendar
694
* system, in which today's rules for leap years are applied for all time.
695
*
696
* @return the ISO chronology, not null
697
*/
698
@Override
699
public IsoChronology getChronology() {
700
return IsoChronology.INSTANCE;
701
}
702
703
/**
704
* Gets the era applicable at this date.
705
* <p>
706
* The official ISO-8601 standard does not define eras, however {@code IsoChronology} does.
707
* It defines two eras, 'CE' from year one onwards and 'BCE' from year zero backwards.
708
* Since dates before the Julian-Gregorian cutover are not in line with history,
709
* the cutover between 'BCE' and 'CE' is also not aligned with the commonly used
710
* eras, often referred to using 'BC' and 'AD'.
711
* <p>
712
* Users of this class should typically ignore this method as it exists primarily
713
* to fulfill the {@link ChronoLocalDate} contract where it is necessary to support
714
* the Japanese calendar system.
715
* <p>
716
* The returned era will be a singleton capable of being compared with the constants
717
* in {@link IsoChronology} using the {@code ==} operator.
718
*
719
* @return the {@code IsoChronology} era constant applicable at this date, not null
720
*/
721
@Override // override for Javadoc
722
public Era getEra() {
723
return ChronoLocalDate.super.getEra();
724
}
725
726
/**
727
* Gets the year field.
728
* <p>
729
* This method returns the primitive {@code int} value for the year.
730
* <p>
731
* The year returned by this method is proleptic as per {@code get(YEAR)}.
732
* To obtain the year-of-era, use {@code get(YEAR_OF_ERA)}.
733
*
734
* @return the year, from MIN_YEAR to MAX_YEAR
735
*/
736
public int getYear() {
737
return year;
738
}
739
740
/**
741
* Gets the month-of-year field from 1 to 12.
742
* <p>
743
* This method returns the month as an {@code int} from 1 to 12.
744
* Application code is frequently clearer if the enum {@link Month}
745
* is used by calling {@link #getMonth()}.
746
*
747
* @return the month-of-year, from 1 to 12
748
* @see #getMonth()
749
*/
750
public int getMonthValue() {
751
return month;
752
}
753
754
/**
755
* Gets the month-of-year field using the {@code Month} enum.
756
* <p>
757
* This method returns the enum {@link Month} for the month.
758
* This avoids confusion as to what {@code int} values mean.
759
* If you need access to the primitive {@code int} value then the enum
760
* provides the {@link Month#getValue() int value}.
761
*
762
* @return the month-of-year, not null
763
* @see #getMonthValue()
764
*/
765
public Month getMonth() {
766
return Month.of(month);
767
}
768
769
/**
770
* Gets the day-of-month field.
771
* <p>
772
* This method returns the primitive {@code int} value for the day-of-month.
773
*
774
* @return the day-of-month, from 1 to 31
775
*/
776
public int getDayOfMonth() {
777
return day;
778
}
779
780
/**
781
* Gets the day-of-year field.
782
* <p>
783
* This method returns the primitive {@code int} value for the day-of-year.
784
*
785
* @return the day-of-year, from 1 to 365, or 366 in a leap year
786
*/
787
public int getDayOfYear() {
788
return getMonth().firstDayOfYear(isLeapYear()) + day - 1;
789
}
790
791
/**
792
* Gets the day-of-week field, which is an enum {@code DayOfWeek}.
793
* <p>
794
* This method returns the enum {@link DayOfWeek} for the day-of-week.
795
* This avoids confusion as to what {@code int} values mean.
796
* If you need access to the primitive {@code int} value then the enum
797
* provides the {@link DayOfWeek#getValue() int value}.
798
* <p>
799
* Additional information can be obtained from the {@code DayOfWeek}.
800
* This includes textual names of the values.
801
*
802
* @return the day-of-week, not null
803
*/
804
public DayOfWeek getDayOfWeek() {
805
int dow0 = (int)Math.floorMod(toEpochDay() + 3, 7);
806
return DayOfWeek.of(dow0 + 1);
807
}
808
809
//-----------------------------------------------------------------------
810
/**
811
* Checks if the year is a leap year, according to the ISO proleptic
812
* calendar system rules.
813
* <p>
814
* This method applies the current rules for leap years across the whole time-line.
815
* In general, a year is a leap year if it is divisible by four without
816
* remainder. However, years divisible by 100, are not leap years, with
817
* the exception of years divisible by 400 which are.
818
* <p>
819
* For example, 1904 is a leap year it is divisible by 4.
820
* 1900 was not a leap year as it is divisible by 100, however 2000 was a
821
* leap year as it is divisible by 400.
822
* <p>
823
* The calculation is proleptic - applying the same rules into the far future and far past.
824
* This is historically inaccurate, but is correct for the ISO-8601 standard.
825
*
826
* @return true if the year is leap, false otherwise
827
*/
828
@Override // override for Javadoc and performance
829
public boolean isLeapYear() {
830
return IsoChronology.INSTANCE.isLeapYear(year);
831
}
832
833
/**
834
* Returns the length of the month represented by this date.
835
* <p>
836
* This returns the length of the month in days.
837
* For example, a date in January would return 31.
838
*
839
* @return the length of the month in days
840
*/
841
@Override
842
public int lengthOfMonth() {
843
switch (month) {
844
case 2:
845
return (isLeapYear() ? 29 : 28);
846
case 4:
847
case 6:
848
case 9:
849
case 11:
850
return 30;
851
default:
852
return 31;
853
}
854
}
855
856
/**
857
* Returns the length of the year represented by this date.
858
* <p>
859
* This returns the length of the year in days, either 365 or 366.
860
*
861
* @return 366 if the year is leap, 365 otherwise
862
*/
863
@Override // override for Javadoc and performance
864
public int lengthOfYear() {
865
return (isLeapYear() ? 366 : 365);
866
}
867
868
//-----------------------------------------------------------------------
869
/**
870
* Returns an adjusted copy of this date.
871
* <p>
872
* This returns a {@code LocalDate}, based on this one, with the date adjusted.
873
* The adjustment takes place using the specified adjuster strategy object.
874
* Read the documentation of the adjuster to understand what adjustment will be made.
875
* <p>
876
* A simple adjuster might simply set the one of the fields, such as the year field.
877
* A more complex adjuster might set the date to the last day of the month.
878
* <p>
879
* A selection of common adjustments is provided in
880
* {@link java.time.temporal.TemporalAdjusters TemporalAdjusters}.
881
* These include finding the "last day of the month" and "next Wednesday".
882
* Key date-time classes also implement the {@code TemporalAdjuster} interface,
883
* such as {@link Month} and {@link java.time.MonthDay MonthDay}.
884
* The adjuster is responsible for handling special cases, such as the varying
885
* lengths of month and leap years.
886
* <p>
887
* For example this code returns a date on the last day of July:
888
* <pre>
889
* import static java.time.Month.*;
890
* import static java.time.temporal.TemporalAdjusters.*;
891
*
892
* result = localDate.with(JULY).with(lastDayOfMonth());
893
* </pre>
894
* <p>
895
* The result of this method is obtained by invoking the
896
* {@link TemporalAdjuster#adjustInto(Temporal)} method on the
897
* specified adjuster passing {@code this} as the argument.
898
* <p>
899
* This instance is immutable and unaffected by this method call.
900
*
901
* @param adjuster the adjuster to use, not null
902
* @return a {@code LocalDate} based on {@code this} with the adjustment made, not null
903
* @throws DateTimeException if the adjustment cannot be made
904
* @throws ArithmeticException if numeric overflow occurs
905
*/
906
@Override
907
public LocalDate with(TemporalAdjuster adjuster) {
908
// optimizations
909
if (adjuster instanceof LocalDate) {
910
return (LocalDate) adjuster;
911
}
912
return (LocalDate) adjuster.adjustInto(this);
913
}
914
915
/**
916
* Returns a copy of this date with the specified field set to a new value.
917
* <p>
918
* This returns a {@code LocalDate}, based on this one, with the value
919
* for the specified field changed.
920
* This can be used to change any supported field, such as the year, month or day-of-month.
921
* If it is not possible to set the value, because the field is not supported or for
922
* some other reason, an exception is thrown.
923
* <p>
924
* In some cases, changing the specified field can cause the resulting date to become invalid,
925
* such as changing the month from 31st January to February would make the day-of-month invalid.
926
* In cases like this, the field is responsible for resolving the date. Typically it will choose
927
* the previous valid date, which would be the last valid day of February in this example.
928
* <p>
929
* If the field is a {@link ChronoField} then the adjustment is implemented here.
930
* The supported fields behave as follows:
931
* <ul>
932
* <li>{@code DAY_OF_WEEK} -
933
* Returns a {@code LocalDate} with the specified day-of-week.
934
* The date is adjusted up to 6 days forward or backward within the boundary
935
* of a Monday to Sunday week.
936
* <li>{@code ALIGNED_DAY_OF_WEEK_IN_MONTH} -
937
* Returns a {@code LocalDate} with the specified aligned-day-of-week.
938
* The date is adjusted to the specified month-based aligned-day-of-week.
939
* Aligned weeks are counted such that the first week of a given month starts
940
* on the first day of that month.
941
* This may cause the date to be moved up to 6 days into the following month.
942
* <li>{@code ALIGNED_DAY_OF_WEEK_IN_YEAR} -
943
* Returns a {@code LocalDate} with the specified aligned-day-of-week.
944
* The date is adjusted to the specified year-based aligned-day-of-week.
945
* Aligned weeks are counted such that the first week of a given year starts
946
* on the first day of that year.
947
* This may cause the date to be moved up to 6 days into the following year.
948
* <li>{@code DAY_OF_MONTH} -
949
* Returns a {@code LocalDate} with the specified day-of-month.
950
* The month and year will be unchanged. If the day-of-month is invalid for the
951
* year and month, then a {@code DateTimeException} is thrown.
952
* <li>{@code DAY_OF_YEAR} -
953
* Returns a {@code LocalDate} with the specified day-of-year.
954
* The year will be unchanged. If the day-of-year is invalid for the
955
* year, then a {@code DateTimeException} is thrown.
956
* <li>{@code EPOCH_DAY} -
957
* Returns a {@code LocalDate} with the specified epoch-day.
958
* This completely replaces the date and is equivalent to {@link #ofEpochDay(long)}.
959
* <li>{@code ALIGNED_WEEK_OF_MONTH} -
960
* Returns a {@code LocalDate} with the specified aligned-week-of-month.
961
* Aligned weeks are counted such that the first week of a given month starts
962
* on the first day of that month.
963
* This adjustment moves the date in whole week chunks to match the specified week.
964
* The result will have the same day-of-week as this date.
965
* This may cause the date to be moved into the following month.
966
* <li>{@code ALIGNED_WEEK_OF_YEAR} -
967
* Returns a {@code LocalDate} with the specified aligned-week-of-year.
968
* Aligned weeks are counted such that the first week of a given year starts
969
* on the first day of that year.
970
* This adjustment moves the date in whole week chunks to match the specified week.
971
* The result will have the same day-of-week as this date.
972
* This may cause the date to be moved into the following year.
973
* <li>{@code MONTH_OF_YEAR} -
974
* Returns a {@code LocalDate} with the specified month-of-year.
975
* The year will be unchanged. The day-of-month will also be unchanged,
976
* unless it would be invalid for the new month and year. In that case, the
977
* day-of-month is adjusted to the maximum valid value for the new month and year.
978
* <li>{@code PROLEPTIC_MONTH} -
979
* Returns a {@code LocalDate} with the specified proleptic-month.
980
* The day-of-month will be unchanged, unless it would be invalid for the new month
981
* and year. In that case, the day-of-month is adjusted to the maximum valid value
982
* for the new month and year.
983
* <li>{@code YEAR_OF_ERA} -
984
* Returns a {@code LocalDate} with the specified year-of-era.
985
* The era and month will be unchanged. The day-of-month will also be unchanged,
986
* unless it would be invalid for the new month and year. In that case, the
987
* day-of-month is adjusted to the maximum valid value for the new month and year.
988
* <li>{@code YEAR} -
989
* Returns a {@code LocalDate} with the specified year.
990
* The month will be unchanged. The day-of-month will also be unchanged,
991
* unless it would be invalid for the new month and year. In that case, the
992
* day-of-month is adjusted to the maximum valid value for the new month and year.
993
* <li>{@code ERA} -
994
* Returns a {@code LocalDate} with the specified era.
995
* The year-of-era and month will be unchanged. The day-of-month will also be unchanged,
996
* unless it would be invalid for the new month and year. In that case, the
997
* day-of-month is adjusted to the maximum valid value for the new month and year.
998
* </ul>
999
* <p>
1000
* In all cases, if the new value is outside the valid range of values for the field
1001
* then a {@code DateTimeException} will be thrown.
1002
* <p>
1003
* All other {@code ChronoField} instances will throw an {@code UnsupportedTemporalTypeException}.
1004
* <p>
1005
* If the field is not a {@code ChronoField}, then the result of this method
1006
* is obtained by invoking {@code TemporalField.adjustInto(Temporal, long)}
1007
* passing {@code this} as the argument. In this case, the field determines
1008
* whether and how to adjust the instant.
1009
* <p>
1010
* This instance is immutable and unaffected by this method call.
1011
*
1012
* @param field the field to set in the result, not null
1013
* @param newValue the new value of the field in the result
1014
* @return a {@code LocalDate} based on {@code this} with the specified field set, not null
1015
* @throws DateTimeException if the field cannot be set
1016
* @throws UnsupportedTemporalTypeException if the field is not supported
1017
* @throws ArithmeticException if numeric overflow occurs
1018
*/
1019
@Override
1020
public LocalDate with(TemporalField field, long newValue) {
1021
if (field instanceof ChronoField) {
1022
ChronoField f = (ChronoField) field;
1023
f.checkValidValue(newValue);
1024
switch (f) {
1025
case DAY_OF_WEEK: return plusDays(newValue - getDayOfWeek().getValue());
1026
case ALIGNED_DAY_OF_WEEK_IN_MONTH: return plusDays(newValue - getLong(ALIGNED_DAY_OF_WEEK_IN_MONTH));
1027
case ALIGNED_DAY_OF_WEEK_IN_YEAR: return plusDays(newValue - getLong(ALIGNED_DAY_OF_WEEK_IN_YEAR));
1028
case DAY_OF_MONTH: return withDayOfMonth((int) newValue);
1029
case DAY_OF_YEAR: return withDayOfYear((int) newValue);
1030
case EPOCH_DAY: return LocalDate.ofEpochDay(newValue);
1031
case ALIGNED_WEEK_OF_MONTH: return plusWeeks(newValue - getLong(ALIGNED_WEEK_OF_MONTH));
1032
case ALIGNED_WEEK_OF_YEAR: return plusWeeks(newValue - getLong(ALIGNED_WEEK_OF_YEAR));
1033
case MONTH_OF_YEAR: return withMonth((int) newValue);
1034
case PROLEPTIC_MONTH: return plusMonths(newValue - getProlepticMonth());
1035
case YEAR_OF_ERA: return withYear((int) (year >= 1 ? newValue : 1 - newValue));
1036
case YEAR: return withYear((int) newValue);
1037
case ERA: return (getLong(ERA) == newValue ? this : withYear(1 - year));
1038
}
1039
throw new UnsupportedTemporalTypeException("Unsupported field: " + field);
1040
}
1041
return field.adjustInto(this, newValue);
1042
}
1043
1044
//-----------------------------------------------------------------------
1045
/**
1046
* Returns a copy of this {@code LocalDate} with the year altered.
1047
* <p>
1048
* If the day-of-month is invalid for the year, it will be changed to the last valid day of the month.
1049
* <p>
1050
* This instance is immutable and unaffected by this method call.
1051
*
1052
* @param year the year to set in the result, from MIN_YEAR to MAX_YEAR
1053
* @return a {@code LocalDate} based on this date with the requested year, not null
1054
* @throws DateTimeException if the year value is invalid
1055
*/
1056
public LocalDate withYear(int year) {
1057
if (this.year == year) {
1058
return this;
1059
}
1060
YEAR.checkValidValue(year);
1061
return resolvePreviousValid(year, month, day);
1062
}
1063
1064
/**
1065
* Returns a copy of this {@code LocalDate} with the month-of-year altered.
1066
* <p>
1067
* If the day-of-month is invalid for the year, it will be changed to the last valid day of the month.
1068
* <p>
1069
* This instance is immutable and unaffected by this method call.
1070
*
1071
* @param month the month-of-year to set in the result, from 1 (January) to 12 (December)
1072
* @return a {@code LocalDate} based on this date with the requested month, not null
1073
* @throws DateTimeException if the month-of-year value is invalid
1074
*/
1075
public LocalDate withMonth(int month) {
1076
if (this.month == month) {
1077
return this;
1078
}
1079
MONTH_OF_YEAR.checkValidValue(month);
1080
return resolvePreviousValid(year, month, day);
1081
}
1082
1083
/**
1084
* Returns a copy of this {@code LocalDate} with the day-of-month altered.
1085
* <p>
1086
* If the resulting date is invalid, an exception is thrown.
1087
* <p>
1088
* This instance is immutable and unaffected by this method call.
1089
*
1090
* @param dayOfMonth the day-of-month to set in the result, from 1 to 28-31
1091
* @return a {@code LocalDate} based on this date with the requested day, not null
1092
* @throws DateTimeException if the day-of-month value is invalid,
1093
* or if the day-of-month is invalid for the month-year
1094
*/
1095
public LocalDate withDayOfMonth(int dayOfMonth) {
1096
if (this.day == dayOfMonth) {
1097
return this;
1098
}
1099
return of(year, month, dayOfMonth);
1100
}
1101
1102
/**
1103
* Returns a copy of this {@code LocalDate} with the day-of-year altered.
1104
* <p>
1105
* If the resulting date is invalid, an exception is thrown.
1106
* <p>
1107
* This instance is immutable and unaffected by this method call.
1108
*
1109
* @param dayOfYear the day-of-year to set in the result, from 1 to 365-366
1110
* @return a {@code LocalDate} based on this date with the requested day, not null
1111
* @throws DateTimeException if the day-of-year value is invalid,
1112
* or if the day-of-year is invalid for the year
1113
*/
1114
public LocalDate withDayOfYear(int dayOfYear) {
1115
if (this.getDayOfYear() == dayOfYear) {
1116
return this;
1117
}
1118
return ofYearDay(year, dayOfYear);
1119
}
1120
1121
//-----------------------------------------------------------------------
1122
/**
1123
* Returns a copy of this date with the specified amount added.
1124
* <p>
1125
* This returns a {@code LocalDate}, based on this one, with the specified amount added.
1126
* The amount is typically {@link Period} but may be any other type implementing
1127
* the {@link TemporalAmount} interface.
1128
* <p>
1129
* The calculation is delegated to the amount object by calling
1130
* {@link TemporalAmount#addTo(Temporal)}. The amount implementation is free
1131
* to implement the addition in any way it wishes, however it typically
1132
* calls back to {@link #plus(long, TemporalUnit)}. Consult the documentation
1133
* of the amount implementation to determine if it can be successfully added.
1134
* <p>
1135
* This instance is immutable and unaffected by this method call.
1136
*
1137
* @param amountToAdd the amount to add, not null
1138
* @return a {@code LocalDate} based on this date with the addition made, not null
1139
* @throws DateTimeException if the addition cannot be made
1140
* @throws ArithmeticException if numeric overflow occurs
1141
*/
1142
@Override
1143
public LocalDate plus(TemporalAmount amountToAdd) {
1144
if (amountToAdd instanceof Period) {
1145
Period periodToAdd = (Period) amountToAdd;
1146
return plusMonths(periodToAdd.toTotalMonths()).plusDays(periodToAdd.getDays());
1147
}
1148
Objects.requireNonNull(amountToAdd, "amountToAdd");
1149
return (LocalDate) amountToAdd.addTo(this);
1150
}
1151
1152
/**
1153
* Returns a copy of this date with the specified amount added.
1154
* <p>
1155
* This returns a {@code LocalDate}, based on this one, with the amount
1156
* in terms of the unit added. If it is not possible to add the amount, because the
1157
* unit is not supported or for some other reason, an exception is thrown.
1158
* <p>
1159
* In some cases, adding the amount can cause the resulting date to become invalid.
1160
* For example, adding one month to 31st January would result in 31st February.
1161
* In cases like this, the unit is responsible for resolving the date.
1162
* Typically it will choose the previous valid date, which would be the last valid
1163
* day of February in this example.
1164
* <p>
1165
* If the field is a {@link ChronoUnit} then the addition is implemented here.
1166
* The supported fields behave as follows:
1167
* <ul>
1168
* <li>{@code DAYS} -
1169
* Returns a {@code LocalDate} with the specified number of days added.
1170
* This is equivalent to {@link #plusDays(long)}.
1171
* <li>{@code WEEKS} -
1172
* Returns a {@code LocalDate} with the specified number of weeks added.
1173
* This is equivalent to {@link #plusWeeks(long)} and uses a 7 day week.
1174
* <li>{@code MONTHS} -
1175
* Returns a {@code LocalDate} with the specified number of months added.
1176
* This is equivalent to {@link #plusMonths(long)}.
1177
* The day-of-month will be unchanged unless it would be invalid for the new
1178
* month and year. In that case, the day-of-month is adjusted to the maximum
1179
* valid value for the new month and year.
1180
* <li>{@code YEARS} -
1181
* Returns a {@code LocalDate} with the specified number of years added.
1182
* This is equivalent to {@link #plusYears(long)}.
1183
* The day-of-month will be unchanged unless it would be invalid for the new
1184
* month and year. In that case, the day-of-month is adjusted to the maximum
1185
* valid value for the new month and year.
1186
* <li>{@code DECADES} -
1187
* Returns a {@code LocalDate} with the specified number of decades added.
1188
* This is equivalent to calling {@link #plusYears(long)} with the amount
1189
* multiplied by 10.
1190
* The day-of-month will be unchanged unless it would be invalid for the new
1191
* month and year. In that case, the day-of-month is adjusted to the maximum
1192
* valid value for the new month and year.
1193
* <li>{@code CENTURIES} -
1194
* Returns a {@code LocalDate} with the specified number of centuries added.
1195
* This is equivalent to calling {@link #plusYears(long)} with the amount
1196
* multiplied by 100.
1197
* The day-of-month will be unchanged unless it would be invalid for the new
1198
* month and year. In that case, the day-of-month is adjusted to the maximum
1199
* valid value for the new month and year.
1200
* <li>{@code MILLENNIA} -
1201
* Returns a {@code LocalDate} with the specified number of millennia added.
1202
* This is equivalent to calling {@link #plusYears(long)} with the amount
1203
* multiplied by 1,000.
1204
* The day-of-month will be unchanged unless it would be invalid for the new
1205
* month and year. In that case, the day-of-month is adjusted to the maximum
1206
* valid value for the new month and year.
1207
* <li>{@code ERAS} -
1208
* Returns a {@code LocalDate} with the specified number of eras added.
1209
* Only two eras are supported so the amount must be one, zero or minus one.
1210
* If the amount is non-zero then the year is changed such that the year-of-era
1211
* is unchanged.
1212
* The day-of-month will be unchanged unless it would be invalid for the new
1213
* month and year. In that case, the day-of-month is adjusted to the maximum
1214
* valid value for the new month and year.
1215
* </ul>
1216
* <p>
1217
* All other {@code ChronoUnit} instances will throw an {@code UnsupportedTemporalTypeException}.
1218
* <p>
1219
* If the field is not a {@code ChronoUnit}, then the result of this method
1220
* is obtained by invoking {@code TemporalUnit.addTo(Temporal, long)}
1221
* passing {@code this} as the argument. In this case, the unit determines
1222
* whether and how to perform the addition.
1223
* <p>
1224
* This instance is immutable and unaffected by this method call.
1225
*
1226
* @param amountToAdd the amount of the unit to add to the result, may be negative
1227
* @param unit the unit of the amount to add, not null
1228
* @return a {@code LocalDate} based on this date with the specified amount added, not null
1229
* @throws DateTimeException if the addition cannot be made
1230
* @throws UnsupportedTemporalTypeException if the unit is not supported
1231
* @throws ArithmeticException if numeric overflow occurs
1232
*/
1233
@Override
1234
public LocalDate plus(long amountToAdd, TemporalUnit unit) {
1235
if (unit instanceof ChronoUnit) {
1236
ChronoUnit f = (ChronoUnit) unit;
1237
switch (f) {
1238
case DAYS: return plusDays(amountToAdd);
1239
case WEEKS: return plusWeeks(amountToAdd);
1240
case MONTHS: return plusMonths(amountToAdd);
1241
case YEARS: return plusYears(amountToAdd);
1242
case DECADES: return plusYears(Math.multiplyExact(amountToAdd, 10));
1243
case CENTURIES: return plusYears(Math.multiplyExact(amountToAdd, 100));
1244
case MILLENNIA: return plusYears(Math.multiplyExact(amountToAdd, 1000));
1245
case ERAS: return with(ERA, Math.addExact(getLong(ERA), amountToAdd));
1246
}
1247
throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit);
1248
}
1249
return unit.addTo(this, amountToAdd);
1250
}
1251
1252
//-----------------------------------------------------------------------
1253
/**
1254
* Returns a copy of this {@code LocalDate} with the specified number of years added.
1255
* <p>
1256
* This method adds the specified amount to the years field in three steps:
1257
* <ol>
1258
* <li>Add the input years to the year field</li>
1259
* <li>Check if the resulting date would be invalid</li>
1260
* <li>Adjust the day-of-month to the last valid day if necessary</li>
1261
* </ol>
1262
* <p>
1263
* For example, 2008-02-29 (leap year) plus one year would result in the
1264
* invalid date 2009-02-29 (standard year). Instead of returning an invalid
1265
* result, the last valid day of the month, 2009-02-28, is selected instead.
1266
* <p>
1267
* This instance is immutable and unaffected by this method call.
1268
*
1269
* @param yearsToAdd the years to add, may be negative
1270
* @return a {@code LocalDate} based on this date with the years added, not null
1271
* @throws DateTimeException if the result exceeds the supported date range
1272
*/
1273
public LocalDate plusYears(long yearsToAdd) {
1274
if (yearsToAdd == 0) {
1275
return this;
1276
}
1277
int newYear = YEAR.checkValidIntValue(year + yearsToAdd); // safe overflow
1278
return resolvePreviousValid(newYear, month, day);
1279
}
1280
1281
/**
1282
* Returns a copy of this {@code LocalDate} with the specified number of months added.
1283
* <p>
1284
* This method adds the specified amount to the months field in three steps:
1285
* <ol>
1286
* <li>Add the input months to the month-of-year field</li>
1287
* <li>Check if the resulting date would be invalid</li>
1288
* <li>Adjust the day-of-month to the last valid day if necessary</li>
1289
* </ol>
1290
* <p>
1291
* For example, 2007-03-31 plus one month would result in the invalid date
1292
* 2007-04-31. Instead of returning an invalid result, the last valid day
1293
* of the month, 2007-04-30, is selected instead.
1294
* <p>
1295
* This instance is immutable and unaffected by this method call.
1296
*
1297
* @param monthsToAdd the months to add, may be negative
1298
* @return a {@code LocalDate} based on this date with the months added, not null
1299
* @throws DateTimeException if the result exceeds the supported date range
1300
*/
1301
public LocalDate plusMonths(long monthsToAdd) {
1302
if (monthsToAdd == 0) {
1303
return this;
1304
}
1305
long monthCount = year * 12L + (month - 1);
1306
long calcMonths = monthCount + monthsToAdd; // safe overflow
1307
int newYear = YEAR.checkValidIntValue(Math.floorDiv(calcMonths, 12));
1308
int newMonth = (int)Math.floorMod(calcMonths, 12) + 1;
1309
return resolvePreviousValid(newYear, newMonth, day);
1310
}
1311
1312
/**
1313
* Returns a copy of this {@code LocalDate} with the specified number of weeks added.
1314
* <p>
1315
* This method adds the specified amount in weeks to the days field incrementing
1316
* the month and year fields as necessary to ensure the result remains valid.
1317
* The result is only invalid if the maximum/minimum year is exceeded.
1318
* <p>
1319
* For example, 2008-12-31 plus one week would result in 2009-01-07.
1320
* <p>
1321
* This instance is immutable and unaffected by this method call.
1322
*
1323
* @param weeksToAdd the weeks to add, may be negative
1324
* @return a {@code LocalDate} based on this date with the weeks added, not null
1325
* @throws DateTimeException if the result exceeds the supported date range
1326
*/
1327
public LocalDate plusWeeks(long weeksToAdd) {
1328
return plusDays(Math.multiplyExact(weeksToAdd, 7));
1329
}
1330
1331
/**
1332
* Returns a copy of this {@code LocalDate} with the specified number of days added.
1333
* <p>
1334
* This method adds the specified amount to the days field incrementing the
1335
* month and year fields as necessary to ensure the result remains valid.
1336
* The result is only invalid if the maximum/minimum year is exceeded.
1337
* <p>
1338
* For example, 2008-12-31 plus one day would result in 2009-01-01.
1339
* <p>
1340
* This instance is immutable and unaffected by this method call.
1341
*
1342
* @param daysToAdd the days to add, may be negative
1343
* @return a {@code LocalDate} based on this date with the days added, not null
1344
* @throws DateTimeException if the result exceeds the supported date range
1345
*/
1346
public LocalDate plusDays(long daysToAdd) {
1347
if (daysToAdd == 0) {
1348
return this;
1349
}
1350
long mjDay = Math.addExact(toEpochDay(), daysToAdd);
1351
return LocalDate.ofEpochDay(mjDay);
1352
}
1353
1354
//-----------------------------------------------------------------------
1355
/**
1356
* Returns a copy of this date with the specified amount subtracted.
1357
* <p>
1358
* This returns a {@code LocalDate}, based on this one, with the specified amount subtracted.
1359
* The amount is typically {@link Period} but may be any other type implementing
1360
* the {@link TemporalAmount} interface.
1361
* <p>
1362
* The calculation is delegated to the amount object by calling
1363
* {@link TemporalAmount#subtractFrom(Temporal)}. The amount implementation is free
1364
* to implement the subtraction in any way it wishes, however it typically
1365
* calls back to {@link #minus(long, TemporalUnit)}. Consult the documentation
1366
* of the amount implementation to determine if it can be successfully subtracted.
1367
* <p>
1368
* This instance is immutable and unaffected by this method call.
1369
*
1370
* @param amountToSubtract the amount to subtract, not null
1371
* @return a {@code LocalDate} based on this date with the subtraction made, not null
1372
* @throws DateTimeException if the subtraction cannot be made
1373
* @throws ArithmeticException if numeric overflow occurs
1374
*/
1375
@Override
1376
public LocalDate minus(TemporalAmount amountToSubtract) {
1377
if (amountToSubtract instanceof Period) {
1378
Period periodToSubtract = (Period) amountToSubtract;
1379
return minusMonths(periodToSubtract.toTotalMonths()).minusDays(periodToSubtract.getDays());
1380
}
1381
Objects.requireNonNull(amountToSubtract, "amountToSubtract");
1382
return (LocalDate) amountToSubtract.subtractFrom(this);
1383
}
1384
1385
/**
1386
* Returns a copy of this date with the specified amount subtracted.
1387
* <p>
1388
* This returns a {@code LocalDate}, based on this one, with the amount
1389
* in terms of the unit subtracted. If it is not possible to subtract the amount,
1390
* because the unit is not supported or for some other reason, an exception is thrown.
1391
* <p>
1392
* This method is equivalent to {@link #plus(long, TemporalUnit)} with the amount negated.
1393
* See that method for a full description of how addition, and thus subtraction, works.
1394
* <p>
1395
* This instance is immutable and unaffected by this method call.
1396
*
1397
* @param amountToSubtract the amount of the unit to subtract from the result, may be negative
1398
* @param unit the unit of the amount to subtract, not null
1399
* @return a {@code LocalDate} based on this date with the specified amount subtracted, not null
1400
* @throws DateTimeException if the subtraction cannot be made
1401
* @throws UnsupportedTemporalTypeException if the unit is not supported
1402
* @throws ArithmeticException if numeric overflow occurs
1403
*/
1404
@Override
1405
public LocalDate minus(long amountToSubtract, TemporalUnit unit) {
1406
return (amountToSubtract == Long.MIN_VALUE ? plus(Long.MAX_VALUE, unit).plus(1, unit) : plus(-amountToSubtract, unit));
1407
}
1408
1409
//-----------------------------------------------------------------------
1410
/**
1411
* Returns a copy of this {@code LocalDate} with the specified number of years subtracted.
1412
* <p>
1413
* This method subtracts the specified amount from the years field in three steps:
1414
* <ol>
1415
* <li>Subtract the input years from the year field</li>
1416
* <li>Check if the resulting date would be invalid</li>
1417
* <li>Adjust the day-of-month to the last valid day if necessary</li>
1418
* </ol>
1419
* <p>
1420
* For example, 2008-02-29 (leap year) minus one year would result in the
1421
* invalid date 2007-02-29 (standard year). Instead of returning an invalid
1422
* result, the last valid day of the month, 2007-02-28, is selected instead.
1423
* <p>
1424
* This instance is immutable and unaffected by this method call.
1425
*
1426
* @param yearsToSubtract the years to subtract, may be negative
1427
* @return a {@code LocalDate} based on this date with the years subtracted, not null
1428
* @throws DateTimeException if the result exceeds the supported date range
1429
*/
1430
public LocalDate minusYears(long yearsToSubtract) {
1431
return (yearsToSubtract == Long.MIN_VALUE ? plusYears(Long.MAX_VALUE).plusYears(1) : plusYears(-yearsToSubtract));
1432
}
1433
1434
/**
1435
* Returns a copy of this {@code LocalDate} with the specified number of months subtracted.
1436
* <p>
1437
* This method subtracts the specified amount from the months field in three steps:
1438
* <ol>
1439
* <li>Subtract the input months from the month-of-year field</li>
1440
* <li>Check if the resulting date would be invalid</li>
1441
* <li>Adjust the day-of-month to the last valid day if necessary</li>
1442
* </ol>
1443
* <p>
1444
* For example, 2007-03-31 minus one month would result in the invalid date
1445
* 2007-02-31. Instead of returning an invalid result, the last valid day
1446
* of the month, 2007-02-28, is selected instead.
1447
* <p>
1448
* This instance is immutable and unaffected by this method call.
1449
*
1450
* @param monthsToSubtract the months to subtract, may be negative
1451
* @return a {@code LocalDate} based on this date with the months subtracted, not null
1452
* @throws DateTimeException if the result exceeds the supported date range
1453
*/
1454
public LocalDate minusMonths(long monthsToSubtract) {
1455
return (monthsToSubtract == Long.MIN_VALUE ? plusMonths(Long.MAX_VALUE).plusMonths(1) : plusMonths(-monthsToSubtract));
1456
}
1457
1458
/**
1459
* Returns a copy of this {@code LocalDate} with the specified number of weeks subtracted.
1460
* <p>
1461
* This method subtracts the specified amount in weeks from the days field decrementing
1462
* the month and year fields as necessary to ensure the result remains valid.
1463
* The result is only invalid if the maximum/minimum year is exceeded.
1464
* <p>
1465
* For example, 2009-01-07 minus one week would result in 2008-12-31.
1466
* <p>
1467
* This instance is immutable and unaffected by this method call.
1468
*
1469
* @param weeksToSubtract the weeks to subtract, may be negative
1470
* @return a {@code LocalDate} based on this date with the weeks subtracted, not null
1471
* @throws DateTimeException if the result exceeds the supported date range
1472
*/
1473
public LocalDate minusWeeks(long weeksToSubtract) {
1474
return (weeksToSubtract == Long.MIN_VALUE ? plusWeeks(Long.MAX_VALUE).plusWeeks(1) : plusWeeks(-weeksToSubtract));
1475
}
1476
1477
/**
1478
* Returns a copy of this {@code LocalDate} with the specified number of days subtracted.
1479
* <p>
1480
* This method subtracts the specified amount from the days field decrementing the
1481
* month and year fields as necessary to ensure the result remains valid.
1482
* The result is only invalid if the maximum/minimum year is exceeded.
1483
* <p>
1484
* For example, 2009-01-01 minus one day would result in 2008-12-31.
1485
* <p>
1486
* This instance is immutable and unaffected by this method call.
1487
*
1488
* @param daysToSubtract the days to subtract, may be negative
1489
* @return a {@code LocalDate} based on this date with the days subtracted, not null
1490
* @throws DateTimeException if the result exceeds the supported date range
1491
*/
1492
public LocalDate minusDays(long daysToSubtract) {
1493
return (daysToSubtract == Long.MIN_VALUE ? plusDays(Long.MAX_VALUE).plusDays(1) : plusDays(-daysToSubtract));
1494
}
1495
1496
//-----------------------------------------------------------------------
1497
/**
1498
* Queries this date using the specified query.
1499
* <p>
1500
* This queries this date using the specified query strategy object.
1501
* The {@code TemporalQuery} object defines the logic to be used to
1502
* obtain the result. Read the documentation of the query to understand
1503
* what the result of this method will be.
1504
* <p>
1505
* The result of this method is obtained by invoking the
1506
* {@link TemporalQuery#queryFrom(TemporalAccessor)} method on the
1507
* specified query passing {@code this} as the argument.
1508
*
1509
* @param <R> the type of the result
1510
* @param query the query to invoke, not null
1511
* @return the query result, null may be returned (defined by the query)
1512
* @throws DateTimeException if unable to query (defined by the query)
1513
* @throws ArithmeticException if numeric overflow occurs (defined by the query)
1514
*/
1515
@SuppressWarnings("unchecked")
1516
@Override
1517
public <R> R query(TemporalQuery<R> query) {
1518
if (query == TemporalQueries.localDate()) {
1519
return (R) this;
1520
}
1521
return ChronoLocalDate.super.query(query);
1522
}
1523
1524
/**
1525
* Adjusts the specified temporal object to have the same date as this object.
1526
* <p>
1527
* This returns a temporal object of the same observable type as the input
1528
* with the date changed to be the same as this.
1529
* <p>
1530
* The adjustment is equivalent to using {@link Temporal#with(TemporalField, long)}
1531
* passing {@link ChronoField#EPOCH_DAY} as the field.
1532
* <p>
1533
* In most cases, it is clearer to reverse the calling pattern by using
1534
* {@link Temporal#with(TemporalAdjuster)}:
1535
* <pre>
1536
* // these two lines are equivalent, but the second approach is recommended
1537
* temporal = thisLocalDate.adjustInto(temporal);
1538
* temporal = temporal.with(thisLocalDate);
1539
* </pre>
1540
* <p>
1541
* This instance is immutable and unaffected by this method call.
1542
*
1543
* @param temporal the target object to be adjusted, not null
1544
* @return the adjusted object, not null
1545
* @throws DateTimeException if unable to make the adjustment
1546
* @throws ArithmeticException if numeric overflow occurs
1547
*/
1548
@Override // override for Javadoc
1549
public Temporal adjustInto(Temporal temporal) {
1550
return ChronoLocalDate.super.adjustInto(temporal);
1551
}
1552
1553
/**
1554
* Calculates the amount of time until another date in terms of the specified unit.
1555
* <p>
1556
* This calculates the amount of time between two {@code LocalDate}
1557
* objects in terms of a single {@code TemporalUnit}.
1558
* The start and end points are {@code this} and the specified date.
1559
* The result will be negative if the end is before the start.
1560
* The {@code Temporal} passed to this method is converted to a
1561
* {@code LocalDate} using {@link #from(TemporalAccessor)}.
1562
* For example, the amount in days between two dates can be calculated
1563
* using {@code startDate.until(endDate, DAYS)}.
1564
* <p>
1565
* The calculation returns a whole number, representing the number of
1566
* complete units between the two dates.
1567
* For example, the amount in months between 2012-06-15 and 2012-08-14
1568
* will only be one month as it is one day short of two months.
1569
* <p>
1570
* There are two equivalent ways of using this method.
1571
* The first is to invoke this method.
1572
* The second is to use {@link TemporalUnit#between(Temporal, Temporal)}:
1573
* <pre>
1574
* // these two lines are equivalent
1575
* amount = start.until(end, MONTHS);
1576
* amount = MONTHS.between(start, end);
1577
* </pre>
1578
* The choice should be made based on which makes the code more readable.
1579
* <p>
1580
* The calculation is implemented in this method for {@link ChronoUnit}.
1581
* The units {@code DAYS}, {@code WEEKS}, {@code MONTHS}, {@code YEARS},
1582
* {@code DECADES}, {@code CENTURIES}, {@code MILLENNIA} and {@code ERAS}
1583
* are supported. Other {@code ChronoUnit} values will throw an exception.
1584
* <p>
1585
* If the unit is not a {@code ChronoUnit}, then the result of this method
1586
* is obtained by invoking {@code TemporalUnit.between(Temporal, Temporal)}
1587
* passing {@code this} as the first argument and the converted input temporal
1588
* as the second argument.
1589
* <p>
1590
* This instance is immutable and unaffected by this method call.
1591
*
1592
* @param endExclusive the end date, exclusive, which is converted to a {@code LocalDate}, not null
1593
* @param unit the unit to measure the amount in, not null
1594
* @return the amount of time between this date and the end date
1595
* @throws DateTimeException if the amount cannot be calculated, or the end
1596
* temporal cannot be converted to a {@code LocalDate}
1597
* @throws UnsupportedTemporalTypeException if the unit is not supported
1598
* @throws ArithmeticException if numeric overflow occurs
1599
*/
1600
@Override
1601
public long until(Temporal endExclusive, TemporalUnit unit) {
1602
LocalDate end = LocalDate.from(endExclusive);
1603
if (unit instanceof ChronoUnit) {
1604
switch ((ChronoUnit) unit) {
1605
case DAYS: return daysUntil(end);
1606
case WEEKS: return daysUntil(end) / 7;
1607
case MONTHS: return monthsUntil(end);
1608
case YEARS: return monthsUntil(end) / 12;
1609
case DECADES: return monthsUntil(end) / 120;
1610
case CENTURIES: return monthsUntil(end) / 1200;
1611
case MILLENNIA: return monthsUntil(end) / 12000;
1612
case ERAS: return end.getLong(ERA) - getLong(ERA);
1613
}
1614
throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit);
1615
}
1616
return unit.between(this, end);
1617
}
1618
1619
long daysUntil(LocalDate end) {
1620
return end.toEpochDay() - toEpochDay(); // no overflow
1621
}
1622
1623
private long monthsUntil(LocalDate end) {
1624
long packed1 = getProlepticMonth() * 32L + getDayOfMonth(); // no overflow
1625
long packed2 = end.getProlepticMonth() * 32L + end.getDayOfMonth(); // no overflow
1626
return (packed2 - packed1) / 32;
1627
}
1628
1629
/**
1630
* Calculates the period between this date and another date as a {@code Period}.
1631
* <p>
1632
* This calculates the period between two dates in terms of years, months and days.
1633
* The start and end points are {@code this} and the specified date.
1634
* The result will be negative if the end is before the start.
1635
* The negative sign will be the same in each of year, month and day.
1636
* <p>
1637
* The calculation is performed using the ISO calendar system.
1638
* If necessary, the input date will be converted to ISO.
1639
* <p>
1640
* The start date is included, but the end date is not.
1641
* The period is calculated by removing complete months, then calculating
1642
* the remaining number of days, adjusting to ensure that both have the same sign.
1643
* The number of months is then normalized into years and months based on a 12 month year.
1644
* A month is considered to be complete if the end day-of-month is greater
1645
* than or equal to the start day-of-month.
1646
* For example, from {@code 2010-01-15} to {@code 2011-03-18} is "1 year, 2 months and 3 days".
1647
* <p>
1648
* There are two equivalent ways of using this method.
1649
* The first is to invoke this method.
1650
* The second is to use {@link Period#between(LocalDate, LocalDate)}:
1651
* <pre>
1652
* // these two lines are equivalent
1653
* period = start.until(end);
1654
* period = Period.between(start, end);
1655
* </pre>
1656
* The choice should be made based on which makes the code more readable.
1657
*
1658
* @param endDateExclusive the end date, exclusive, which may be in any chronology, not null
1659
* @return the period between this date and the end date, not null
1660
*/
1661
@Override
1662
public Period until(ChronoLocalDate endDateExclusive) {
1663
LocalDate end = LocalDate.from(endDateExclusive);
1664
long totalMonths = end.getProlepticMonth() - this.getProlepticMonth(); // safe
1665
int days = end.day - this.day;
1666
if (totalMonths > 0 && days < 0) {
1667
totalMonths--;
1668
LocalDate calcDate = this.plusMonths(totalMonths);
1669
days = (int) (end.toEpochDay() - calcDate.toEpochDay()); // safe
1670
} else if (totalMonths < 0 && days > 0) {
1671
totalMonths++;
1672
days -= end.lengthOfMonth();
1673
}
1674
long years = totalMonths / 12; // safe
1675
int months = (int) (totalMonths % 12); // safe
1676
return Period.of(Math.toIntExact(years), months, days);
1677
}
1678
1679
/**
1680
* Formats this date using the specified formatter.
1681
* <p>
1682
* This date will be passed to the formatter to produce a string.
1683
*
1684
* @param formatter the formatter to use, not null
1685
* @return the formatted date string, not null
1686
* @throws DateTimeException if an error occurs during printing
1687
*/
1688
@Override // override for Javadoc and performance
1689
public String format(DateTimeFormatter formatter) {
1690
Objects.requireNonNull(formatter, "formatter");
1691
return formatter.format(this);
1692
}
1693
1694
//-----------------------------------------------------------------------
1695
/**
1696
* Combines this date with a time to create a {@code LocalDateTime}.
1697
* <p>
1698
* This returns a {@code LocalDateTime} formed from this date at the specified time.
1699
* All possible combinations of date and time are valid.
1700
*
1701
* @param time the time to combine with, not null
1702
* @return the local date-time formed from this date and the specified time, not null
1703
*/
1704
@Override
1705
public LocalDateTime atTime(LocalTime time) {
1706
return LocalDateTime.of(this, time);
1707
}
1708
1709
/**
1710
* Combines this date with a time to create a {@code LocalDateTime}.
1711
* <p>
1712
* This returns a {@code LocalDateTime} formed from this date at the
1713
* specified hour and minute.
1714
* The seconds and nanosecond fields will be set to zero.
1715
* The individual time fields must be within their valid range.
1716
* All possible combinations of date and time are valid.
1717
*
1718
* @param hour the hour-of-day to use, from 0 to 23
1719
* @param minute the minute-of-hour to use, from 0 to 59
1720
* @return the local date-time formed from this date and the specified time, not null
1721
* @throws DateTimeException if the value of any field is out of range
1722
*/
1723
public LocalDateTime atTime(int hour, int minute) {
1724
return atTime(LocalTime.of(hour, minute));
1725
}
1726
1727
/**
1728
* Combines this date with a time to create a {@code LocalDateTime}.
1729
* <p>
1730
* This returns a {@code LocalDateTime} formed from this date at the
1731
* specified hour, minute and second.
1732
* The nanosecond field will be set to zero.
1733
* The individual time fields must be within their valid range.
1734
* All possible combinations of date and time are valid.
1735
*
1736
* @param hour the hour-of-day to use, from 0 to 23
1737
* @param minute the minute-of-hour to use, from 0 to 59
1738
* @param second the second-of-minute to represent, from 0 to 59
1739
* @return the local date-time formed from this date and the specified time, not null
1740
* @throws DateTimeException if the value of any field is out of range
1741
*/
1742
public LocalDateTime atTime(int hour, int minute, int second) {
1743
return atTime(LocalTime.of(hour, minute, second));
1744
}
1745
1746
/**
1747
* Combines this date with a time to create a {@code LocalDateTime}.
1748
* <p>
1749
* This returns a {@code LocalDateTime} formed from this date at the
1750
* specified hour, minute, second and nanosecond.
1751
* The individual time fields must be within their valid range.
1752
* All possible combinations of date and time are valid.
1753
*
1754
* @param hour the hour-of-day to use, from 0 to 23
1755
* @param minute the minute-of-hour to use, from 0 to 59
1756
* @param second the second-of-minute to represent, from 0 to 59
1757
* @param nanoOfSecond the nano-of-second to represent, from 0 to 999,999,999
1758
* @return the local date-time formed from this date and the specified time, not null
1759
* @throws DateTimeException if the value of any field is out of range
1760
*/
1761
public LocalDateTime atTime(int hour, int minute, int second, int nanoOfSecond) {
1762
return atTime(LocalTime.of(hour, minute, second, nanoOfSecond));
1763
}
1764
1765
/**
1766
* Combines this date with an offset time to create an {@code OffsetDateTime}.
1767
* <p>
1768
* This returns an {@code OffsetDateTime} formed from this date at the specified time.
1769
* All possible combinations of date and time are valid.
1770
*
1771
* @param time the time to combine with, not null
1772
* @return the offset date-time formed from this date and the specified time, not null
1773
*/
1774
public OffsetDateTime atTime(OffsetTime time) {
1775
return OffsetDateTime.of(LocalDateTime.of(this, time.toLocalTime()), time.getOffset());
1776
}
1777
1778
/**
1779
* Combines this date with the time of midnight to create a {@code LocalDateTime}
1780
* at the start of this date.
1781
* <p>
1782
* This returns a {@code LocalDateTime} formed from this date at the time of
1783
* midnight, 00:00, at the start of this date.
1784
*
1785
* @return the local date-time of midnight at the start of this date, not null
1786
*/
1787
public LocalDateTime atStartOfDay() {
1788
return LocalDateTime.of(this, LocalTime.MIDNIGHT);
1789
}
1790
1791
/**
1792
* Returns a zoned date-time from this date at the earliest valid time according
1793
* to the rules in the time-zone.
1794
* <p>
1795
* Time-zone rules, such as daylight savings, mean that not every local date-time
1796
* is valid for the specified zone, thus the local date-time may not be midnight.
1797
* <p>
1798
* In most cases, there is only one valid offset for a local date-time.
1799
* In the case of an overlap, there are two valid offsets, and the earlier one is used,
1800
* corresponding to the first occurrence of midnight on the date.
1801
* In the case of a gap, the zoned date-time will represent the instant just after the gap.
1802
* <p>
1803
* If the zone ID is a {@link ZoneOffset}, then the result always has a time of midnight.
1804
* <p>
1805
* To convert to a specific time in a given time-zone call {@link #atTime(LocalTime)}
1806
* followed by {@link LocalDateTime#atZone(ZoneId)}.
1807
*
1808
* @param zone the zone ID to use, not null
1809
* @return the zoned date-time formed from this date and the earliest valid time for the zone, not null
1810
*/
1811
public ZonedDateTime atStartOfDay(ZoneId zone) {
1812
Objects.requireNonNull(zone, "zone");
1813
// need to handle case where there is a gap from 11:30 to 00:30
1814
// standard ZDT factory would result in 01:00 rather than 00:30
1815
LocalDateTime ldt = atTime(LocalTime.MIDNIGHT);
1816
if (zone instanceof ZoneOffset == false) {
1817
ZoneRules rules = zone.getRules();
1818
ZoneOffsetTransition trans = rules.getTransition(ldt);
1819
if (trans != null && trans.isGap()) {
1820
ldt = trans.getDateTimeAfter();
1821
}
1822
}
1823
return ZonedDateTime.of(ldt, zone);
1824
}
1825
1826
//-----------------------------------------------------------------------
1827
@Override
1828
public long toEpochDay() {
1829
long y = year;
1830
long m = month;
1831
long total = 0;
1832
total += 365 * y;
1833
if (y >= 0) {
1834
total += (y + 3) / 4 - (y + 99) / 100 + (y + 399) / 400;
1835
} else {
1836
total -= y / -4 - y / -100 + y / -400;
1837
}
1838
total += ((367 * m - 362) / 12);
1839
total += day - 1;
1840
if (m > 2) {
1841
total--;
1842
if (isLeapYear() == false) {
1843
total--;
1844
}
1845
}
1846
return total - DAYS_0000_TO_1970;
1847
}
1848
1849
//-----------------------------------------------------------------------
1850
/**
1851
* Compares this date to another date.
1852
* <p>
1853
* The comparison is primarily based on the date, from earliest to latest.
1854
* It is "consistent with equals", as defined by {@link Comparable}.
1855
* <p>
1856
* If all the dates being compared are instances of {@code LocalDate},
1857
* then the comparison will be entirely based on the date.
1858
* If some dates being compared are in different chronologies, then the
1859
* chronology is also considered, see {@link java.time.chrono.ChronoLocalDate#compareTo}.
1860
*
1861
* @param other the other date to compare to, not null
1862
* @return the comparator value, negative if less, positive if greater
1863
*/
1864
@Override // override for Javadoc and performance
1865
public int compareTo(ChronoLocalDate other) {
1866
if (other instanceof LocalDate) {
1867
return compareTo0((LocalDate) other);
1868
}
1869
return ChronoLocalDate.super.compareTo(other);
1870
}
1871
1872
int compareTo0(LocalDate otherDate) {
1873
int cmp = (year - otherDate.year);
1874
if (cmp == 0) {
1875
cmp = (month - otherDate.month);
1876
if (cmp == 0) {
1877
cmp = (day - otherDate.day);
1878
}
1879
}
1880
return cmp;
1881
}
1882
1883
/**
1884
* Checks if this date is after the specified date.
1885
* <p>
1886
* This checks to see if this date represents a point on the
1887
* local time-line after the other date.
1888
* <pre>
1889
* LocalDate a = LocalDate.of(2012, 6, 30);
1890
* LocalDate b = LocalDate.of(2012, 7, 1);
1891
* a.isAfter(b) == false
1892
* a.isAfter(a) == false
1893
* b.isAfter(a) == true
1894
* </pre>
1895
* <p>
1896
* This method only considers the position of the two dates on the local time-line.
1897
* It does not take into account the chronology, or calendar system.
1898
* This is different from the comparison in {@link #compareTo(ChronoLocalDate)},
1899
* but is the same approach as {@link ChronoLocalDate#timeLineOrder()}.
1900
*
1901
* @param other the other date to compare to, not null
1902
* @return true if this date is after the specified date
1903
*/
1904
@Override // override for Javadoc and performance
1905
public boolean isAfter(ChronoLocalDate other) {
1906
if (other instanceof LocalDate) {
1907
return compareTo0((LocalDate) other) > 0;
1908
}
1909
return ChronoLocalDate.super.isAfter(other);
1910
}
1911
1912
/**
1913
* Checks if this date is before the specified date.
1914
* <p>
1915
* This checks to see if this date represents a point on the
1916
* local time-line before the other date.
1917
* <pre>
1918
* LocalDate a = LocalDate.of(2012, 6, 30);
1919
* LocalDate b = LocalDate.of(2012, 7, 1);
1920
* a.isBefore(b) == true
1921
* a.isBefore(a) == false
1922
* b.isBefore(a) == false
1923
* </pre>
1924
* <p>
1925
* This method only considers the position of the two dates on the local time-line.
1926
* It does not take into account the chronology, or calendar system.
1927
* This is different from the comparison in {@link #compareTo(ChronoLocalDate)},
1928
* but is the same approach as {@link ChronoLocalDate#timeLineOrder()}.
1929
*
1930
* @param other the other date to compare to, not null
1931
* @return true if this date is before the specified date
1932
*/
1933
@Override // override for Javadoc and performance
1934
public boolean isBefore(ChronoLocalDate other) {
1935
if (other instanceof LocalDate) {
1936
return compareTo0((LocalDate) other) < 0;
1937
}
1938
return ChronoLocalDate.super.isBefore(other);
1939
}
1940
1941
/**
1942
* Checks if this date is equal to the specified date.
1943
* <p>
1944
* This checks to see if this date represents the same point on the
1945
* local time-line as the other date.
1946
* <pre>
1947
* LocalDate a = LocalDate.of(2012, 6, 30);
1948
* LocalDate b = LocalDate.of(2012, 7, 1);
1949
* a.isEqual(b) == false
1950
* a.isEqual(a) == true
1951
* b.isEqual(a) == false
1952
* </pre>
1953
* <p>
1954
* This method only considers the position of the two dates on the local time-line.
1955
* It does not take into account the chronology, or calendar system.
1956
* This is different from the comparison in {@link #compareTo(ChronoLocalDate)}
1957
* but is the same approach as {@link ChronoLocalDate#timeLineOrder()}.
1958
*
1959
* @param other the other date to compare to, not null
1960
* @return true if this date is equal to the specified date
1961
*/
1962
@Override // override for Javadoc and performance
1963
public boolean isEqual(ChronoLocalDate other) {
1964
if (other instanceof LocalDate) {
1965
return compareTo0((LocalDate) other) == 0;
1966
}
1967
return ChronoLocalDate.super.isEqual(other);
1968
}
1969
1970
//-----------------------------------------------------------------------
1971
/**
1972
* Checks if this date is equal to another date.
1973
* <p>
1974
* Compares this {@code LocalDate} with another ensuring that the date is the same.
1975
* <p>
1976
* Only objects of type {@code LocalDate} are compared, other types return false.
1977
* To compare the dates of two {@code TemporalAccessor} instances, including dates
1978
* in two different chronologies, use {@link ChronoField#EPOCH_DAY} as a comparator.
1979
*
1980
* @param obj the object to check, null returns false
1981
* @return true if this is equal to the other date
1982
*/
1983
@Override
1984
public boolean equals(Object obj) {
1985
if (this == obj) {
1986
return true;
1987
}
1988
if (obj instanceof LocalDate) {
1989
return compareTo0((LocalDate) obj) == 0;
1990
}
1991
return false;
1992
}
1993
1994
/**
1995
* A hash code for this date.
1996
*
1997
* @return a suitable hash code
1998
*/
1999
@Override
2000
public int hashCode() {
2001
int yearValue = year;
2002
int monthValue = month;
2003
int dayValue = day;
2004
return (yearValue & 0xFFFFF800) ^ ((yearValue << 11) + (monthValue << 6) + (dayValue));
2005
}
2006
2007
//-----------------------------------------------------------------------
2008
/**
2009
* Outputs this date as a {@code String}, such as {@code 2007-12-03}.
2010
* <p>
2011
* The output will be in the ISO-8601 format {@code uuuu-MM-dd}.
2012
*
2013
* @return a string representation of this date, not null
2014
*/
2015
@Override
2016
public String toString() {
2017
int yearValue = year;
2018
int monthValue = month;
2019
int dayValue = day;
2020
int absYear = Math.abs(yearValue);
2021
StringBuilder buf = new StringBuilder(10);
2022
if (absYear < 1000) {
2023
if (yearValue < 0) {
2024
buf.append(yearValue - 10000).deleteCharAt(1);
2025
} else {
2026
buf.append(yearValue + 10000).deleteCharAt(0);
2027
}
2028
} else {
2029
if (yearValue > 9999) {
2030
buf.append('+');
2031
}
2032
buf.append(yearValue);
2033
}
2034
return buf.append(monthValue < 10 ? "-0" : "-")
2035
.append(monthValue)
2036
.append(dayValue < 10 ? "-0" : "-")
2037
.append(dayValue)
2038
.toString();
2039
}
2040
2041
//-----------------------------------------------------------------------
2042
/**
2043
* Writes the object using a
2044
* <a href="../../serialized-form.html#java.time.Ser">dedicated serialized form</a>.
2045
* @serialData
2046
* <pre>
2047
* out.writeByte(3); // identifies a LocalDate
2048
* out.writeInt(year);
2049
* out.writeByte(month);
2050
* out.writeByte(day);
2051
* </pre>
2052
*
2053
* @return the instance of {@code Ser}, not null
2054
*/
2055
private Object writeReplace() {
2056
return new Ser(Ser.LOCAL_DATE_TYPE, this);
2057
}
2058
2059
/**
2060
* Defend against malicious streams.
2061
*
2062
* @param s the stream to read
2063
* @throws InvalidObjectException always
2064
*/
2065
private void readObject(ObjectInputStream s) throws InvalidObjectException {
2066
throw new InvalidObjectException("Deserialization via serialization delegate");
2067
}
2068
2069
void writeExternal(DataOutput out) throws IOException {
2070
out.writeInt(year);
2071
out.writeByte(month);
2072
out.writeByte(day);
2073
}
2074
2075
static LocalDate readExternal(DataInput in) throws IOException {
2076
int year = in.readInt();
2077
int month = in.readByte();
2078
int dayOfMonth = in.readByte();
2079
return LocalDate.of(year, month, dayOfMonth);
2080
}
2081
2082
}
2083
2084