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.temporal.ChronoField.DAY_OF_MONTH;
60 import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
61 import static java.time.temporal.ChronoField.YEAR;
62
63 import java.io.DataInput;
64 import java.io.DataOutput;
65 import java.io.IOException;
66 import java.io.Serializable;
67 import java.time.Clock;
68 import java.time.DateTimeException;
69 import java.time.LocalDate;
70 import java.time.LocalTime;
71 import java.time.Period;
72 import java.time.ZoneId;
73 import java.time.temporal.ChronoField;
74 import java.time.temporal.TemporalQuery;
75 import java.time.temporal.TemporalAccessor;
76 import java.time.temporal.TemporalAdjuster;
77 import java.time.temporal.TemporalAmount;
78 import java.time.temporal.TemporalField;
79 import java.time.temporal.TemporalUnit;
80 import java.time.temporal.ValueRange;
81 import java.util.Calendar;
82 import java.util.Objects;
83
84 import sun.util.calendar.LocalGregorianCalendar;
85
86 /**
87 * A date in the Japanese Imperial calendar system.
88 * <p>
89 * This date operates using the {@linkplain JapaneseChronology Japanese Imperial calendar}.
90 * This calendar system is primarily used in Japan.
91 * <p>
92 * The Japanese Imperial calendar system is the same as the ISO calendar system
93 * apart from the era-based year numbering. The proleptic-year is defined to be
94 * equal to the ISO proleptic-year.
95 * <p>
96 * For example, the Japanese year "Heisei 24" corresponds to ISO year "2012".<br>
97 * Calling {@code japaneseDate.get(YEAR_OF_ERA)} will return 24.<br>
98 * Calling {@code japaneseDate.get(YEAR)} will return 2012.<br>
99 * Calling {@code japaneseDate.get(ERA)} will return 2, corresponding to
174 }
175
176 /**
177 * Obtains a {@code JapaneseDate} representing a date in the Japanese calendar
178 * system from the era, year-of-era, month-of-year and day-of-month fields.
179 * <p>
180 * This returns a {@code JapaneseDate} with the specified fields.
181 * The day must be valid for the year and month, otherwise an exception will be thrown.
182 *
183 * @param era the Japanese era, not null
184 * @param yearOfEra the Japanese year-of-era
185 * @param month the Japanese month-of-year, from 1 to 12
186 * @param dayOfMonth the Japanese day-of-month, from 1 to 31
187 * @return the date in Japanese calendar system, not null
188 * @throws DateTimeException if the value of any field is out of range,
189 * or if the day-of-month is invalid for the month-year,
190 * or if the date is not a Japanese era
191 */
192 public static JapaneseDate of(Era era, int yearOfEra, int month, int dayOfMonth) {
193 if (era instanceof JapaneseEra == false) {
194 throw new DateTimeException("Era must be JapaneseEra");
195 }
196 return JapaneseDate.of((JapaneseEra) era, yearOfEra, month, dayOfMonth);
197 }
198
199 /**
200 * Obtains a {@code JapaneseDate} representing a date in the Japanese calendar
201 * system from the proleptic-year, month-of-year and day-of-month fields.
202 * <p>
203 * This returns a {@code JapaneseDate} with the specified fields.
204 * The day must be valid for the year and month, otherwise an exception will be thrown.
205 *
206 * @param prolepticYear the Japanese proleptic-year
207 * @param month the Japanese month-of-year, from 1 to 12
208 * @param dayOfMonth the Japanese day-of-month, from 1 to 31
209 * @return the date in Japanese calendar system, not null
210 * @throws DateTimeException if the value of any field is out of range,
211 * or if the day-of-month is invalid for the month-year
212 */
213 public static JapaneseDate of(int prolepticYear, int month, int dayOfMonth) {
214 return new JapaneseDate(LocalDate.of(prolepticYear, month, dayOfMonth));
235 /**
236 * Obtains a {@code JapaneseDate} representing a date in the Japanese calendar
237 * system from the era, year-of-era, month-of-year and day-of-month fields.
238 * <p>
239 * This returns a {@code JapaneseDate} with the specified fields.
240 * The day must be valid for the year and month, otherwise an exception will be thrown.
241 *
242 * @param era the Japanese era, not null
243 * @param yearOfEra the Japanese year-of-era
244 * @param month the Japanese month-of-year, from 1 to 12
245 * @param dayOfMonth the Japanese day-of-month, from 1 to 31
246 * @return the date in Japanese calendar system, not null
247 * @throws DateTimeException if the value of any field is out of range,
248 * or if the day-of-month is invalid for the month-year
249 */
250 static JapaneseDate of(JapaneseEra era, int yearOfEra, int month, int dayOfMonth) {
251 Objects.requireNonNull(era, "era");
252 LocalGregorianCalendar.Date jdate = JapaneseChronology.JCAL.newCalendarDate(null);
253 jdate.setEra(era.getPrivateEra()).setDate(yearOfEra, month, dayOfMonth);
254 if (!JapaneseChronology.JCAL.validate(jdate)) {
255 throw new IllegalArgumentException();
256 }
257 LocalDate date = LocalDate.of(jdate.getNormalizedYear(), month, dayOfMonth);
258 return new JapaneseDate(era, yearOfEra, date);
259 }
260
261 /**
262 * Obtains a {@code JapaneseDate} from a temporal object.
263 * <p>
264 * This obtains a date in the Japanese calendar system based on the specified temporal.
265 * A {@code TemporalAccessor} represents an arbitrary set of date and time information,
266 * which this factory converts to an instance of {@code JapaneseDate}.
267 * <p>
268 * The conversion typically uses the {@link ChronoField#EPOCH_DAY EPOCH_DAY}
269 * field, which is standardized across calendar systems.
270 * <p>
271 * This method matches the signature of the functional interface {@link TemporalQuery}
272 * allowing it to be used as a query via method reference, {@code JapaneseDate::from}.
273 *
274 * @param temporal the temporal object to convert, not null
275 * @return the date in Japanese calendar system, not null
290 this.era = JapaneseEra.toJapaneseEra(jdate.getEra());
291 this.yearOfEra = jdate.getYear();
292 this.isoDate = isoDate;
293 }
294
295 /**
296 * Constructs a {@code JapaneseDate}. This constructor does NOT validate the given parameters,
297 * and {@code era} and {@code year} must agree with {@code isoDate}.
298 *
299 * @param era the era, validated not null
300 * @param year the year-of-era, validated
301 * @param isoDate the standard local date, validated not null
302 */
303 JapaneseDate(JapaneseEra era, int year, LocalDate isoDate) {
304 this.era = era;
305 this.yearOfEra = year;
306 this.isoDate = isoDate;
307 }
308
309 //-----------------------------------------------------------------------
310 @Override
311 public JapaneseChronology getChronology() {
312 return JapaneseChronology.INSTANCE;
313 }
314
315 @Override
316 public int lengthOfMonth() {
317 return isoDate.lengthOfMonth();
318 }
319
320 @Override
321 public ValueRange range(TemporalField field) {
322 if (field instanceof ChronoField) {
323 if (isSupported(field)) {
324 ChronoField f = (ChronoField) field;
325 switch (f) {
326 case DAY_OF_YEAR:
327 return actualRange(Calendar.DAY_OF_YEAR);
328 case YEAR_OF_ERA:
329 return actualRange(Calendar.YEAR);
330 }
331 return getChronology().range(f);
332 }
333 throw new DateTimeException("Unsupported field: " + field.getName());
334 }
335 return field.rangeRefinedBy(this);
336 }
337
338 private ValueRange actualRange(int calendarField) {
339 Calendar jcal = Calendar.getInstance(JapaneseChronology.LOCALE);
340 jcal.set(Calendar.ERA, era.getValue() + JapaneseEra.ERA_OFFSET);
341 jcal.set(yearOfEra, isoDate.getMonthValue() - 1, isoDate.getDayOfMonth());
342 return ValueRange.of(jcal.getActualMinimum(calendarField),
343 jcal.getActualMaximum(calendarField));
344 }
345
346 @Override
347 public long getLong(TemporalField field) {
348 if (field instanceof ChronoField) {
349 switch ((ChronoField) field) {
350 case YEAR_OF_ERA:
351 return yearOfEra;
352 case ERA:
353 return era.getValue();
354 case DAY_OF_YEAR: {
355 LocalGregorianCalendar.Date jdate = toPrivateJapaneseDate(isoDate);
356 return JapaneseChronology.JCAL.getDayOfYear(jdate);
357 }
358 }
359 // TODO: review other fields
360 return isoDate.getLong(field);
361 }
362 return field.getFrom(this);
363 }
364
365 /**
366 * Returns a {@code LocalGregorianCalendar.Date} converted from the given {@code isoDate}.
367 *
368 * @param isoDate the local date, not null
369 * @return a {@code LocalGregorianCalendar.Date}, not null
370 */
371 private static LocalGregorianCalendar.Date toPrivateJapaneseDate(LocalDate isoDate) {
372 LocalGregorianCalendar.Date jdate = JapaneseChronology.JCAL.newCalendarDate(null);
373 sun.util.calendar.Era sunEra = JapaneseEra.privateEraFrom(isoDate);
374 int year = isoDate.getYear();
375 if (sunEra != null) {
376 year -= sunEra.getSinceDate().getYear() - 1;
377 }
378 jdate.setEra(sunEra).setYear(year).setMonth(isoDate.getMonthValue()).setDayOfMonth(isoDate.getDayOfMonth());
379 JapaneseChronology.JCAL.normalize(jdate);
380 return jdate;
381 }
382
383 //-----------------------------------------------------------------------
384 @Override
385 public JapaneseDate with(TemporalField field, long newValue) {
386 if (field instanceof ChronoField) {
387 ChronoField f = (ChronoField) field;
388 if (getLong(f) == newValue) {
389 return this;
390 }
391 switch (f) {
392 case YEAR_OF_ERA:
393 case YEAR:
394 case ERA: {
395 f.checkValidValue(newValue);
396 int nvalue = (int) newValue;
397 switch (f) {
398 case YEAR_OF_ERA:
399 return this.withYear(nvalue);
400 case YEAR:
401 return with(isoDate.withYear(nvalue));
402 case ERA: {
403 return this.withYear(JapaneseEra.of(nvalue), yearOfEra);
404 }
405 }
406 }
407 }
408 // TODO: review other fields, such as WEEK_OF_YEAR
409 return with(isoDate.with(field, newValue));
410 }
411 return (JapaneseDate) ChronoLocalDate.super.with(field, newValue);
412 }
413
414 @Override
415 public Era getEra() {
416 return era;
417 }
418
419 /**
420 * {@inheritDoc}
421 * @throws DateTimeException {@inheritDoc}
422 * @throws ArithmeticException {@inheritDoc}
423 */
424 @Override
425 public JapaneseDate with(TemporalAdjuster adjuster) {
426 return (JapaneseDate)super.with(adjuster);
427 }
428
429 /**
430 * {@inheritDoc}
431 * @throws DateTimeException {@inheritDoc}
432 * @throws ArithmeticException {@inheritDoc}
433 */
434 @Override
435 public JapaneseDate plus(TemporalAmount amount) {
436 return (JapaneseDate)super.plus(amount);
437 }
438
439 /**
440 * {@inheritDoc}
441 * @throws DateTimeException {@inheritDoc}
442 * @throws ArithmeticException {@inheritDoc}
443 */
444 @Override
445 public JapaneseDate minus(TemporalAmount amount) {
446 return (JapaneseDate)super.minus(amount);
447 }
448 //-----------------------------------------------------------------------
449 /**
450 * Returns a copy of this date with the year altered.
451 * <p>
452 * This method changes the year of the date.
453 * If the month-day is invalid for the year, then the previous valid day
454 * will be selected instead.
455 * <p>
456 * This instance is immutable and unaffected by this method call.
457 *
458 * @param era the era to set in the result, not null
459 * @param yearOfEra the year-of-era to set in the returned date
460 * @return a {@code JapaneseDate} based on this date with the requested year, never null
461 * @throws DateTimeException if {@code year} is invalid
462 */
463 private JapaneseDate withYear(JapaneseEra era, int yearOfEra) {
464 int year = JapaneseChronology.INSTANCE.prolepticYear(era, yearOfEra);
465 return with(isoDate.withYear(year));
466 }
467
468 /**
469 * Returns a copy of this date with the year-of-era altered.
470 * <p>
471 * This method changes the year-of-era of the date.
472 * If the month-day is invalid for the year, then the previous valid day
473 * will be selected instead.
474 * <p>
475 * This instance is immutable and unaffected by this method call.
476 *
477 * @param year the year to set in the returned date
478 * @return a {@code JapaneseDate} based on this date with the requested year-of-era, never null
479 * @throws DateTimeException if {@code year} is invalid
480 */
481 private JapaneseDate withYear(int year) {
482 return withYear((JapaneseEra) getEra(), year);
483 }
484
485 //-----------------------------------------------------------------------
486 @Override
487 JapaneseDate plusYears(long years) {
488 return with(isoDate.plusYears(years));
489 }
490
491 @Override
492 JapaneseDate plusMonths(long months) {
493 return with(isoDate.plusMonths(months));
494 }
495
496 @Override
497 JapaneseDate plusWeeks(long weeksToAdd) {
498 return with(isoDate.plusWeeks(weeksToAdd));
499 }
500
501 @Override
502 JapaneseDate plusDays(long days) {
503 return with(isoDate.plusDays(days));
504 }
505
506 @Override
507 public JapaneseDate plus(long amountToAdd, TemporalUnit unit) {
508 return (JapaneseDate)super.plus(amountToAdd, unit);
509 }
510
511 @Override
512 public JapaneseDate minus(long amountToAdd, TemporalUnit unit) {
513 return (JapaneseDate)super.minus(amountToAdd, unit);
514 }
515
516 @Override
517 JapaneseDate minusYears(long yearsToSubtract) {
518 return (JapaneseDate)super.minusYears(yearsToSubtract);
519 }
520
521 @Override
522 JapaneseDate minusMonths(long monthsToSubtract) {
523 return (JapaneseDate)super.minusMonths(monthsToSubtract);
524 }
525
526 @Override
527 JapaneseDate minusWeeks(long weeksToSubtract) {
528 return (JapaneseDate)super.minusWeeks(weeksToSubtract);
529 }
530
531 @Override
532 JapaneseDate minusDays(long daysToSubtract) {
533 return (JapaneseDate)super.minusDays(daysToSubtract);
534 }
535
536 private JapaneseDate with(LocalDate newDate) {
537 return (newDate.equals(isoDate) ? this : new JapaneseDate(newDate));
538 }
539
540 @Override // for javadoc and covariant return type
541 public final ChronoLocalDateTime<JapaneseDate> atTime(LocalTime localTime) {
542 return (ChronoLocalDateTime<JapaneseDate>)super.atTime(localTime);
543 }
544
545 @Override
546 public Period periodUntil(ChronoLocalDate<?> endDate) {
547 return isoDate.periodUntil(endDate);
548 }
549
550 @Override // override for performance
551 public long toEpochDay() {
552 return isoDate.toEpochDay();
553 }
554
555 //-------------------------------------------------------------------------
556 @Override // override for performance
557 public boolean equals(Object obj) {
558 if (this == obj) {
559 return true;
560 }
561 if (obj instanceof JapaneseDate) {
562 JapaneseDate otherDate = (JapaneseDate) obj;
|
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.temporal.ChronoField.DAY_OF_MONTH;
60 import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
61 import static java.time.temporal.ChronoField.YEAR;
62
63 import java.io.DataInput;
64 import java.io.DataOutput;
65 import java.io.IOException;
66 import java.io.Serializable;
67 import java.time.Clock;
68 import java.time.DateTimeException;
69 import java.time.LocalDate;
70 import java.time.LocalTime;
71 import java.time.Period;
72 import java.time.Year;
73 import java.time.ZoneId;
74 import java.time.temporal.ChronoField;
75 import java.time.temporal.TemporalAccessor;
76 import java.time.temporal.TemporalAdjuster;
77 import java.time.temporal.TemporalAmount;
78 import java.time.temporal.TemporalField;
79 import java.time.temporal.TemporalQuery;
80 import java.time.temporal.TemporalUnit;
81 import java.time.temporal.UnsupportedTemporalTypeException;
82 import java.time.temporal.ValueRange;
83 import java.util.Calendar;
84 import java.util.Objects;
85
86 import sun.util.calendar.LocalGregorianCalendar;
87
88 /**
89 * A date in the Japanese Imperial calendar system.
90 * <p>
91 * This date operates using the {@linkplain JapaneseChronology Japanese Imperial calendar}.
92 * This calendar system is primarily used in Japan.
93 * <p>
94 * The Japanese Imperial calendar system is the same as the ISO calendar system
95 * apart from the era-based year numbering. The proleptic-year is defined to be
96 * equal to the ISO proleptic-year.
97 * <p>
98 * For example, the Japanese year "Heisei 24" corresponds to ISO year "2012".<br>
99 * Calling {@code japaneseDate.get(YEAR_OF_ERA)} will return 24.<br>
100 * Calling {@code japaneseDate.get(YEAR)} will return 2012.<br>
101 * Calling {@code japaneseDate.get(ERA)} will return 2, corresponding to
176 }
177
178 /**
179 * Obtains a {@code JapaneseDate} representing a date in the Japanese calendar
180 * system from the era, year-of-era, month-of-year and day-of-month fields.
181 * <p>
182 * This returns a {@code JapaneseDate} with the specified fields.
183 * The day must be valid for the year and month, otherwise an exception will be thrown.
184 *
185 * @param era the Japanese era, not null
186 * @param yearOfEra the Japanese year-of-era
187 * @param month the Japanese month-of-year, from 1 to 12
188 * @param dayOfMonth the Japanese day-of-month, from 1 to 31
189 * @return the date in Japanese calendar system, not null
190 * @throws DateTimeException if the value of any field is out of range,
191 * or if the day-of-month is invalid for the month-year,
192 * or if the date is not a Japanese era
193 */
194 public static JapaneseDate of(Era era, int yearOfEra, int month, int dayOfMonth) {
195 if (era instanceof JapaneseEra == false) {
196 throw new ClassCastException("Era must be JapaneseEra");
197 }
198 return JapaneseDate.of((JapaneseEra) era, yearOfEra, month, dayOfMonth);
199 }
200
201 /**
202 * Obtains a {@code JapaneseDate} representing a date in the Japanese calendar
203 * system from the proleptic-year, month-of-year and day-of-month fields.
204 * <p>
205 * This returns a {@code JapaneseDate} with the specified fields.
206 * The day must be valid for the year and month, otherwise an exception will be thrown.
207 *
208 * @param prolepticYear the Japanese proleptic-year
209 * @param month the Japanese month-of-year, from 1 to 12
210 * @param dayOfMonth the Japanese day-of-month, from 1 to 31
211 * @return the date in Japanese calendar system, not null
212 * @throws DateTimeException if the value of any field is out of range,
213 * or if the day-of-month is invalid for the month-year
214 */
215 public static JapaneseDate of(int prolepticYear, int month, int dayOfMonth) {
216 return new JapaneseDate(LocalDate.of(prolepticYear, month, dayOfMonth));
237 /**
238 * Obtains a {@code JapaneseDate} representing a date in the Japanese calendar
239 * system from the era, year-of-era, month-of-year and day-of-month fields.
240 * <p>
241 * This returns a {@code JapaneseDate} with the specified fields.
242 * The day must be valid for the year and month, otherwise an exception will be thrown.
243 *
244 * @param era the Japanese era, not null
245 * @param yearOfEra the Japanese year-of-era
246 * @param month the Japanese month-of-year, from 1 to 12
247 * @param dayOfMonth the Japanese day-of-month, from 1 to 31
248 * @return the date in Japanese calendar system, not null
249 * @throws DateTimeException if the value of any field is out of range,
250 * or if the day-of-month is invalid for the month-year
251 */
252 static JapaneseDate of(JapaneseEra era, int yearOfEra, int month, int dayOfMonth) {
253 Objects.requireNonNull(era, "era");
254 LocalGregorianCalendar.Date jdate = JapaneseChronology.JCAL.newCalendarDate(null);
255 jdate.setEra(era.getPrivateEra()).setDate(yearOfEra, month, dayOfMonth);
256 if (!JapaneseChronology.JCAL.validate(jdate)) {
257 throw new DateTimeException("year, month, and day not valid for Era");
258 }
259 LocalDate date = LocalDate.of(jdate.getNormalizedYear(), month, dayOfMonth);
260 return new JapaneseDate(era, yearOfEra, date);
261 }
262
263 /**
264 * Obtains a {@code JapaneseDate} from a temporal object.
265 * <p>
266 * This obtains a date in the Japanese calendar system based on the specified temporal.
267 * A {@code TemporalAccessor} represents an arbitrary set of date and time information,
268 * which this factory converts to an instance of {@code JapaneseDate}.
269 * <p>
270 * The conversion typically uses the {@link ChronoField#EPOCH_DAY EPOCH_DAY}
271 * field, which is standardized across calendar systems.
272 * <p>
273 * This method matches the signature of the functional interface {@link TemporalQuery}
274 * allowing it to be used as a query via method reference, {@code JapaneseDate::from}.
275 *
276 * @param temporal the temporal object to convert, not null
277 * @return the date in Japanese calendar system, not null
292 this.era = JapaneseEra.toJapaneseEra(jdate.getEra());
293 this.yearOfEra = jdate.getYear();
294 this.isoDate = isoDate;
295 }
296
297 /**
298 * Constructs a {@code JapaneseDate}. This constructor does NOT validate the given parameters,
299 * and {@code era} and {@code year} must agree with {@code isoDate}.
300 *
301 * @param era the era, validated not null
302 * @param year the year-of-era, validated
303 * @param isoDate the standard local date, validated not null
304 */
305 JapaneseDate(JapaneseEra era, int year, LocalDate isoDate) {
306 this.era = era;
307 this.yearOfEra = year;
308 this.isoDate = isoDate;
309 }
310
311 //-----------------------------------------------------------------------
312 /**
313 * Gets the chronology of this date, which is the Japanese calendar system.
314 * <p>
315 * The {@code Chronology} represents the calendar system in use.
316 * The era and other fields in {@link ChronoField} are defined by the chronology.
317 *
318 * @return the Japanese chronology, not null
319 */
320 @Override
321 public JapaneseChronology getChronology() {
322 return JapaneseChronology.INSTANCE;
323 }
324
325 /**
326 * Gets the era applicable at this date.
327 * <p>
328 * The Japanese calendar system has multiple eras defined by {@link JapaneseEra}.
329 *
330 * @return the era applicable at this date, not null
331 */
332 @Override
333 public JapaneseEra getEra() {
334 return era;
335 }
336
337 /**
338 * Returns the length of the month represented by this date.
339 * <p>
340 * This returns the length of the month in days.
341 * Month lengths match those of the ISO calendar system.
342 *
343 * @return the length of the month in days
344 */
345 @Override
346 public int lengthOfMonth() {
347 return isoDate.lengthOfMonth();
348 }
349
350 //-----------------------------------------------------------------------
351 @Override
352 public ValueRange range(TemporalField field) {
353 if (field instanceof ChronoField) {
354 if (isSupported(field)) {
355 ChronoField f = (ChronoField) field;
356 switch (f) {
357 case DAY_OF_MONTH:
358 case ALIGNED_WEEK_OF_MONTH:
359 return isoDate.range(field);
360 case DAY_OF_YEAR:
361 return actualRange(Calendar.DAY_OF_YEAR);
362 case YEAR_OF_ERA:
363 return actualRange(Calendar.YEAR);
364 }
365 return getChronology().range(f);
366 }
367 throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName());
368 }
369 return field.rangeRefinedBy(this);
370 }
371
372 private ValueRange actualRange(int calendarField) {
373 Calendar jcal = Calendar.getInstance(JapaneseChronology.LOCALE);
374 jcal.set(Calendar.ERA, era.getValue() + JapaneseEra.ERA_OFFSET); // TODO: cannot calculate this way for SEIREKI
375 jcal.set(yearOfEra, isoDate.getMonthValue() - 1, isoDate.getDayOfMonth());
376 return ValueRange.of(jcal.getActualMinimum(calendarField),
377 jcal.getActualMaximum(calendarField));
378 }
379
380 @Override
381 public long getLong(TemporalField field) {
382 if (field instanceof ChronoField) {
383 // same as ISO:
384 // DAY_OF_WEEK, ALIGNED_DAY_OF_WEEK_IN_MONTH, DAY_OF_MONTH, EPOCH_DAY,
385 // ALIGNED_WEEK_OF_MONTH, MONTH_OF_YEAR, PROLEPTIC_MONTH, YEAR
386 //
387 // calendar specific fields
388 // ALIGNED_DAY_OF_WEEK_IN_YEAR, DAY_OF_YEAR, ALIGNED_WEEK_OF_YEAR, YEAR_OF_ERA, ERA
389 switch ((ChronoField) field) {
390 case YEAR_OF_ERA:
391 return yearOfEra;
392 case ERA:
393 return era.getValue();
394 case DAY_OF_YEAR: {
395 LocalGregorianCalendar.Date jdate = toPrivateJapaneseDate(isoDate);
396 return JapaneseChronology.JCAL.getDayOfYear(jdate);
397 }
398 // TODO: ALIGNED_DAY_OF_WEEK_IN_YEAR and ALIGNED_WEEK_OF_YEAR ???
399 }
400 return isoDate.getLong(field);
401 }
402 return field.getFrom(this);
403 }
404
405 /**
406 * Returns a {@code LocalGregorianCalendar.Date} converted from the given {@code isoDate}.
407 *
408 * @param isoDate the local date, not null
409 * @return a {@code LocalGregorianCalendar.Date}, not null
410 */
411 private static LocalGregorianCalendar.Date toPrivateJapaneseDate(LocalDate isoDate) {
412 LocalGregorianCalendar.Date jdate = JapaneseChronology.JCAL.newCalendarDate(null);
413 sun.util.calendar.Era sunEra = JapaneseEra.privateEraFrom(isoDate);
414 int year = isoDate.getYear();
415 if (sunEra != null) {
416 year -= sunEra.getSinceDate().getYear() - 1;
417 }
418 jdate.setEra(sunEra).setYear(year).setMonth(isoDate.getMonthValue()).setDayOfMonth(isoDate.getDayOfMonth());
419 JapaneseChronology.JCAL.normalize(jdate);
420 return jdate;
421 }
422
423 //-----------------------------------------------------------------------
424 @Override
425 public JapaneseDate with(TemporalField field, long newValue) {
426 if (field instanceof ChronoField) {
427 ChronoField f = (ChronoField) field;
428 if (getLong(f) == newValue) {
429 return this;
430 }
431 switch (f) {
432 case YEAR_OF_ERA:
433 case YEAR:
434 case ERA: {
435 int nvalue = getChronology().range(f).checkValidIntValue(newValue, f);
436 switch (f) {
437 case YEAR_OF_ERA:
438 return this.withYear(nvalue);
439 case YEAR:
440 return with(isoDate.withYear(nvalue));
441 case ERA: {
442 return this.withYear(JapaneseEra.of(nvalue), yearOfEra);
443 }
444 }
445 }
446 }
447 // YEAR, PROLEPTIC_MONTH and others are same as ISO
448 // TODO: review other fields, such as WEEK_OF_YEAR
449 return with(isoDate.with(field, newValue));
450 }
451 return ChronoLocalDate.super.with(field, newValue);
452 }
453
454 /**
455 * {@inheritDoc}
456 * @throws DateTimeException {@inheritDoc}
457 * @throws ArithmeticException {@inheritDoc}
458 */
459 @Override
460 public JapaneseDate with(TemporalAdjuster adjuster) {
461 return super.with(adjuster);
462 }
463
464 /**
465 * {@inheritDoc}
466 * @throws DateTimeException {@inheritDoc}
467 * @throws ArithmeticException {@inheritDoc}
468 */
469 @Override
470 public JapaneseDate plus(TemporalAmount amount) {
471 return super.plus(amount);
472 }
473
474 /**
475 * {@inheritDoc}
476 * @throws DateTimeException {@inheritDoc}
477 * @throws ArithmeticException {@inheritDoc}
478 */
479 @Override
480 public JapaneseDate minus(TemporalAmount amount) {
481 return super.minus(amount);
482 }
483 //-----------------------------------------------------------------------
484 /**
485 * Returns a copy of this date with the year altered.
486 * <p>
487 * This method changes the year of the date.
488 * If the month-day is invalid for the year, then the previous valid day
489 * will be selected instead.
490 * <p>
491 * This instance is immutable and unaffected by this method call.
492 *
493 * @param era the era to set in the result, not null
494 * @param yearOfEra the year-of-era to set in the returned date
495 * @return a {@code JapaneseDate} based on this date with the requested year, never null
496 * @throws DateTimeException if {@code year} is invalid
497 */
498 private JapaneseDate withYear(JapaneseEra era, int yearOfEra) {
499 int year = JapaneseChronology.INSTANCE.prolepticYear(era, yearOfEra);
500 return with(isoDate.withYear(year));
501 }
502
503 /**
504 * Returns a copy of this date with the year-of-era altered.
505 * <p>
506 * This method changes the year-of-era of the date.
507 * If the month-day is invalid for the year, then the previous valid day
508 * will be selected instead.
509 * <p>
510 * This instance is immutable and unaffected by this method call.
511 *
512 * @param year the year to set in the returned date
513 * @return a {@code JapaneseDate} based on this date with the requested year-of-era, never null
514 * @throws DateTimeException if {@code year} is invalid
515 */
516 private JapaneseDate withYear(int year) {
517 return withYear(getEra(), year);
518 }
519
520 //-----------------------------------------------------------------------
521 @Override
522 JapaneseDate plusYears(long years) {
523 return with(isoDate.plusYears(years));
524 }
525
526 @Override
527 JapaneseDate plusMonths(long months) {
528 return with(isoDate.plusMonths(months));
529 }
530
531 @Override
532 JapaneseDate plusWeeks(long weeksToAdd) {
533 return with(isoDate.plusWeeks(weeksToAdd));
534 }
535
536 @Override
537 JapaneseDate plusDays(long days) {
538 return with(isoDate.plusDays(days));
539 }
540
541 @Override
542 public JapaneseDate plus(long amountToAdd, TemporalUnit unit) {
543 return super.plus(amountToAdd, unit);
544 }
545
546 @Override
547 public JapaneseDate minus(long amountToAdd, TemporalUnit unit) {
548 return super.minus(amountToAdd, unit);
549 }
550
551 @Override
552 JapaneseDate minusYears(long yearsToSubtract) {
553 return super.minusYears(yearsToSubtract);
554 }
555
556 @Override
557 JapaneseDate minusMonths(long monthsToSubtract) {
558 return super.minusMonths(monthsToSubtract);
559 }
560
561 @Override
562 JapaneseDate minusWeeks(long weeksToSubtract) {
563 return super.minusWeeks(weeksToSubtract);
564 }
565
566 @Override
567 JapaneseDate minusDays(long daysToSubtract) {
568 return super.minusDays(daysToSubtract);
569 }
570
571 private JapaneseDate with(LocalDate newDate) {
572 return (newDate.equals(isoDate) ? this : new JapaneseDate(newDate));
573 }
574
575 @Override // for javadoc and covariant return type
576 public final ChronoLocalDateTime<JapaneseDate> atTime(LocalTime localTime) {
577 return super.atTime(localTime);
578 }
579
580 @Override
581 public Period periodUntil(ChronoLocalDate<?> endDate) {
582 return isoDate.periodUntil(endDate);
583 }
584
585 @Override // override for performance
586 public long toEpochDay() {
587 return isoDate.toEpochDay();
588 }
589
590 //-------------------------------------------------------------------------
591 @Override // override for performance
592 public boolean equals(Object obj) {
593 if (this == obj) {
594 return true;
595 }
596 if (obj instanceof JapaneseDate) {
597 JapaneseDate otherDate = (JapaneseDate) obj;
|