All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.ibm.icu.util.JapaneseCalendar Maven / Gradle / Ivy

The newest version!
// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
 *******************************************************************************
 * Copyright (C) 1996-2014, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 */
package com.ibm.icu.util;
import java.util.Date;
import java.util.Locale;

import com.ibm.icu.impl.CalType;
import com.ibm.icu.impl.EraRules;

/**
 * JapaneseCalendar is a subclass of GregorianCalendar
 * that numbers years and eras based on the reigns of the Japanese emperors.
 * The Japanese calendar is identical to the Gregorian calendar in all respects
 * except for the year and era.  The ascension of each  emperor to the throne
 * begins a new era, and the years of that era are numbered starting with the
 * year of ascension as year 1.
 * 

* Note that in the year of an imperial ascension, there are two possible sets * of year and era values: that for the old era and for the new. For example, a * new era began on January 7, 1989 AD. Strictly speaking, the first six days * of that year were in the Showa era, e.g. "January 6, 64 Showa", while the rest * of the year was in the Heisei era, e.g. "January 7, 1 Heisei". This class * handles this distinction correctly when computing dates. However, in lenient * mode either form of date is acceptable as input. *

* In modern times, eras have started on January 8, 1868 AD, Gregorian (Meiji), * July 30, 1912 (Taisho), December 25, 1926 (Showa), and January 7, 1989 (Heisei). Constants * for these eras, suitable for use in the ERA field, are provided * in this class. Note that the number used for each era is more or * less arbitrary. Currently, the era starting in 645 AD is era #0; however this * may change in the future. Use the predefined constants rather than using actual, * absolute numbers. *

* Since ICU4J 63, start date of each era is imported from CLDR. CLDR era data * may contain tentative era in near future with placeholder names. By default, * such era data is not enabled. ICU4J users who want to test the behavior of * the future era can enable this by one of following settings (in the priority * order): *

    *
  1. Java system property ICU_ENABLE_TENTATIVE_ERA=true.
  2. *
  3. Environment variable ICU_ENABLE_TENTATIVE_ERA=true.
  4. *
  5. Java system property jdk.calendar.japanese.supplemental.era=xxx. * (Note: This configuration is used for specifying a new era's start date and * names in OpenJDK. ICU4J implementation enables the CLDR tentative era when * this property is defined, but it does not use the start date and names specified * by the property value.)
  6. *
*

* This class should not be subclassed.

*

* JapaneseCalendar usually should be instantiated using * {@link com.ibm.icu.util.Calendar#getInstance(ULocale)} passing in a ULocale * with the tag "@calendar=japanese".

* * @see com.ibm.icu.util.GregorianCalendar * @see com.ibm.icu.util.Calendar * * @author Laura Werner * @author Alan Liu * @stable ICU 2.8 */ public class JapaneseCalendar extends GregorianCalendar { // jdk1.4.2 serialver private static final long serialVersionUID = -2977189902603704691L; //------------------------------------------------------------------------- // Constructors... //------------------------------------------------------------------------- /** * Constructs a default JapaneseCalendar using the current time * in the default time zone with the default locale. * @stable ICU 2.8 */ public JapaneseCalendar() { super(); } /** * Constructs a JapaneseCalendar based on the current time * in the given time zone with the default locale. * @param zone the given time zone. * @stable ICU 2.8 */ public JapaneseCalendar(TimeZone zone) { super(zone); } /** * Constructs a JapaneseCalendar based on the current time * in the default time zone with the given locale. * @param aLocale the given locale. * @stable ICU 2.8 */ public JapaneseCalendar(Locale aLocale) { super(aLocale); } /** * Constructs a JapaneseCalendar based on the current time * in the default time zone with the given locale. * @param locale the given ulocale. * @stable ICU 3.2 */ public JapaneseCalendar(ULocale locale) { super(locale); } /** * Constructs a JapaneseCalendar based on the current time * in the given time zone with the given locale. * * @param zone the given time zone. * * @param aLocale the given locale. * @stable ICU 2.8 */ public JapaneseCalendar(TimeZone zone, Locale aLocale) { super(zone, aLocale); } /** * Constructs a JapaneseCalendar based on the current time * in the given time zone with the given locale. * * @param zone the given time zone. * * @param locale the given ulocale. * @stable ICU 3.2 */ public JapaneseCalendar(TimeZone zone, ULocale locale) { super(zone, locale); } /** * Constructs a JapaneseCalendar with the given date set * in the default time zone with the default locale. * * @param date The date to which the new calendar is set. * @stable ICU 2.8 */ public JapaneseCalendar(Date date) { this(); setTime(date); } /** * Constructs a JapaneseCalendar with the given date set * in the default time zone with the default locale. * * @param era The imperial era used to set the calendar's {@link #ERA ERA} field. * Eras are numbered starting with the Tenki era, which * began in 1053 AD Gregorian, as era zero. Recent * eras can be specified using the constants * {@link #MEIJI} (which started in 1868 AD), * {@link #TAISHO} (1912 AD), * {@link #SHOWA} (1926 AD), and * {@link #HEISEI} (1989 AD). * * @param year The value used to set the calendar's {@link #YEAR YEAR} field, * in terms of the era. * * @param month The value used to set the calendar's {@link #MONTH MONTH} field. * The value is 0-based. e.g., 0 for January. * * @param date The value used to set the calendar's DATE field. * @stable ICU 2.8 */ public JapaneseCalendar(int era, int year, int month, int date) { super(year, month, date); set(ERA, era); } /** * Constructs a JapaneseCalendar with the given date set * in the default time zone with the default locale. * * @param year The value used to set the calendar's {@link #YEAR YEAR} field, * in the era Heisei, the most current at the time this * class was last updated. * * @param month The value used to set the calendar's {@link #MONTH MONTH} field. * The value is 0-based. e.g., 0 for January. * * @param date The value used to set the calendar's {@link #DATE DATE} field. * @stable ICU 2.8 */ public JapaneseCalendar(int year, int month, int date) { super(year, month, date); set(ERA, CURRENT_ERA); } /** * Constructs a JapaneseCalendar with the given date * and time set for the default time zone with the default locale. * * @param year The value used to set the calendar's {@link #YEAR YEAR} time field, * in the era Heisei, the most current at the time of this * writing. * * @param month The value used to set the calendar's {@link #MONTH MONTH} time field. * The value is 0-based. e.g., 0 for January. * * @param date The value used to set the calendar's {@link #DATE DATE} time field. * * @param hour The value used to set the calendar's {@link #HOUR_OF_DAY HOUR_OF_DAY} time field. * * @param minute The value used to set the calendar's {@link #MINUTE MINUTE} time field. * * @param second The value used to set the calendar's {@link #SECOND SECOND} time field. * @stable ICU 2.8 */ public JapaneseCalendar(int year, int month, int date, int hour, int minute, int second) { super(year, month, date, hour, minute, second); set(ERA, CURRENT_ERA); } //------------------------------------------------------------------------- // Use 1970 as the default value of EXTENDED_YEAR private static final int GREGORIAN_EPOCH = 1970; private static final EraRules ERA_RULES; static { ERA_RULES = EraRules.getInstance(CalType.JAPANESE, enableTentativeEra()); } /** * Check environment variable that enables use of future eras. * @internal * @deprecated This API is ICU internal only. */ @Deprecated public static boolean enableTentativeEra() { // Although start date of next Japanese era is planned ahead, a name of // new era might not be available. This implementation allows tester to // check a new era without era names by settings below (in priority order). // By default, such tentative era is disabled. // // 1. System property ICU_ENABLE_TENTATIVE_ERA=true or false // 2. Environment variable ICU_ENABLE_TENTATIVE_ERA=true or false // 3. Java system property - jdk.calendar.japanese.supplemental.era for Japanese // // Note: Java system property specifies the start date of new Japanese era, // but this implementation always uses the date read from ICU data. boolean includeTentativeEra = false; final String VAR_NAME = "ICU_ENABLE_TENTATIVE_ERA"; String eraConf = System.getProperty(VAR_NAME); if (eraConf == null) { eraConf = System.getenv(VAR_NAME); } if (eraConf != null) { includeTentativeEra = eraConf.equalsIgnoreCase("true"); } else { String jdkEraConf = System.getProperty("jdk.calendar.japanese.supplemental.era"); includeTentativeEra = jdkEraConf != null; } return includeTentativeEra; } /** * @stable ICU 2.8 */ @Override protected int handleGetExtendedYear() { // EXTENDED_YEAR in JapaneseCalendar is a Gregorian year // The default value of EXTENDED_YEAR is 1970 (Showa 45) int year; if (newerField(EXTENDED_YEAR, YEAR) == EXTENDED_YEAR && newerField(EXTENDED_YEAR, ERA) == EXTENDED_YEAR) { year = internalGet(EXTENDED_YEAR, GREGORIAN_EPOCH); } else { // extended year is a gregorian year, where 1 = 1AD, 0 = 1BC, -1 = 2BC, etc year = internalGet(YEAR, 1) // pin to minimum of year 1 (first year) + ERA_RULES.getStartYear(internalGet(ERA, CURRENT_ERA)) // add gregorian starting year - 1; // Subtract one because year starts at 1 } return year; } /** * Called by handleComputeJulianDay. Returns the default month (0-based) for the year, * taking year and era into account. Defaults to 0 (JANUARY) for Gregorian. * @param extendedYear the extendedYear, as returned by handleGetExtendedYear * @return the default month * @draft ICU 3.6 (retain) * @see #MONTH */ @Override protected int getDefaultMonthInYear(int extendedYear) { int era = internalGet(ERA, CURRENT_ERA); // computeFields(status); // No need to compute fields here - expect the caller already did so. // Find out if we are at the edge of an era int[] eraStart = ERA_RULES.getStartDate(era, null); if (extendedYear == eraStart[0]) { return eraStart[1] // month.. - 1; // return 0-based month } else { return super.getDefaultMonthInYear(extendedYear); } } /** * Called by handleComputeJulianDay. Returns the default day (1-based) for the month, * taking currently-set year and era into account. Defaults to 1 for Gregorian. * @param extendedYear the extendedYear, as returned by handleGetExtendedYear * @param month the month, as returned by getDefaultMonthInYear * @return the default day of the month * @draft ICU 3.6 (retain) * @see #DAY_OF_MONTH */ @Override protected int getDefaultDayInMonth(int extendedYear, int month) { int era = internalGet(ERA, CURRENT_ERA); int[] eraStart = ERA_RULES.getStartDate(era, null); if (extendedYear == eraStart[0]) { // if it is year 1.. if (month == (eraStart[1] - 1)) { // if it is the emperor's first month.. return eraStart[2]; // return the D_O_M of accession } } return super.getDefaultDayInMonth(extendedYear, month); } /** * @stable ICU 2.8 */ @Override protected void handleComputeFields(int julianDay) { super.handleComputeFields(julianDay); int year = internalGet(EXTENDED_YEAR); int eraIdx = ERA_RULES.getEraIndex(year, internalGet(MONTH) + 1 /* 1-base */, internalGet(DAY_OF_MONTH)); internalSet(ERA, eraIdx); internalSet(YEAR, year - ERA_RULES.getStartYear(eraIdx) + 1); } //------------------------------------------------------------------------- // Public constants for some of the recent eras that folks might use... //------------------------------------------------------------------------- // Constant for the current era. This must be regularly updated. /** * @stable ICU 2.8 */ static public final int CURRENT_ERA; /** * Constant for the era starting on Sept. 8, 1868 AD. * @stable ICU 2.8 */ static public final int MEIJI; /** * Constant for the era starting on July 30, 1912 AD. * @stable ICU 2.8 */ static public final int TAISHO; /** * Constant for the era starting on Dec. 25, 1926 AD. * @stable ICU 2.8 */ static public final int SHOWA; /** * Constant for the era starting on Jan. 7, 1989 AD. * @stable ICU 2.8 */ static public final int HEISEI; /** * Constant for the era starting on May 1, 2019 AD. * @stable ICU 64 */ static public final int REIWA; // We want to make these era constants initialized in a static initializer // block to prevent javac to inline these values in a consumer code. // By doing so, we can keep better binary compatibility across versions even // these values are changed. static { MEIJI = 232; TAISHO = 233; SHOWA = 234; HEISEI = 235; REIWA = 236; CURRENT_ERA = ERA_RULES.getCurrentEraIndex(); } /** * Override GregorianCalendar. We should really handle YEAR_WOY and * EXTENDED_YEAR here too to implement the 1..5000000 range, but it's * not critical. * @stable ICU 2.8 */ @Override @SuppressWarnings("fallthrough") protected int handleGetLimit(int field, int limitType) { switch (field) { case ERA: if (limitType == MINIMUM || limitType == GREATEST_MINIMUM) { return 0; } return ERA_RULES.getNumberOfEras() - 1; // max known era, not always CURRENT_ERA case YEAR: { switch (limitType) { case MINIMUM: case GREATEST_MINIMUM: return 1; case LEAST_MAXIMUM: return 1; case MAXIMUM: return super.handleGetLimit(field, MAXIMUM) - ERA_RULES.getStartYear(CURRENT_ERA); } //Fall through to the default if not handled above } default: return super.handleGetLimit(field, limitType); } } /** * {@inheritDoc} * @stable ICU 3.8 */ @Override public String getType() { return "japanese"; } /** * {@inheritDoc} * @internal * @deprecated This API is ICU internal only. */ @Override @Deprecated public boolean haveDefaultCentury() { return false; } /** * {@inheritDoc} * @stable ICU 4.0 */ @Override public int getActualMaximum(int field) { if (field == YEAR) { int era = get(Calendar.ERA); if (era == ERA_RULES.getNumberOfEras() - 1) { // TODO: Investigate what value should be used here - revisit after 4.0. return handleGetLimit(YEAR, MAXIMUM); } else { int[] nextEraStart = ERA_RULES.getStartDate(era + 1, null); int nextEraYear = nextEraStart[0]; int nextEraMonth = nextEraStart[1]; // 1-base int nextEraDate = nextEraStart[2]; int maxYear = nextEraYear - ERA_RULES.getStartYear(era) + 1; // 1-base if (nextEraMonth == 1 && nextEraDate == 1) { // Substract 1, because the next era starts at Jan 1 maxYear--; } return maxYear; } } return super.getActualMaximum(field); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy