src/share/classes/java/time/chrono/JapaneseChronology.java
Print this page
@@ -59,15 +59,15 @@
import java.io.Serializable;
import java.time.Clock;
import java.time.DateTimeException;
import java.time.Instant;
import java.time.LocalDate;
+import java.time.Year;
+import java.time.ZoneId;
import java.time.temporal.ChronoField;
import java.time.temporal.TemporalAccessor;
import java.time.temporal.ValueRange;
-import java.time.Year;
-import java.time.ZoneId;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;
import java.util.Locale;
@@ -103,35 +103,10 @@
* Singleton instance for Japanese chronology.
*/
public static final JapaneseChronology INSTANCE = new JapaneseChronology();
/**
- * The singleton instance for the before Meiji era ( - 1868-09-07)
- * which has the value -999.
- */
- public static final Era ERA_SEIREKI = JapaneseEra.SEIREKI;
- /**
- * The singleton instance for the Meiji era (1868-09-08 - 1912-07-29)
- * which has the value -1.
- */
- public static final Era ERA_MEIJI = JapaneseEra.MEIJI;
- /**
- * The singleton instance for the Taisho era (1912-07-30 - 1926-12-24)
- * which has the value 0.
- */
- public static final Era ERA_TAISHO = JapaneseEra.TAISHO;
- /**
- * The singleton instance for the Showa era (1926-12-25 - 1989-01-07)
- * which has the value 1.
- */
- public static final Era ERA_SHOWA = JapaneseEra.SHOWA;
- /**
- * The singleton instance for the Heisei era (1989-01-08 - current)
- * which has the value 2.
- */
- public static final Era ERA_HEISEI = JapaneseEra.HEISEI;
- /**
* Serialization version.
*/
private static final long serialVersionUID = 459996390165777884L;
//-----------------------------------------------------------------------
@@ -139,19 +114,10 @@
* Restricted constructor.
*/
private JapaneseChronology() {
}
- /**
- * Resolve singleton.
- *
- * @return the singleton instance, not null
- */
- private Object readResolve() {
- return INSTANCE;
- }
-
//-----------------------------------------------------------------------
/**
* Gets the ID of the chronology - 'Japanese'.
* <p>
* The ID uniquely identifies the {@code Chronology}.
@@ -181,40 +147,86 @@
public String getCalendarType() {
return "japanese";
}
//-----------------------------------------------------------------------
+ /**
+ * Obtains a local date in Japanese calendar system from the
+ * era, year-of-era, month-of-year and day-of-month fields.
+ *
+ * @param era the Japanese era, not null
+ * @param yearOfEra the year-of-era
+ * @param month the month-of-year
+ * @param dayOfMonth the day-of-month
+ * @return the Japanese local date, not null
+ * @throws DateTimeException if unable to create the date
+ * @throws ClassCastException if the {@code era} is not a {@code JapaneseEra}
+ */
@Override
public JapaneseDate date(Era era, int yearOfEra, int month, int dayOfMonth) {
if (era instanceof JapaneseEra == false) {
- throw new DateTimeException("Era must be JapaneseEra");
+ throw new ClassCastException("Era must be JapaneseEra");
}
return JapaneseDate.of((JapaneseEra) era, yearOfEra, month, dayOfMonth);
}
+ /**
+ * Obtains a local date in Japanese calendar system from the
+ * proleptic-year, month-of-year and day-of-month fields.
+ *
+ * @param prolepticYear the proleptic-year
+ * @param month the month-of-year
+ * @param dayOfMonth the day-of-month
+ * @return the Japanese local date, not null
+ * @throws DateTimeException if unable to create the date
+ */
@Override
public JapaneseDate date(int prolepticYear, int month, int dayOfMonth) {
return new JapaneseDate(LocalDate.of(prolepticYear, month, dayOfMonth));
}
+ /**
+ * Obtains a local date in Japanese calendar system from the
+ * era, year-of-era and day-of-year fields.
+ *
+ * @param era the Japanese era, not null
+ * @param yearOfEra the year-of-era
+ * @param dayOfYear the day-of-year
+ * @return the Japanese local date, not null
+ * @throws DateTimeException if unable to create the date
+ * @throws ClassCastException if the {@code era} is not a {@code JapaneseEra}
+ */
@Override
- public JapaneseDate dateYearDay(int prolepticYear, int dayOfYear) {
- LocalDate date = LocalDate.ofYearDay(prolepticYear, dayOfYear);
- return date(prolepticYear, date.getMonthValue(), date.getDayOfMonth());
+ public JapaneseDate dateYearDay(Era era, int yearOfEra, int dayOfYear) {
+ return dateYearDay(prolepticYear(era, yearOfEra), dayOfYear);
}
+ /**
+ * Obtains a local date in Japanese calendar system from the
+ * proleptic-year and day-of-year fields.
+ *
+ * @param prolepticYear the proleptic-year
+ * @param dayOfYear the day-of-year
+ * @return the Japanese local date, not null
+ * @throws DateTimeException if unable to create the date
+ */
@Override
- public JapaneseDate date(TemporalAccessor temporal) {
- if (temporal instanceof JapaneseDate) {
- return (JapaneseDate) temporal;
- }
- return new JapaneseDate(LocalDate.from(temporal));
+ public JapaneseDate dateYearDay(int prolepticYear, int dayOfYear) {
+ LocalDate date = LocalDate.ofYearDay(prolepticYear, dayOfYear);
+ return date(prolepticYear, date.getMonthValue(), date.getDayOfMonth());
}
- @Override
- public JapaneseDate dateYearDay(Era era, int yearOfEra, int dayOfYear) {
- return dateYearDay(prolepticYear(era, yearOfEra), dayOfYear);
+ /**
+ * Obtains a local date in the Japanese calendar system from the epoch-day.
+ *
+ * @param epochDay the epoch day
+ * @return the Japanese local date, not null
+ * @throws DateTimeException if unable to create the date
+ */
+ @Override // override with covariant return type
+ public JapaneseDate dateEpochDay(long epochDay) {
+ return new JapaneseDate(LocalDate.ofEpochDay(epochDay));
}
@Override
public JapaneseDate dateNow() {
return dateNow(Clock.systemDefaultZone());
@@ -229,10 +241,18 @@
public JapaneseDate dateNow(Clock clock) {
return date(LocalDate.now(clock));
}
@Override
+ public JapaneseDate date(TemporalAccessor temporal) {
+ if (temporal instanceof JapaneseDate) {
+ return (JapaneseDate) temporal;
+ }
+ return new JapaneseDate(LocalDate.from(temporal));
+ }
+
+ @Override
public ChronoLocalDateTime<JapaneseDate> localDateTime(TemporalAccessor temporal) {
return (ChronoLocalDateTime<JapaneseDate>)super.localDateTime(temporal);
}
@Override
@@ -262,33 +282,36 @@
}
@Override
public int prolepticYear(Era era, int yearOfEra) {
if (era instanceof JapaneseEra == false) {
- throw new DateTimeException("Era must be JapaneseEra");
+ throw new ClassCastException("Era must be JapaneseEra");
}
JapaneseEra jera = (JapaneseEra) era;
int gregorianYear = jera.getPrivateEra().getSinceDate().getYear() + yearOfEra - 1;
if (yearOfEra == 1) {
return gregorianYear;
}
LocalGregorianCalendar.Date jdate = JCAL.newCalendarDate(null);
jdate.setEra(jera.getPrivateEra()).setDate(yearOfEra, 1, 1);
+ if (!JapaneseChronology.JCAL.validate(jdate)) {
+ throw new DateTimeException("Invalid yearOfEra value");
+ }
JCAL.normalize(jdate);
if (jdate.getNormalizedYear() == gregorianYear) {
return gregorianYear;
}
- throw new DateTimeException("invalid yearOfEra value");
+ throw new DateTimeException("Invalid yearOfEra value");
}
/**
* Returns the calendar system era object from the given numeric value.
*
* See the description of each Era for the numeric values of:
- * {@link #ERA_HEISEI}, {@link #ERA_SHOWA},{@link #ERA_TAISHO},
- * {@link #ERA_MEIJI}), only Meiji and later eras are supported.
- * Prior to Meiji {@link #ERA_SEIREKI} is used.
+ * {@link JapaneseEra#HEISEI}, {@link JapaneseEra#SHOWA},{@link JapaneseEra#TAISHO},
+ * {@link JapaneseEra#MEIJI}), only Meiji and later eras are supported.
+ * Prior to Meiji {@link JapaneseEra#SEIREKI} is used.
*
* @param eraValue the era value
* @return the Japanese {@code Era} for the given numeric era value
* @throws DateTimeException if {@code eraValue} is invalid
*/
@@ -297,11 +320,11 @@
return JapaneseEra.of(eraValue);
}
@Override
public List<Era> eras() {
- return Arrays.<Era>asList(JapaneseEra.values());
+ return Arrays.asList(JapaneseEra.values());
}
//-----------------------------------------------------------------------
@Override
public ValueRange range(ChronoField field) {
@@ -320,24 +343,28 @@
case MILLI_OF_SECOND:
case NANO_OF_DAY:
case NANO_OF_SECOND:
case CLOCK_HOUR_OF_DAY:
case CLOCK_HOUR_OF_AMPM:
- case EPOCH_DAY:
- case EPOCH_MONTH:
+ case EPOCH_DAY: // TODO: if year is restricted, then so is epoch-day
return field.range();
}
Calendar jcal = Calendar.getInstance(LOCALE);
int fieldIndex;
switch (field) {
case ERA:
- return ValueRange.of(jcal.getMinimum(Calendar.ERA) - JapaneseEra.ERA_OFFSET,
+ return ValueRange.of(JapaneseEra.SEIREKI.getValue(),
jcal.getMaximum(Calendar.ERA) - JapaneseEra.ERA_OFFSET);
case YEAR:
case YEAR_OF_ERA:
+ // TODO: this is not right
return ValueRange.of(Year.MIN_VALUE, jcal.getGreatestMinimum(Calendar.YEAR),
jcal.getLeastMaximum(Calendar.YEAR), Year.MAX_VALUE);
+ case PROLEPTIC_MONTH:
+ // TODO: should be the range of months bound by the valid range of years
+ return ValueRange.of((jcal.getGreatestMinimum(Calendar.YEAR) - 1) * 12,
+ (jcal.getLeastMaximum(Calendar.YEAR)) * 12);
case MONTH_OF_YEAR:
return ValueRange.of(jcal.getMinimum(Calendar.MONTH) + 1, jcal.getGreatestMinimum(Calendar.MONTH) + 1,
jcal.getLeastMaximum(Calendar.MONTH) + 1, jcal.getMaximum(Calendar.MONTH) + 1);
case DAY_OF_YEAR:
fieldIndex = Calendar.DAY_OF_YEAR;