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/chrono/IsoChronology.java
38918 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) 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.chrono;
63
64
import java.io.InvalidObjectException;
65
import static java.time.temporal.ChronoField.DAY_OF_MONTH;
66
import static java.time.temporal.ChronoField.ERA;
67
import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
68
import static java.time.temporal.ChronoField.PROLEPTIC_MONTH;
69
import static java.time.temporal.ChronoField.YEAR;
70
import static java.time.temporal.ChronoField.YEAR_OF_ERA;
71
72
import java.io.ObjectInputStream;
73
import java.io.Serializable;
74
import java.time.Clock;
75
import java.time.DateTimeException;
76
import java.time.Instant;
77
import java.time.LocalDate;
78
import java.time.LocalDateTime;
79
import java.time.Month;
80
import java.time.Period;
81
import java.time.Year;
82
import java.time.ZoneId;
83
import java.time.ZonedDateTime;
84
import java.time.format.ResolverStyle;
85
import java.time.temporal.ChronoField;
86
import java.time.temporal.TemporalAccessor;
87
import java.time.temporal.TemporalField;
88
import java.time.temporal.ValueRange;
89
import java.util.Arrays;
90
import java.util.List;
91
import java.util.Locale;
92
import java.util.Map;
93
import java.util.Objects;
94
95
/**
96
* The ISO calendar system.
97
* <p>
98
* This chronology defines the rules of the ISO calendar system.
99
* This calendar system is based on the ISO-8601 standard, which is the
100
* <i>de facto</i> world calendar.
101
* <p>
102
* The fields are defined as follows:
103
* <ul>
104
* <li>era - There are two eras, 'Current Era' (CE) and 'Before Current Era' (BCE).
105
* <li>year-of-era - The year-of-era is the same as the proleptic-year for the current CE era.
106
* For the BCE era before the ISO epoch the year increases from 1 upwards as time goes backwards.
107
* <li>proleptic-year - The proleptic year is the same as the year-of-era for the
108
* current era. For the previous era, years have zero, then negative values.
109
* <li>month-of-year - There are 12 months in an ISO year, numbered from 1 to 12.
110
* <li>day-of-month - There are between 28 and 31 days in each of the ISO month, numbered from 1 to 31.
111
* Months 4, 6, 9 and 11 have 30 days, Months 1, 3, 5, 7, 8, 10 and 12 have 31 days.
112
* Month 2 has 28 days, or 29 in a leap year.
113
* <li>day-of-year - There are 365 days in a standard ISO year and 366 in a leap year.
114
* The days are numbered from 1 to 365 or 1 to 366.
115
* <li>leap-year - Leap years occur every 4 years, except where the year is divisble by 100 and not divisble by 400.
116
* </ul>
117
*
118
* @implSpec
119
* This class is immutable and thread-safe.
120
*
121
* @since 1.8
122
*/
123
public final class IsoChronology extends AbstractChronology implements Serializable {
124
125
/**
126
* Singleton instance of the ISO chronology.
127
*/
128
public static final IsoChronology INSTANCE = new IsoChronology();
129
130
/**
131
* Serialization version.
132
*/
133
private static final long serialVersionUID = -1440403870442975015L;
134
135
/**
136
* Restricted constructor.
137
*/
138
private IsoChronology() {
139
}
140
141
//-----------------------------------------------------------------------
142
/**
143
* Gets the ID of the chronology - 'ISO'.
144
* <p>
145
* The ID uniquely identifies the {@code Chronology}.
146
* It can be used to lookup the {@code Chronology} using {@link Chronology#of(String)}.
147
*
148
* @return the chronology ID - 'ISO'
149
* @see #getCalendarType()
150
*/
151
@Override
152
public String getId() {
153
return "ISO";
154
}
155
156
/**
157
* Gets the calendar type of the underlying calendar system - 'iso8601'.
158
* <p>
159
* The calendar type is an identifier defined by the
160
* <em>Unicode Locale Data Markup Language (LDML)</em> specification.
161
* It can be used to lookup the {@code Chronology} using {@link Chronology#of(String)}.
162
* It can also be used as part of a locale, accessible via
163
* {@link Locale#getUnicodeLocaleType(String)} with the key 'ca'.
164
*
165
* @return the calendar system type - 'iso8601'
166
* @see #getId()
167
*/
168
@Override
169
public String getCalendarType() {
170
return "iso8601";
171
}
172
173
//-----------------------------------------------------------------------
174
/**
175
* Obtains an ISO local date from the era, year-of-era, month-of-year
176
* and day-of-month fields.
177
*
178
* @param era the ISO era, not null
179
* @param yearOfEra the ISO year-of-era
180
* @param month the ISO month-of-year
181
* @param dayOfMonth the ISO day-of-month
182
* @return the ISO local date, not null
183
* @throws DateTimeException if unable to create the date
184
* @throws ClassCastException if the type of {@code era} is not {@code IsoEra}
185
*/
186
@Override // override with covariant return type
187
public LocalDate date(Era era, int yearOfEra, int month, int dayOfMonth) {
188
return date(prolepticYear(era, yearOfEra), month, dayOfMonth);
189
}
190
191
/**
192
* Obtains an ISO local date from the proleptic-year, month-of-year
193
* and day-of-month fields.
194
* <p>
195
* This is equivalent to {@link LocalDate#of(int, int, int)}.
196
*
197
* @param prolepticYear the ISO proleptic-year
198
* @param month the ISO month-of-year
199
* @param dayOfMonth the ISO day-of-month
200
* @return the ISO local date, not null
201
* @throws DateTimeException if unable to create the date
202
*/
203
@Override // override with covariant return type
204
public LocalDate date(int prolepticYear, int month, int dayOfMonth) {
205
return LocalDate.of(prolepticYear, month, dayOfMonth);
206
}
207
208
/**
209
* Obtains an ISO local date from the era, year-of-era and day-of-year fields.
210
*
211
* @param era the ISO era, not null
212
* @param yearOfEra the ISO year-of-era
213
* @param dayOfYear the ISO day-of-year
214
* @return the ISO local date, not null
215
* @throws DateTimeException if unable to create the date
216
*/
217
@Override // override with covariant return type
218
public LocalDate dateYearDay(Era era, int yearOfEra, int dayOfYear) {
219
return dateYearDay(prolepticYear(era, yearOfEra), dayOfYear);
220
}
221
222
/**
223
* Obtains an ISO local date from the proleptic-year and day-of-year fields.
224
* <p>
225
* This is equivalent to {@link LocalDate#ofYearDay(int, int)}.
226
*
227
* @param prolepticYear the ISO proleptic-year
228
* @param dayOfYear the ISO day-of-year
229
* @return the ISO local date, not null
230
* @throws DateTimeException if unable to create the date
231
*/
232
@Override // override with covariant return type
233
public LocalDate dateYearDay(int prolepticYear, int dayOfYear) {
234
return LocalDate.ofYearDay(prolepticYear, dayOfYear);
235
}
236
237
/**
238
* Obtains an ISO local date from the epoch-day.
239
* <p>
240
* This is equivalent to {@link LocalDate#ofEpochDay(long)}.
241
*
242
* @param epochDay the epoch day
243
* @return the ISO local date, not null
244
* @throws DateTimeException if unable to create the date
245
*/
246
@Override // override with covariant return type
247
public LocalDate dateEpochDay(long epochDay) {
248
return LocalDate.ofEpochDay(epochDay);
249
}
250
251
//-----------------------------------------------------------------------
252
/**
253
* Obtains an ISO local date from another date-time object.
254
* <p>
255
* This is equivalent to {@link LocalDate#from(TemporalAccessor)}.
256
*
257
* @param temporal the date-time object to convert, not null
258
* @return the ISO local date, not null
259
* @throws DateTimeException if unable to create the date
260
*/
261
@Override // override with covariant return type
262
public LocalDate date(TemporalAccessor temporal) {
263
return LocalDate.from(temporal);
264
}
265
266
/**
267
* Obtains an ISO local date-time from another date-time object.
268
* <p>
269
* This is equivalent to {@link LocalDateTime#from(TemporalAccessor)}.
270
*
271
* @param temporal the date-time object to convert, not null
272
* @return the ISO local date-time, not null
273
* @throws DateTimeException if unable to create the date-time
274
*/
275
@Override // override with covariant return type
276
public LocalDateTime localDateTime(TemporalAccessor temporal) {
277
return LocalDateTime.from(temporal);
278
}
279
280
/**
281
* Obtains an ISO zoned date-time from another date-time object.
282
* <p>
283
* This is equivalent to {@link ZonedDateTime#from(TemporalAccessor)}.
284
*
285
* @param temporal the date-time object to convert, not null
286
* @return the ISO zoned date-time, not null
287
* @throws DateTimeException if unable to create the date-time
288
*/
289
@Override // override with covariant return type
290
public ZonedDateTime zonedDateTime(TemporalAccessor temporal) {
291
return ZonedDateTime.from(temporal);
292
}
293
294
/**
295
* Obtains an ISO zoned date-time in this chronology from an {@code Instant}.
296
* <p>
297
* This is equivalent to {@link ZonedDateTime#ofInstant(Instant, ZoneId)}.
298
*
299
* @param instant the instant to create the date-time from, not null
300
* @param zone the time-zone, not null
301
* @return the zoned date-time, not null
302
* @throws DateTimeException if the result exceeds the supported range
303
*/
304
@Override
305
public ZonedDateTime zonedDateTime(Instant instant, ZoneId zone) {
306
return ZonedDateTime.ofInstant(instant, zone);
307
}
308
309
//-----------------------------------------------------------------------
310
/**
311
* Obtains the current ISO local date from the system clock in the default time-zone.
312
* <p>
313
* This will query the {@link Clock#systemDefaultZone() system clock} in the default
314
* time-zone to obtain the current date.
315
* <p>
316
* Using this method will prevent the ability to use an alternate clock for testing
317
* because the clock is hard-coded.
318
*
319
* @return the current ISO local date using the system clock and default time-zone, not null
320
* @throws DateTimeException if unable to create the date
321
*/
322
@Override // override with covariant return type
323
public LocalDate dateNow() {
324
return dateNow(Clock.systemDefaultZone());
325
}
326
327
/**
328
* Obtains the current ISO local date from the system clock in the specified time-zone.
329
* <p>
330
* This will query the {@link Clock#system(ZoneId) system clock} to obtain the current date.
331
* Specifying the time-zone avoids dependence on the default time-zone.
332
* <p>
333
* Using this method will prevent the ability to use an alternate clock for testing
334
* because the clock is hard-coded.
335
*
336
* @return the current ISO local date using the system clock, not null
337
* @throws DateTimeException if unable to create the date
338
*/
339
@Override // override with covariant return type
340
public LocalDate dateNow(ZoneId zone) {
341
return dateNow(Clock.system(zone));
342
}
343
344
/**
345
* Obtains the current ISO local date from the specified clock.
346
* <p>
347
* This will query the specified clock to obtain the current date - today.
348
* Using this method allows the use of an alternate clock for testing.
349
* The alternate clock may be introduced using {@link Clock dependency injection}.
350
*
351
* @param clock the clock to use, not null
352
* @return the current ISO local date, not null
353
* @throws DateTimeException if unable to create the date
354
*/
355
@Override // override with covariant return type
356
public LocalDate dateNow(Clock clock) {
357
Objects.requireNonNull(clock, "clock");
358
return date(LocalDate.now(clock));
359
}
360
361
//-----------------------------------------------------------------------
362
/**
363
* Checks if the year is a leap year, according to the ISO proleptic
364
* calendar system rules.
365
* <p>
366
* This method applies the current rules for leap years across the whole time-line.
367
* In general, a year is a leap year if it is divisible by four without
368
* remainder. However, years divisible by 100, are not leap years, with
369
* the exception of years divisible by 400 which are.
370
* <p>
371
* For example, 1904 is a leap year it is divisible by 4.
372
* 1900 was not a leap year as it is divisible by 100, however 2000 was a
373
* leap year as it is divisible by 400.
374
* <p>
375
* The calculation is proleptic - applying the same rules into the far future and far past.
376
* This is historically inaccurate, but is correct for the ISO-8601 standard.
377
*
378
* @param prolepticYear the ISO proleptic year to check
379
* @return true if the year is leap, false otherwise
380
*/
381
@Override
382
public boolean isLeapYear(long prolepticYear) {
383
return ((prolepticYear & 3) == 0) && ((prolepticYear % 100) != 0 || (prolepticYear % 400) == 0);
384
}
385
386
@Override
387
public int prolepticYear(Era era, int yearOfEra) {
388
if (era instanceof IsoEra == false) {
389
throw new ClassCastException("Era must be IsoEra");
390
}
391
return (era == IsoEra.CE ? yearOfEra : 1 - yearOfEra);
392
}
393
394
@Override
395
public IsoEra eraOf(int eraValue) {
396
return IsoEra.of(eraValue);
397
}
398
399
@Override
400
public List<Era> eras() {
401
return Arrays.<Era>asList(IsoEra.values());
402
}
403
404
//-----------------------------------------------------------------------
405
/**
406
* Resolves parsed {@code ChronoField} values into a date during parsing.
407
* <p>
408
* Most {@code TemporalField} implementations are resolved using the
409
* resolve method on the field. By contrast, the {@code ChronoField} class
410
* defines fields that only have meaning relative to the chronology.
411
* As such, {@code ChronoField} date fields are resolved here in the
412
* context of a specific chronology.
413
* <p>
414
* {@code ChronoField} instances on the ISO calendar system are resolved
415
* as follows.
416
* <ul>
417
* <li>{@code EPOCH_DAY} - If present, this is converted to a {@code LocalDate}
418
* and all other date fields are then cross-checked against the date.
419
* <li>{@code PROLEPTIC_MONTH} - If present, then it is split into the
420
* {@code YEAR} and {@code MONTH_OF_YEAR}. If the mode is strict or smart
421
* then the field is validated.
422
* <li>{@code YEAR_OF_ERA} and {@code ERA} - If both are present, then they
423
* are combined to form a {@code YEAR}. In lenient mode, the {@code YEAR_OF_ERA}
424
* range is not validated, in smart and strict mode it is. The {@code ERA} is
425
* validated for range in all three modes. If only the {@code YEAR_OF_ERA} is
426
* present, and the mode is smart or lenient, then the current era (CE/AD)
427
* is assumed. In strict mode, no era is assumed and the {@code YEAR_OF_ERA} is
428
* left untouched. If only the {@code ERA} is present, then it is left untouched.
429
* <li>{@code YEAR}, {@code MONTH_OF_YEAR} and {@code DAY_OF_MONTH} -
430
* If all three are present, then they are combined to form a {@code LocalDate}.
431
* In all three modes, the {@code YEAR} is validated. If the mode is smart or strict,
432
* then the month and day are validated, with the day validated from 1 to 31.
433
* If the mode is lenient, then the date is combined in a manner equivalent to
434
* creating a date on the first of January in the requested year, then adding
435
* the difference in months, then the difference in days.
436
* If the mode is smart, and the day-of-month is greater than the maximum for
437
* the year-month, then the day-of-month is adjusted to the last day-of-month.
438
* If the mode is strict, then the three fields must form a valid date.
439
* <li>{@code YEAR} and {@code DAY_OF_YEAR} -
440
* If both are present, then they are combined to form a {@code LocalDate}.
441
* In all three modes, the {@code YEAR} is validated.
442
* If the mode is lenient, then the date is combined in a manner equivalent to
443
* creating a date on the first of January in the requested year, then adding
444
* the difference in days.
445
* If the mode is smart or strict, then the two fields must form a valid date.
446
* <li>{@code YEAR}, {@code MONTH_OF_YEAR}, {@code ALIGNED_WEEK_OF_MONTH} and
447
* {@code ALIGNED_DAY_OF_WEEK_IN_MONTH} -
448
* If all four are present, then they are combined to form a {@code LocalDate}.
449
* In all three modes, the {@code YEAR} is validated.
450
* If the mode is lenient, then the date is combined in a manner equivalent to
451
* creating a date on the first of January in the requested year, then adding
452
* the difference in months, then the difference in weeks, then in days.
453
* If the mode is smart or strict, then the all four fields are validated to
454
* their outer ranges. The date is then combined in a manner equivalent to
455
* creating a date on the first day of the requested year and month, then adding
456
* the amount in weeks and days to reach their values. If the mode is strict,
457
* the date is additionally validated to check that the day and week adjustment
458
* did not change the month.
459
* <li>{@code YEAR}, {@code MONTH_OF_YEAR}, {@code ALIGNED_WEEK_OF_MONTH} and
460
* {@code DAY_OF_WEEK} - If all four are present, then they are combined to
461
* form a {@code LocalDate}. The approach is the same as described above for
462
* years, months and weeks in {@code ALIGNED_DAY_OF_WEEK_IN_MONTH}.
463
* The day-of-week is adjusted as the next or same matching day-of-week once
464
* the years, months and weeks have been handled.
465
* <li>{@code YEAR}, {@code ALIGNED_WEEK_OF_YEAR} and {@code ALIGNED_DAY_OF_WEEK_IN_YEAR} -
466
* If all three are present, then they are combined to form a {@code LocalDate}.
467
* In all three modes, the {@code YEAR} is validated.
468
* If the mode is lenient, then the date is combined in a manner equivalent to
469
* creating a date on the first of January in the requested year, then adding
470
* the difference in weeks, then in days.
471
* If the mode is smart or strict, then the all three fields are validated to
472
* their outer ranges. The date is then combined in a manner equivalent to
473
* creating a date on the first day of the requested year, then adding
474
* the amount in weeks and days to reach their values. If the mode is strict,
475
* the date is additionally validated to check that the day and week adjustment
476
* did not change the year.
477
* <li>{@code YEAR}, {@code ALIGNED_WEEK_OF_YEAR} and {@code DAY_OF_WEEK} -
478
* If all three are present, then they are combined to form a {@code LocalDate}.
479
* The approach is the same as described above for years and weeks in
480
* {@code ALIGNED_DAY_OF_WEEK_IN_YEAR}. The day-of-week is adjusted as the
481
* next or same matching day-of-week once the years and weeks have been handled.
482
* </ul>
483
*
484
* @param fieldValues the map of fields to values, which can be updated, not null
485
* @param resolverStyle the requested type of resolve, not null
486
* @return the resolved date, null if insufficient information to create a date
487
* @throws DateTimeException if the date cannot be resolved, typically
488
* because of a conflict in the input data
489
*/
490
@Override // override for performance
491
public LocalDate resolveDate(Map<TemporalField, Long> fieldValues, ResolverStyle resolverStyle) {
492
return (LocalDate) super.resolveDate(fieldValues, resolverStyle);
493
}
494
495
@Override // override for better proleptic algorithm
496
void resolveProlepticMonth(Map<TemporalField, Long> fieldValues, ResolverStyle resolverStyle) {
497
Long pMonth = fieldValues.remove(PROLEPTIC_MONTH);
498
if (pMonth != null) {
499
if (resolverStyle != ResolverStyle.LENIENT) {
500
PROLEPTIC_MONTH.checkValidValue(pMonth);
501
}
502
addFieldValue(fieldValues, MONTH_OF_YEAR, Math.floorMod(pMonth, 12) + 1);
503
addFieldValue(fieldValues, YEAR, Math.floorDiv(pMonth, 12));
504
}
505
}
506
507
@Override // override for enhanced behaviour
508
LocalDate resolveYearOfEra(Map<TemporalField, Long> fieldValues, ResolverStyle resolverStyle) {
509
Long yoeLong = fieldValues.remove(YEAR_OF_ERA);
510
if (yoeLong != null) {
511
if (resolverStyle != ResolverStyle.LENIENT) {
512
YEAR_OF_ERA.checkValidValue(yoeLong);
513
}
514
Long era = fieldValues.remove(ERA);
515
if (era == null) {
516
Long year = fieldValues.get(YEAR);
517
if (resolverStyle == ResolverStyle.STRICT) {
518
// do not invent era if strict, but do cross-check with year
519
if (year != null) {
520
addFieldValue(fieldValues, YEAR, (year > 0 ? yoeLong: Math.subtractExact(1, yoeLong)));
521
} else {
522
// reinstate the field removed earlier, no cross-check issues
523
fieldValues.put(YEAR_OF_ERA, yoeLong);
524
}
525
} else {
526
// invent era
527
addFieldValue(fieldValues, YEAR, (year == null || year > 0 ? yoeLong: Math.subtractExact(1, yoeLong)));
528
}
529
} else if (era.longValue() == 1L) {
530
addFieldValue(fieldValues, YEAR, yoeLong);
531
} else if (era.longValue() == 0L) {
532
addFieldValue(fieldValues, YEAR, Math.subtractExact(1, yoeLong));
533
} else {
534
throw new DateTimeException("Invalid value for era: " + era);
535
}
536
} else if (fieldValues.containsKey(ERA)) {
537
ERA.checkValidValue(fieldValues.get(ERA)); // always validated
538
}
539
return null;
540
}
541
542
@Override // override for performance
543
LocalDate resolveYMD(Map <TemporalField, Long> fieldValues, ResolverStyle resolverStyle) {
544
int y = YEAR.checkValidIntValue(fieldValues.remove(YEAR));
545
if (resolverStyle == ResolverStyle.LENIENT) {
546
long months = Math.subtractExact(fieldValues.remove(MONTH_OF_YEAR), 1);
547
long days = Math.subtractExact(fieldValues.remove(DAY_OF_MONTH), 1);
548
return LocalDate.of(y, 1, 1).plusMonths(months).plusDays(days);
549
}
550
int moy = MONTH_OF_YEAR.checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR));
551
int dom = DAY_OF_MONTH.checkValidIntValue(fieldValues.remove(DAY_OF_MONTH));
552
if (resolverStyle == ResolverStyle.SMART) { // previous valid
553
if (moy == 4 || moy == 6 || moy == 9 || moy == 11) {
554
dom = Math.min(dom, 30);
555
} else if (moy == 2) {
556
dom = Math.min(dom, Month.FEBRUARY.length(Year.isLeap(y)));
557
558
}
559
}
560
return LocalDate.of(y, moy, dom);
561
}
562
563
//-----------------------------------------------------------------------
564
@Override
565
public ValueRange range(ChronoField field) {
566
return field.range();
567
}
568
569
//-----------------------------------------------------------------------
570
/**
571
* Obtains a period for this chronology based on years, months and days.
572
* <p>
573
* This returns a period tied to the ISO chronology using the specified
574
* years, months and days. See {@link Period} for further details.
575
*
576
* @param years the number of years, may be negative
577
* @param months the number of years, may be negative
578
* @param days the number of years, may be negative
579
* @return the period in terms of this chronology, not null
580
* @return the ISO period, not null
581
*/
582
@Override // override with covariant return type
583
public Period period(int years, int months, int days) {
584
return Period.of(years, months, days);
585
}
586
587
//-----------------------------------------------------------------------
588
/**
589
* Writes the Chronology using a
590
* <a href="../../../serialized-form.html#java.time.chrono.Ser">dedicated serialized form</a>.
591
* @serialData
592
* <pre>
593
* out.writeByte(1); // identifies a Chronology
594
* out.writeUTF(getId());
595
* </pre>
596
*
597
* @return the instance of {@code Ser}, not null
598
*/
599
@Override
600
Object writeReplace() {
601
return super.writeReplace();
602
}
603
604
/**
605
* Defend against malicious streams.
606
*
607
* @param s the stream to read
608
* @throws InvalidObjectException always
609
*/
610
private void readObject(ObjectInputStream s) throws InvalidObjectException {
611
throw new InvalidObjectException("Deserialization via serialization delegate");
612
}
613
}
614
615