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/ThaiBuddhistDate.java
38918 views
1
/*
2
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
/*
27
* Copyright (c) 2012, Stephen Colebourne & Michael Nascimento Santos
28
*
29
* All rights reserved.
30
*
31
* Redistribution and use in source and binary forms, with or without
32
* modification, are permitted provided that the following conditions are met:
33
*
34
* * Redistributions of source code must retain the above copyright notice,
35
* this list of conditions and the following disclaimer.
36
*
37
* * Redistributions in binary form must reproduce the above copyright notice,
38
* this list of conditions and the following disclaimer in the documentation
39
* and/or other materials provided with the distribution.
40
*
41
* * Neither the name of JSR-310 nor the names of its contributors
42
* may be used to endorse or promote products derived from this software
43
* without specific prior written permission.
44
*
45
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
46
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
47
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
48
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
49
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
50
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
51
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
52
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
53
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
54
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
55
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
56
*/
57
package java.time.chrono;
58
59
import static java.time.chrono.ThaiBuddhistChronology.YEARS_DIFFERENCE;
60
import static java.time.temporal.ChronoField.DAY_OF_MONTH;
61
import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
62
import static java.time.temporal.ChronoField.YEAR;
63
64
import java.io.DataInput;
65
import java.io.DataOutput;
66
import java.io.IOException;
67
import java.io.InvalidObjectException;
68
import java.io.ObjectInputStream;
69
import java.io.Serializable;
70
import java.time.Clock;
71
import java.time.DateTimeException;
72
import java.time.LocalDate;
73
import java.time.LocalTime;
74
import java.time.Period;
75
import java.time.ZoneId;
76
import java.time.temporal.ChronoField;
77
import java.time.temporal.TemporalAccessor;
78
import java.time.temporal.TemporalAdjuster;
79
import java.time.temporal.TemporalAmount;
80
import java.time.temporal.TemporalField;
81
import java.time.temporal.TemporalQuery;
82
import java.time.temporal.TemporalUnit;
83
import java.time.temporal.UnsupportedTemporalTypeException;
84
import java.time.temporal.ValueRange;
85
import java.util.Objects;
86
87
/**
88
* A date in the Thai Buddhist calendar system.
89
* <p>
90
* This date operates using the {@linkplain ThaiBuddhistChronology Thai Buddhist calendar}.
91
* This calendar system is primarily used in Thailand.
92
* Dates are aligned such that {@code 2484-01-01 (Buddhist)} is {@code 1941-01-01 (ISO)}.
93
*
94
* <p>
95
* This is a <a href="{@docRoot}/java/lang/doc-files/ValueBased.html">value-based</a>
96
* class; use of identity-sensitive operations (including reference equality
97
* ({@code ==}), identity hash code, or synchronization) on instances of
98
* {@code ThaiBuddhistDate} may have unpredictable results and should be avoided.
99
* The {@code equals} method should be used for comparisons.
100
*
101
* @implSpec
102
* This class is immutable and thread-safe.
103
*
104
* @since 1.8
105
*/
106
public final class ThaiBuddhistDate
107
extends ChronoLocalDateImpl<ThaiBuddhistDate>
108
implements ChronoLocalDate, Serializable {
109
110
/**
111
* Serialization version.
112
*/
113
private static final long serialVersionUID = -8722293800195731463L;
114
115
/**
116
* The underlying date.
117
*/
118
private final transient LocalDate isoDate;
119
120
//-----------------------------------------------------------------------
121
/**
122
* Obtains the current {@code ThaiBuddhistDate} from the system clock in the default time-zone.
123
* <p>
124
* This will query the {@link Clock#systemDefaultZone() system clock} in the default
125
* time-zone to obtain the current date.
126
* <p>
127
* Using this method will prevent the ability to use an alternate clock for testing
128
* because the clock is hard-coded.
129
*
130
* @return the current date using the system clock and default time-zone, not null
131
*/
132
public static ThaiBuddhistDate now() {
133
return now(Clock.systemDefaultZone());
134
}
135
136
/**
137
* Obtains the current {@code ThaiBuddhistDate} from the system clock in the specified time-zone.
138
* <p>
139
* This will query the {@link Clock#system(ZoneId) system clock} to obtain the current date.
140
* Specifying the time-zone avoids dependence on the default time-zone.
141
* <p>
142
* Using this method will prevent the ability to use an alternate clock for testing
143
* because the clock is hard-coded.
144
*
145
* @param zone the zone ID to use, not null
146
* @return the current date using the system clock, not null
147
*/
148
public static ThaiBuddhistDate now(ZoneId zone) {
149
return now(Clock.system(zone));
150
}
151
152
/**
153
* Obtains the current {@code ThaiBuddhistDate} from the specified clock.
154
* <p>
155
* This will query the specified clock to obtain the current date - today.
156
* Using this method allows the use of an alternate clock for testing.
157
* The alternate clock may be introduced using {@linkplain Clock dependency injection}.
158
*
159
* @param clock the clock to use, not null
160
* @return the current date, not null
161
* @throws DateTimeException if the current date cannot be obtained
162
*/
163
public static ThaiBuddhistDate now(Clock clock) {
164
return new ThaiBuddhistDate(LocalDate.now(clock));
165
}
166
167
/**
168
* Obtains a {@code ThaiBuddhistDate} representing a date in the Thai Buddhist calendar
169
* system from the proleptic-year, month-of-year and day-of-month fields.
170
* <p>
171
* This returns a {@code ThaiBuddhistDate} with the specified fields.
172
* The day must be valid for the year and month, otherwise an exception will be thrown.
173
*
174
* @param prolepticYear the Thai Buddhist proleptic-year
175
* @param month the Thai Buddhist month-of-year, from 1 to 12
176
* @param dayOfMonth the Thai Buddhist day-of-month, from 1 to 31
177
* @return the date in Thai Buddhist calendar system, not null
178
* @throws DateTimeException if the value of any field is out of range,
179
* or if the day-of-month is invalid for the month-year
180
*/
181
public static ThaiBuddhistDate of(int prolepticYear, int month, int dayOfMonth) {
182
return new ThaiBuddhistDate(LocalDate.of(prolepticYear - YEARS_DIFFERENCE, month, dayOfMonth));
183
}
184
185
/**
186
* Obtains a {@code ThaiBuddhistDate} from a temporal object.
187
* <p>
188
* This obtains a date in the Thai Buddhist calendar system based on the specified temporal.
189
* A {@code TemporalAccessor} represents an arbitrary set of date and time information,
190
* which this factory converts to an instance of {@code ThaiBuddhistDate}.
191
* <p>
192
* The conversion typically uses the {@link ChronoField#EPOCH_DAY EPOCH_DAY}
193
* field, which is standardized across calendar systems.
194
* <p>
195
* This method matches the signature of the functional interface {@link TemporalQuery}
196
* allowing it to be used as a query via method reference, {@code ThaiBuddhistDate::from}.
197
*
198
* @param temporal the temporal object to convert, not null
199
* @return the date in Thai Buddhist calendar system, not null
200
* @throws DateTimeException if unable to convert to a {@code ThaiBuddhistDate}
201
*/
202
public static ThaiBuddhistDate from(TemporalAccessor temporal) {
203
return ThaiBuddhistChronology.INSTANCE.date(temporal);
204
}
205
206
//-----------------------------------------------------------------------
207
/**
208
* Creates an instance from an ISO date.
209
*
210
* @param isoDate the standard local date, validated not null
211
*/
212
ThaiBuddhistDate(LocalDate isoDate) {
213
Objects.requireNonNull(isoDate, "isoDate");
214
this.isoDate = isoDate;
215
}
216
217
//-----------------------------------------------------------------------
218
/**
219
* Gets the chronology of this date, which is the Thai Buddhist calendar system.
220
* <p>
221
* The {@code Chronology} represents the calendar system in use.
222
* The era and other fields in {@link ChronoField} are defined by the chronology.
223
*
224
* @return the Thai Buddhist chronology, not null
225
*/
226
@Override
227
public ThaiBuddhistChronology getChronology() {
228
return ThaiBuddhistChronology.INSTANCE;
229
}
230
231
/**
232
* Gets the era applicable at this date.
233
* <p>
234
* The Thai Buddhist calendar system has two eras, 'BE' and 'BEFORE_BE',
235
* defined by {@link ThaiBuddhistEra}.
236
*
237
* @return the era applicable at this date, not null
238
*/
239
@Override
240
public ThaiBuddhistEra getEra() {
241
return (getProlepticYear() >= 1 ? ThaiBuddhistEra.BE : ThaiBuddhistEra.BEFORE_BE);
242
}
243
244
/**
245
* Returns the length of the month represented by this date.
246
* <p>
247
* This returns the length of the month in days.
248
* Month lengths match those of the ISO calendar system.
249
*
250
* @return the length of the month in days
251
*/
252
@Override
253
public int lengthOfMonth() {
254
return isoDate.lengthOfMonth();
255
}
256
257
//-----------------------------------------------------------------------
258
@Override
259
public ValueRange range(TemporalField field) {
260
if (field instanceof ChronoField) {
261
if (isSupported(field)) {
262
ChronoField f = (ChronoField) field;
263
switch (f) {
264
case DAY_OF_MONTH:
265
case DAY_OF_YEAR:
266
case ALIGNED_WEEK_OF_MONTH:
267
return isoDate.range(field);
268
case YEAR_OF_ERA: {
269
ValueRange range = YEAR.range();
270
long max = (getProlepticYear() <= 0 ? -(range.getMinimum() + YEARS_DIFFERENCE) + 1 : range.getMaximum() + YEARS_DIFFERENCE);
271
return ValueRange.of(1, max);
272
}
273
}
274
return getChronology().range(f);
275
}
276
throw new UnsupportedTemporalTypeException("Unsupported field: " + field);
277
}
278
return field.rangeRefinedBy(this);
279
}
280
281
@Override
282
public long getLong(TemporalField field) {
283
if (field instanceof ChronoField) {
284
switch ((ChronoField) field) {
285
case PROLEPTIC_MONTH:
286
return getProlepticMonth();
287
case YEAR_OF_ERA: {
288
int prolepticYear = getProlepticYear();
289
return (prolepticYear >= 1 ? prolepticYear : 1 - prolepticYear);
290
}
291
case YEAR:
292
return getProlepticYear();
293
case ERA:
294
return (getProlepticYear() >= 1 ? 1 : 0);
295
}
296
return isoDate.getLong(field);
297
}
298
return field.getFrom(this);
299
}
300
301
private long getProlepticMonth() {
302
return getProlepticYear() * 12L + isoDate.getMonthValue() - 1;
303
}
304
305
private int getProlepticYear() {
306
return isoDate.getYear() + YEARS_DIFFERENCE;
307
}
308
309
//-----------------------------------------------------------------------
310
@Override
311
public ThaiBuddhistDate with(TemporalField field, long newValue) {
312
if (field instanceof ChronoField) {
313
ChronoField f = (ChronoField) field;
314
if (getLong(f) == newValue) {
315
return this;
316
}
317
switch (f) {
318
case PROLEPTIC_MONTH:
319
getChronology().range(f).checkValidValue(newValue, f);
320
return plusMonths(newValue - getProlepticMonth());
321
case YEAR_OF_ERA:
322
case YEAR:
323
case ERA: {
324
int nvalue = getChronology().range(f).checkValidIntValue(newValue, f);
325
switch (f) {
326
case YEAR_OF_ERA:
327
return with(isoDate.withYear((getProlepticYear() >= 1 ? nvalue : 1 - nvalue) - YEARS_DIFFERENCE));
328
case YEAR:
329
return with(isoDate.withYear(nvalue - YEARS_DIFFERENCE));
330
case ERA:
331
return with(isoDate.withYear((1 - getProlepticYear()) - YEARS_DIFFERENCE));
332
}
333
}
334
}
335
return with(isoDate.with(field, newValue));
336
}
337
return super.with(field, newValue);
338
}
339
340
/**
341
* {@inheritDoc}
342
* @throws DateTimeException {@inheritDoc}
343
* @throws ArithmeticException {@inheritDoc}
344
*/
345
@Override
346
public ThaiBuddhistDate with(TemporalAdjuster adjuster) {
347
return super.with(adjuster);
348
}
349
350
/**
351
* {@inheritDoc}
352
* @throws DateTimeException {@inheritDoc}
353
* @throws ArithmeticException {@inheritDoc}
354
*/
355
@Override
356
public ThaiBuddhistDate plus(TemporalAmount amount) {
357
return super.plus(amount);
358
}
359
360
/**
361
* {@inheritDoc}
362
* @throws DateTimeException {@inheritDoc}
363
* @throws ArithmeticException {@inheritDoc}
364
*/
365
@Override
366
public ThaiBuddhistDate minus(TemporalAmount amount) {
367
return super.minus(amount);
368
}
369
370
//-----------------------------------------------------------------------
371
@Override
372
ThaiBuddhistDate plusYears(long years) {
373
return with(isoDate.plusYears(years));
374
}
375
376
@Override
377
ThaiBuddhistDate plusMonths(long months) {
378
return with(isoDate.plusMonths(months));
379
}
380
381
@Override
382
ThaiBuddhistDate plusWeeks(long weeksToAdd) {
383
return super.plusWeeks(weeksToAdd);
384
}
385
386
@Override
387
ThaiBuddhistDate plusDays(long days) {
388
return with(isoDate.plusDays(days));
389
}
390
391
@Override
392
public ThaiBuddhistDate plus(long amountToAdd, TemporalUnit unit) {
393
return super.plus(amountToAdd, unit);
394
}
395
396
@Override
397
public ThaiBuddhistDate minus(long amountToAdd, TemporalUnit unit) {
398
return super.minus(amountToAdd, unit);
399
}
400
401
@Override
402
ThaiBuddhistDate minusYears(long yearsToSubtract) {
403
return super.minusYears(yearsToSubtract);
404
}
405
406
@Override
407
ThaiBuddhistDate minusMonths(long monthsToSubtract) {
408
return super.minusMonths(monthsToSubtract);
409
}
410
411
@Override
412
ThaiBuddhistDate minusWeeks(long weeksToSubtract) {
413
return super.minusWeeks(weeksToSubtract);
414
}
415
416
@Override
417
ThaiBuddhistDate minusDays(long daysToSubtract) {
418
return super.minusDays(daysToSubtract);
419
}
420
421
private ThaiBuddhistDate with(LocalDate newDate) {
422
return (newDate.equals(isoDate) ? this : new ThaiBuddhistDate(newDate));
423
}
424
425
@Override // for javadoc and covariant return type
426
@SuppressWarnings("unchecked")
427
public final ChronoLocalDateTime<ThaiBuddhistDate> atTime(LocalTime localTime) {
428
return (ChronoLocalDateTime<ThaiBuddhistDate>) super.atTime(localTime);
429
}
430
431
@Override
432
public ChronoPeriod until(ChronoLocalDate endDate) {
433
Period period = isoDate.until(endDate);
434
return getChronology().period(period.getYears(), period.getMonths(), period.getDays());
435
}
436
437
@Override // override for performance
438
public long toEpochDay() {
439
return isoDate.toEpochDay();
440
}
441
442
//-------------------------------------------------------------------------
443
/**
444
* Compares this date to another date, including the chronology.
445
* <p>
446
* Compares this {@code ThaiBuddhistDate} with another ensuring that the date is the same.
447
* <p>
448
* Only objects of type {@code ThaiBuddhistDate} are compared, other types return false.
449
* To compare the dates of two {@code TemporalAccessor} instances, including dates
450
* in two different chronologies, use {@link ChronoField#EPOCH_DAY} as a comparator.
451
*
452
* @param obj the object to check, null returns false
453
* @return true if this is equal to the other date
454
*/
455
@Override // override for performance
456
public boolean equals(Object obj) {
457
if (this == obj) {
458
return true;
459
}
460
if (obj instanceof ThaiBuddhistDate) {
461
ThaiBuddhistDate otherDate = (ThaiBuddhistDate) obj;
462
return this.isoDate.equals(otherDate.isoDate);
463
}
464
return false;
465
}
466
467
/**
468
* A hash code for this date.
469
*
470
* @return a suitable hash code based only on the Chronology and the date
471
*/
472
@Override // override for performance
473
public int hashCode() {
474
return getChronology().getId().hashCode() ^ isoDate.hashCode();
475
}
476
477
//-----------------------------------------------------------------------
478
/**
479
* Defend against malicious streams.
480
*
481
* @param s the stream to read
482
* @throws InvalidObjectException always
483
*/
484
private void readObject(ObjectInputStream s) throws InvalidObjectException {
485
throw new InvalidObjectException("Deserialization via serialization delegate");
486
}
487
488
/**
489
* Writes the object using a
490
* <a href="../../../serialized-form.html#java.time.chrono.Ser">dedicated serialized form</a>.
491
* @serialData
492
* <pre>
493
* out.writeByte(10); // identifies a ThaiBuddhistDate
494
* out.writeInt(get(YEAR));
495
* out.writeByte(get(MONTH_OF_YEAR));
496
* out.writeByte(get(DAY_OF_MONTH));
497
* </pre>
498
*
499
* @return the instance of {@code Ser}, not null
500
*/
501
private Object writeReplace() {
502
return new Ser(Ser.THAIBUDDHIST_DATE_TYPE, this);
503
}
504
505
void writeExternal(DataOutput out) throws IOException {
506
// ThaiBuddhistChronology is implicit in the THAIBUDDHIST_DATE_TYPE
507
out.writeInt(this.get(YEAR));
508
out.writeByte(this.get(MONTH_OF_YEAR));
509
out.writeByte(this.get(DAY_OF_MONTH));
510
}
511
512
static ThaiBuddhistDate readExternal(DataInput in) throws IOException {
513
int year = in.readInt();
514
int month = in.readByte();
515
int dayOfMonth = in.readByte();
516
return ThaiBuddhistChronology.INSTANCE.date(year, month, dayOfMonth);
517
}
518
519
}
520
521