EthiopicCalendar.java
// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
*******************************************************************************
* Copyright (C) 2005-2016, International Business Machines Corporation and
* others. All Rights Reserved.
*******************************************************************************
*/
package com.ibm.icu.util;
import com.ibm.icu.impl.CalendarUtil;
import com.ibm.icu.util.ULocale.Category;
import java.util.Date;
import java.util.Locale;
/**
* Implement the Ethiopic calendar system.
*
* <p>EthiopicCalendar usually should be instantiated using {@link
* com.ibm.icu.util.Calendar#getInstance(ULocale)} passing in a <code>ULocale</code> with the tag
* <code>"@calendar=ethiopic"</code>.
*
* @see com.ibm.icu.util.Calendar
* @stable ICU 3.4
*/
public final class EthiopicCalendar extends CECalendar {
// jdk1.4.2 serialver
private static final long serialVersionUID = -2438495771339315608L;
/**
* Constant for መስከረም, the 1st month of the Ethiopic year.
*
* @stable ICU 3.4
*/
public static final int MESKEREM = 0;
/**
* Constant for ጥቅምት, the 2nd month of the Ethiopic year.
*
* @stable ICU 3.4
*/
public static final int TEKEMT = 1;
/**
* Constant for ኅዳር, the 3rd month of the Ethiopic year.
*
* @stable ICU 3.4
*/
public static final int HEDAR = 2;
/**
* Constant for ታኅሣሥ, the 4th month of the Ethiopic year.
*
* @stable ICU 3.4
*/
public static final int TAHSAS = 3;
/**
* Constant for ጥር, the 5th month of the Ethiopic year.
*
* @stable ICU 3.4
*/
public static final int TER = 4;
/**
* Constant for የካቲት, the 6th month of the Ethiopic year.
*
* @stable ICU 3.4
*/
public static final int YEKATIT = 5;
/**
* Constant for መጋቢት, the 7th month of the Ethiopic year.
*
* @stable ICU 3.4
*/
public static final int MEGABIT = 6;
/**
* Constant for ሚያዝያ, the 8th month of the Ethiopic year.
*
* @stable ICU 3.4
*/
public static final int MIAZIA = 7;
/**
* Constant for ግንቦት, the 9th month of the Ethiopic year.
*
* @stable ICU 3.4
*/
public static final int GENBOT = 8;
/**
* Constant for ሰኔ, the 10th month of the Ethiopic year.
*
* @stable ICU 3.4
*/
public static final int SENE = 9;
/**
* Constant for ሐምሌ, the 11th month of the Ethiopic year.
*
* @stable ICU 3.4
*/
public static final int HAMLE = 10;
/**
* Constant for ነሐሴ, the 12th month of the Ethiopic year.
*
* @stable ICU 3.4
*/
public static final int NEHASSE = 11;
/**
* Constant for ጳጉሜን, the 13th month of the Ethiopic year.
*
* @stable ICU 3.4
*/
public static final int PAGUMEN = 12;
// Up until the end of the 19th century the prevailant convention was to
// reference the Ethiopic Calendar from the creation of the world,
// \u12d3\u1218\u1270\u1361\u12d3\u1208\u121d
// (Amete Alem 5500 BC). As Ethiopia modernized the reference epoch from
// the birth of Christ (\u12d3\u1218\u1270\u1361\u121d\u1215\u1228\u1275)
// began to displace the creation of the
// world reference point. However, years before the birth of Christ are
// still referenced in the creation of the world system.
// Thus -100 \u12d3/\u121d
// would be rendered as 5400 \u12d3/\u12d3.
//
// The creation of the world in Ethiopic cannon was
// Meskerem 1, -5500 \u12d3/\u121d 00:00:00
// applying the birth of Christ reference and Ethiopian time conventions. This is
// 6 hours less than the Julian epoch reference point (noon). In Gregorian
// the date and time was July 18th -5493 BC 06:00 AM.
// Julian Days relative to the
// \u12d3\u1218\u1270\u1361\u121d\u1215\u1228\u1275 epoch
// Note: we no longer use this constant
private static final int JD_EPOCH_OFFSET_AMETE_ALEM = -285019;
// Julian Days relative to the
// \u12d3\u1218\u1270\u1361\u12d3\u1208\u121d epoch
private static final int JD_EPOCH_OFFSET_AMETE_MIHRET = 1723856;
// The delta between Amete Alem 1 and Amete Mihret 1
// AA 5501 = AM 1
private static final int AMETE_MIHRET_DELTA = 5500;
// Eras
private static final int AMETE_ALEM = 0;
private static final int AMETE_MIHRET = 1;
// Era mode. When eraType is AMETE_ALEM_ERA,
// Amete Mihret won't be used for the ERA field.
private static final int AMETE_MIHRET_ERA = 0;
private static final int AMETE_ALEM_ERA = 1;
private int eraType = AMETE_MIHRET_ERA;
/**
* Constructs a default <code>EthiopicCalendar</code> using the current time in the default time
* zone with the default locale.
*
* @stable ICU 3.4
*/
public EthiopicCalendar() {
this(TimeZone.getDefault(), ULocale.getDefault(Category.FORMAT));
}
/**
* Constructs a <code>EthiopicCalendar</code> based on the current time in the given time zone
* with the default locale.
*
* @param zone The time zone for the new calendar.
* @stable ICU 3.4
*/
public EthiopicCalendar(TimeZone zone) {
this(zone, ULocale.getDefault(Category.FORMAT));
}
/**
* Constructs a <code>EthiopicCalendar</code> based on the current time in the default time zone
* with the given locale.
*
* @param aLocale The locale for the new calendar.
* @stable ICU 3.4
*/
public EthiopicCalendar(Locale aLocale) {
this(TimeZone.forLocaleOrDefault(aLocale), aLocale);
}
/**
* Constructs a <code>EthiopicCalendar</code> based on the current time in the default time zone
* with the given locale.
*
* @param locale The icu locale for the new calendar.
* @stable ICU 3.4
*/
public EthiopicCalendar(ULocale locale) {
this(TimeZone.forULocaleOrDefault(locale), locale);
}
/**
* Constructs a <code>EthiopicCalendar</code> based on the current time in the given time zone
* with the given locale.
*
* @param zone The time zone for the new calendar.
* @param aLocale The locale for the new calendar.
* @stable ICU 3.4
*/
public EthiopicCalendar(TimeZone zone, Locale aLocale) {
this(zone, ULocale.forLocale(aLocale));
}
/**
* Constructs a <code>EthiopicCalendar</code> based on the current time in the given time zone
* with the given locale.
*
* @param zone The time zone for the new calendar.
* @param locale The icu locale for the new calendar.
* @stable ICU 3.4
*/
public EthiopicCalendar(TimeZone zone, ULocale locale) {
super(zone, locale);
setCalcTypeForLocale(locale);
}
/**
* Constructs a <code>EthiopicCalendar</code> 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} time field.
* @param month The value used to set the calendar's {@link #MONTH MONTH} time field. The value
* is 0-based. e.g., 0 for Meskerem.
* @param date The value used to set the calendar's {@link #DATE DATE} time field.
* @stable ICU 3.4
*/
public EthiopicCalendar(int year, int month, int date) {
super(year, month, date);
}
/**
* Constructs a <code>EthiopicCalendar</code> 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 3.4
*/
public EthiopicCalendar(Date date) {
super(date);
}
/**
* Constructs a <code>EthiopicCalendar</code> 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.
* @param month The value used to set the calendar's {@link #MONTH MONTH} time field. The value
* is 0-based. e.g., 0 for Meskerem.
* @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 3.4
*/
public EthiopicCalendar(int year, int month, int date, int hour, int minute, int second) {
super(year, month, date, hour, minute, second);
}
/**
* {@inheritDoc}
*
* @stable ICU 3.8
*/
@Override
public String getType() {
if (isAmeteAlemEra()) {
return "ethiopic-amete-alem";
}
return "ethiopic";
}
/**
* Set Alem or Mihret era.
*
* @param onOff Set Amete Alem era if true, otherwise set Amete Mihret era.
* @stable ICU 3.4
*/
public void setAmeteAlemEra(boolean onOff) {
eraType = onOff ? AMETE_ALEM_ERA : AMETE_MIHRET_ERA;
}
/**
* Return true if this calendar is set to the Amete Alem era.
*
* @return true if set to the Amete Alem era.
* @stable ICU 3.4
*/
public boolean isAmeteAlemEra() {
return (eraType == AMETE_ALEM_ERA);
}
/**
* {@inheritDoc}
*
* @internal
* @deprecated This API is ICU internal only.
*/
@Override
@Deprecated
protected int handleGetExtendedYear() {
// Ethiopic calendar uses EXTENDED_YEAR aligned to
// Amelete Mihret year always.
int eyear;
if (newerField(EXTENDED_YEAR, YEAR) == EXTENDED_YEAR) {
eyear = internalGet(EXTENDED_YEAR, 1); // Default to year 1
} else if (isAmeteAlemEra()) {
eyear = internalGet(YEAR, 1); // Default to year 1
} else {
// The year defaults to the epoch start, the era to AMETE_MIHRET
int era = internalGet(ERA, AMETE_MIHRET);
if (era == AMETE_MIHRET) {
eyear = internalGet(YEAR, 1); // Default to year 1
} else {
eyear = internalGet(YEAR, 1) - AMETE_MIHRET_DELTA;
}
}
return eyear;
}
/**
* {@inheritDoc}
*
* @internal
* @deprecated This API is ICU internal only.
*/
@Deprecated
@Override
protected int extendedYearToEra(int eyear) {
if (isAmeteAlemEra()) {
return AMETE_ALEM;
} else {
return (eyear <= 0) ? AMETE_ALEM : AMETE_MIHRET;
}
}
/**
* {@inheritDoc}
*
* @internal
* @deprecated This API is ICU internal only.
*/
@Deprecated
@Override
protected int extendedYearToYear(int eyear) {
if (isAmeteAlemEra()) {
return eyear;
} else {
return (eyear <= 0) ? eyear + AMETE_MIHRET_DELTA : eyear;
}
}
/**
* {@inheritDoc}
*
* @internal
* @deprecated This API is ICU internal only.
*/
@Override
@Deprecated
protected int handleGetLimit(int field, int limitType) {
if (isAmeteAlemEra() && field == ERA) {
return 0; // Only one era in this mode, era is always 0
}
return super.handleGetLimit(field, limitType);
}
/**
* {@inheritDoc}
*
* @internal
* @deprecated This API is ICU internal only.
*/
@Override
@Deprecated
protected int getJDEpochOffset() {
return isAmeteAlemEra() ? JD_EPOCH_OFFSET_AMETE_ALEM : JD_EPOCH_OFFSET_AMETE_MIHRET;
}
/**
* Convert an Ethiopic year, month, and day to a Julian day.
*
* @param year the year
* @param month the month
* @param date the day
* @draft ICU 3.4 (retain)
*/
// The equivalent operation can be done by public Calendar API.
// This API was accidentally marked as @draft, but we have no good
// reason to keep this. For now, we leave it as is, but may be
// removed in future. 2008-03-21 yoshito
public static int EthiopicToJD(long year, int month, int date) {
return ceToJD(year, month, date, JD_EPOCH_OFFSET_AMETE_MIHRET);
}
private static final int ETHIOPIC_CALENDAR_RELATED_YEAR_DIFFERENCE = 8;
/**
* @internal
* @deprecated This API is ICU internal only.
*/
@Deprecated
protected final int getRelatedYearDifference() {
return ETHIOPIC_CALENDAR_RELATED_YEAR_DIFFERENCE;
}
/** set type based on locale */
private void setCalcTypeForLocale(ULocale locale) {
String localeCalType = CalendarUtil.getCalendarType(locale);
if ("ethiopic-amete-alem".equals(localeCalType)) {
setAmeteAlemEra(true);
} else {
setAmeteAlemEra(false); // default - Amete Mihret
}
}
}