com.ibm.icu.util.JapaneseCalendar Maven / Gradle / Ivy
Show all versions of icu4j Show documentation
/*
*******************************************************************************
* 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;
/**
* 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 1053 AD is era #0; however this
* may change in the future as we add more historical data. Use the predefined
* constants rather than using actual, absolute numbers.
*
* 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;
/**
* @stable ICU 2.8
*/
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)
+ ERAS[internalGet(ERA, CURRENT_ERA) * 3] // 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
* @provisional ICU 3.6
* @draft ICU 3.6 (retain)
* @see #MONTH
*/
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
if(extendedYear == ERAS[era*3]) {
return ERAS[(era*3)+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)
* @provisional ICU 3.6
* @see #DAY_OF_MONTH
*/
protected int getDefaultDayInMonth(int extendedYear, int month) {
int era = internalGet(ERA, CURRENT_ERA);
if(extendedYear == ERAS[era*3]) { // if it is year 1..
if(month == ((ERAS[(era*3)+1])-1)) { // if it is the emperor's first month..
return ERAS[(era*3)+2]; // return the D_O_M of acession
}
}
return super.getDefaultDayInMonth(extendedYear, month);
}
/**
* @stable ICU 2.8
*/
protected void handleComputeFields(int julianDay) {
super.handleComputeFields(julianDay);
int year = internalGet(EXTENDED_YEAR);
int low = 0;
// Short circuit for recent years. Most modern computations will
// occur in the current era and won't require the binary search.
// Note that if the year is == the current era year, then we use
// the binary search to handle the month/dom comparison.
if (year > ERAS[ERAS.length - 3]) {
low = CURRENT_ERA;
} else {
// Binary search
int high = ERAS.length / 3;
while (low < high - 1) {
int i = (low + high) / 2;
int diff = year - ERAS[i*3];
// If years are the same, then compare the months, and if those
// are the same, compare days of month. In the ERAS array
// months are 1-based for easier maintenance.
if (diff == 0) {
diff = internalGet(MONTH) - (ERAS[i*3 + 1] - 1);
if (diff == 0) {
diff = internalGet(DAY_OF_MONTH) - ERAS[i*3 + 2];
}
}
if (diff >= 0) {
low = i;
} else {
high = i;
}
}
}
// Now we've found the last era that starts before this date, so
// adjust the year to count from the start of that era. Note that
// all dates before the first era will fall into the first era by
// the algorithm.
internalSet(ERA, low);
internalSet(YEAR, year - ERAS[low*3] + 1);
}
private static final int[] ERAS = {
// Gregorian date of each emperor's ascension
// Years are AD, months are 1-based.
// Year Month Day
645, 6, 19, // Taika
650, 2, 15, // Hakuchi
672, 1, 1, // Hakuho
686, 7, 20, // Shucho
701, 3, 21, // Taiho
704, 5, 10, // Keiun
708, 1, 11, // Wado
715, 9, 2, // Reiki
717, 11, 17, // Yoro
724, 2, 4, // Jinki
729, 8, 5, // Tempyo
749, 4, 14, // Tempyo-kampo
749, 7, 2, // Tempyo-shoho
757, 8, 18, // Tempyo-hoji
765, 1, 7, // Tempho-jingo
767, 8, 16, // Jingo-keiun
770, 10, 1, // Hoki
781, 1, 1, // Ten-o
782, 8, 19, // Enryaku
806, 5, 18, // Daido
810, 9, 19, // Konin
824, 1, 5, // Tencho
834, 1, 3, // Showa
848, 6, 13, // Kajo
851, 4, 28, // Ninju
854, 11, 30, // Saiko
857, 2, 21, // Tennan
859, 4, 15, // Jogan
877, 4, 16, // Genkei
885, 2, 21, // Ninna
889, 4, 27, // Kampyo
898, 4, 26, // Shotai
901, 7, 15, // Engi
923, 4, 11, // Encho
931, 4, 26, // Shohei
938, 5, 22, // Tengyo
947, 4, 22, // Tenryaku
957, 10, 27, // Tentoku
961, 2, 16, // Owa
964, 7, 10, // Koho
968, 8, 13, // Anna
970, 3, 25, // Tenroku
973, 12, 20, // Ten-en
976, 7, 13, // Jogen
978, 11, 29, // Tengen
983, 4, 15, // Eikan
985, 4, 27, // Kanna
987, 4, 5, // Ei-en
989, 8, 8, // Eiso
990, 11, 7, // Shoryaku
995, 2, 22, // Chotoku
999, 1, 13, // Choho
1004, 7, 20, // Kanko
1012, 12, 25, // Chowa
1017, 4, 23, // Kannin
1021, 2, 2, // Jian
1024, 7, 13, // Manju
1028, 7, 25, // Chogen
1037, 4, 21, // Choryaku
1040, 11, 10, // Chokyu
1044, 11, 24, // Kantoku
1046, 4, 14, // Eisho
1053, 1, 11, // Tengi
1058, 8, 29, // Kohei
1065, 8, 2, // Jiryaku
1069, 4, 13, // Enkyu
1074, 8, 23, // Shoho
1077, 11, 17, // Shoryaku
1081, 2, 10, // Eiho
1084, 2, 7, // Otoku
1087, 4, 7, // Kanji
1094, 12, 15, // Kaho
1096, 12, 17, // Eicho
1097, 11, 21, // Shotoku
1099, 8, 28, // Kowa
1104, 2, 10, // Choji
1106, 4, 9, // Kasho
1108, 8, 3, // Tennin
1110, 7, 13, // Ten-ei
1113, 7, 13, // Eikyu
1118, 4, 3, // Gen-ei
1120, 4, 10, // Hoan
1124, 4, 3, // Tenji
1126, 1, 22, // Daiji
1131, 1, 29, // Tensho
1132, 8, 11, // Chosho
1135, 4, 27, // Hoen
1141, 7, 10, // Eiji
1142, 4, 28, // Koji
1144, 2, 23, // Tenyo
1145, 7, 22, // Kyuan
1151, 1, 26, // Ninpei
1154, 10, 28, // Kyuju
1156, 4, 27, // Hogen
1159, 4, 20, // Heiji
1160, 1, 10, // Eiryaku
1161, 9, 4, // Oho
1163, 3, 29, // Chokan
1165, 6, 5, // Eiman
1166, 8, 27, // Nin-an
1169, 4, 8, // Kao
1171, 4, 21, // Shoan
1175, 7, 28, // Angen
1177, 8, 4, // Jisho
1181, 7, 14, // Yowa
1182, 5, 27, // Juei
1184, 4, 16, // Genryuku
1185, 8, 14, // Bunji
1190, 4, 11, // Kenkyu
1199, 4, 27, // Shoji
1201, 2, 13, // Kennin
1204, 2, 20, // Genkyu
1206, 4, 27, // Ken-ei
1207, 10, 25, // Shogen
1211, 3, 9, // Kenryaku
1213, 12, 6, // Kenpo
1219, 4, 12, // Shokyu
1222, 4, 13, // Joo
1224, 11, 20, // Gennin
1225, 4, 20, // Karoku
1227, 12, 10, // Antei
1229, 3, 5, // Kanki
1232, 4, 2, // Joei
1233, 4, 15, // Tempuku
1234, 11, 5, // Bunryaku
1235, 9, 19, // Katei
1238, 11, 23, // Ryakunin
1239, 2, 7, // En-o
1240, 7, 16, // Ninji
1243, 2, 26, // Kangen
1247, 2, 28, // Hoji
1249, 3, 18, // Kencho
1256, 10, 5, // Kogen
1257, 3, 14, // Shoka
1259, 3, 26, // Shogen
1260, 4, 13, // Bun-o
1261, 2, 20, // Kocho
1264, 2, 28, // Bun-ei
1275, 4, 25, // Kenji
1278, 2, 29, // Koan
1288, 4, 28, // Shoo
1293, 8, 55, // Einin
1299, 4, 25, // Shoan
1302, 11, 21, // Kengen
1303, 8, 5, // Kagen
1306, 12, 14, // Tokuji
1308, 10, 9, // Enkei
1311, 4, 28, // Ocho
1312, 3, 20, // Showa
1317, 2, 3, // Bunpo
1319, 4, 28, // Geno
1321, 2, 23, // Genkyo
1324, 12, 9, // Shochu
1326, 4, 26, // Kareki
1329, 8, 29, // Gentoku
1331, 8, 9, // Genko
1334, 1, 29, // Kemmu
1336, 2, 29, // Engen
1340, 4, 28, // Kokoku
1346, 12, 8, // Shohei
1370, 7, 24, // Kentoku
1372, 4, 1, // Bunch\u0169
1375, 5, 27, // Tenju
1379, 3, 22, // Koryaku
1381, 2, 10, // Kowa
1384, 4, 28, // Gench\u0169
1384, 2, 27, // Meitoku
1387, 8, 23, // Kakei
1389, 2, 9, // Koo
1390, 3, 26, // Meitoku
1394, 7, 5, // Oei
1428, 4, 27, // Shocho
1429, 9, 5, // Eikyo
1441, 2, 17, // Kakitsu
1444, 2, 5, // Bun-an
1449, 7, 28, // Hotoku
1452, 7, 25, // Kyotoku
1455, 7, 25, // Kosho
1457, 9, 28, // Choroku
1460, 12, 21, // Kansho
1466, 2, 28, // Bunsho
1467, 3, 3, // Onin
1469, 4, 28, // Bunmei
1487, 7, 29, // Chokyo
1489, 8, 21, // Entoku
1492, 7, 19, // Meio
1501, 2, 29, // Bunki
1504, 2, 30, // Eisho
1521, 8, 23, // Taiei
1528, 8, 20, // Kyoroku
1532, 7, 29, // Tenmon
1555, 10, 23, // Koji
1558, 2, 28, // Eiroku
1570, 4, 23, // Genki
1573, 7, 28, // Tensho
1592, 12, 8, // Bunroku
1596, 10, 27, // Keicho
1615, 7, 13, // Genwa
1624, 2, 30, // Kan-ei
1644, 12, 16, // Shoho
1648, 2, 15, // Keian
1652, 9, 18, // Shoo
1655, 4, 13, // Meiryaku
1658, 7, 23, // Manji
1661, 4, 25, // Kanbun
1673, 9, 21, // Enpo
1681, 9, 29, // Tenwa
1684, 2, 21, // Jokyo
1688, 9, 30, // Genroku
1704, 3, 13, // Hoei
1711, 4, 25, // Shotoku
1716, 6, 22, // Kyoho
1736, 4, 28, // Genbun
1741, 2, 27, // Kanpo
1744, 2, 21, // Enkyo
1748, 7, 12, // Kan-en
1751, 10, 27, // Horyaku
1764, 6, 2, // Meiwa
1772, 11, 16, // An-ei
1781, 4, 2, // Tenmei
1789, 1, 25, // Kansei
1801, 2, 5, // Kyowa
1804, 2, 11, // Bunka
1818, 4, 22, // Bunsei
1830, 12, 10, // Tenpo
1844, 12, 2, // Koka
1848, 2, 28, // Kaei
1854, 11, 27, // Ansei
1860, 3, 18, // Man-en
1861, 2, 19, // Bunkyu
1864, 2, 20, // Genji
1865, 4, 7, // Keio
1868, 9, 8, // Meiji
1912, 7, 30, // Taisho
1926, 12, 25, // Showa
1989, 1, 8, // Heisei
2019, 5, 1, // Reiwa
};
//-------------------------------------------------------------------------
// 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 = (ERAS.length / 3) - 1;
/**
* Constant for the era starting on Sept. 8, 1868 AD.
* @stable ICU 2.8
*/
static public final int MEIJI = CURRENT_ERA - 4;
/**
* Constant for the era starting on July 30, 1912 AD.
* @stable ICU 2.8
*/
static public final int TAISHO = CURRENT_ERA - 3;
/**
* Constant for the era starting on Dec. 25, 1926 AD.
* @stable ICU 2.8
*/
static public final int SHOWA = CURRENT_ERA - 2;
/**
* Constant for the era starting on Jan. 7, 1989 AD.
* @stable ICU 2.8
*/
static public final int HEISEI = CURRENT_ERA - 1;
/**
* 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
*/
@SuppressWarnings("fallthrough")
protected int handleGetLimit(int field, int limitType) {
switch (field) {
case ERA:
if (limitType == MINIMUM || limitType == GREATEST_MINIMUM) {
return 0;
}
return 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) - ERAS[CURRENT_ERA*3];
}
//Fall through to the default if not handled above
}
default:
return super.handleGetLimit(field, limitType);
}
}
/**
* {@inheritDoc}
* @stable ICU 3.8
*/
public String getType() {
return "japanese";
}
/**
* {@inheritDoc}
* @internal
* @deprecated This API is ICU internal only.
*/
@Deprecated
public boolean haveDefaultCentury() {
return false;
}
/**
* {@inheritDoc}
* @stable ICU 4.0
*/
public int getActualMaximum(int field) {
if (field == YEAR) {
int era = get(Calendar.ERA);
if (era == CURRENT_ERA) {
// TODO: Investigate what value should be used here - revisit after 4.0.
return handleGetLimit(YEAR, MAXIMUM);
} else {
int nextEraYear = ERAS[(era+1)*3];
int nextEraMonth = ERAS[(era+1)*3 + 1];
int nextEraDate = ERAS[(era+1)*3 + 2];
int maxYear = nextEraYear - ERAS[era*3] + 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);
}
}