mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-08 06:53:45 +00:00
ICU-10249 Implement new Islamic calendar variants tbla, rgsa
X-SVN-Rev: 34172
This commit is contained in:
parent
b8227cab88
commit
d2d0d0d9f0
3 changed files with 95 additions and 16 deletions
|
@ -25,7 +25,6 @@ import com.ibm.icu.text.DateFormat;
|
|||
import com.ibm.icu.text.DateFormatSymbols;
|
||||
import com.ibm.icu.text.MessageFormat;
|
||||
import com.ibm.icu.text.SimpleDateFormat;
|
||||
import com.ibm.icu.util.IslamicCalendar.CalculationType;
|
||||
import com.ibm.icu.util.ULocale.Category;
|
||||
|
||||
/**
|
||||
|
@ -1881,15 +1880,11 @@ public abstract class Calendar implements Serializable, Cloneable, Comparable<Ca
|
|||
cal = new PersianCalendar(zone, locale);
|
||||
break;
|
||||
case CALTYPE_ISLAMIC_CIVIL:
|
||||
cal = new IslamicCalendar(zone, locale);
|
||||
break;
|
||||
case CALTYPE_ISLAMIC_UMALQURA :
|
||||
cal=new IslamicCalendar (zone,locale);
|
||||
((IslamicCalendar)cal).setType(CalculationType.ISLAMIC_UMALQURA);
|
||||
break;
|
||||
case CALTYPE_ISLAMIC_TBLA:
|
||||
case CALTYPE_ISLAMIC_RGSA:
|
||||
case CALTYPE_ISLAMIC:
|
||||
cal = new IslamicCalendar(zone, locale);
|
||||
((IslamicCalendar)cal).setType(CalculationType.ISLAMIC);
|
||||
break;
|
||||
case CALTYPE_HEBREW:
|
||||
cal = new HebrewCalendar(zone, locale);
|
||||
|
@ -1919,9 +1914,6 @@ public abstract class Calendar implements Serializable, Cloneable, Comparable<Ca
|
|||
cal.setFirstDayOfWeek(MONDAY);
|
||||
cal.setMinimalDaysInFirstWeek(4);
|
||||
break;
|
||||
case CALTYPE_ISLAMIC_TBLA:
|
||||
case CALTYPE_ISLAMIC_RGSA:
|
||||
// Need to add handling for these, meanwhile fall through to default
|
||||
default:
|
||||
// we must not get here, because unknown type is mapped to
|
||||
// Gregorian at the beginning of this method.
|
||||
|
|
|
@ -12,6 +12,7 @@ import java.util.Locale;
|
|||
|
||||
import com.ibm.icu.impl.CalendarAstronomer;
|
||||
import com.ibm.icu.impl.CalendarCache;
|
||||
import com.ibm.icu.impl.CalendarUtil;
|
||||
import com.ibm.icu.util.ULocale.Category;
|
||||
|
||||
/**
|
||||
|
@ -167,6 +168,15 @@ public class IslamicCalendar extends Calendar {
|
|||
|
||||
private static final long HIJRA_MILLIS = -42521587200000L; // 7/16/622 AD 00:00
|
||||
|
||||
/**
|
||||
* Friday EPOC
|
||||
*/
|
||||
private static final long CIVIL_EPOC = 1948440;
|
||||
/**
|
||||
* Thursday EPOC
|
||||
*/
|
||||
private static final long ASTRONOMICAL_EPOC = 1948439;
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Constructors...
|
||||
//-------------------------------------------------------------------------
|
||||
|
@ -228,8 +238,7 @@ public class IslamicCalendar extends Calendar {
|
|||
*/
|
||||
public IslamicCalendar(TimeZone zone, Locale aLocale)
|
||||
{
|
||||
super(zone, aLocale);
|
||||
setTimeInMillis(System.currentTimeMillis());
|
||||
this(zone, ULocale.forLocale(aLocale));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -243,6 +252,7 @@ public class IslamicCalendar extends Calendar {
|
|||
public IslamicCalendar(TimeZone zone, ULocale locale)
|
||||
{
|
||||
super(zone, locale);
|
||||
setCalcTypeForLocale(locale);
|
||||
setTimeInMillis(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
|
@ -504,6 +514,7 @@ public class IslamicCalendar extends Calendar {
|
|||
private long yearStart(int year) {
|
||||
long ys = 0;
|
||||
if (cType == CalculationType.ISLAMIC_CIVIL
|
||||
|| cType == CalculationType.ISLAMIC_TBLA
|
||||
|| (cType == CalculationType.ISLAMIC_UMALQURA && year < UMALQURA_YEAR_START )) {
|
||||
ys = (year-1)*354 + (long)Math.floor((3+11*year)/30.0);
|
||||
} else if(cType == CalculationType.ISLAMIC) {
|
||||
|
@ -532,6 +543,7 @@ public class IslamicCalendar extends Calendar {
|
|||
int realMonth = month % 12;
|
||||
long ms = 0;
|
||||
if (cType == CalculationType.ISLAMIC_CIVIL
|
||||
|| cType == CalculationType.ISLAMIC_TBLA
|
||||
|| (cType == CalculationType.ISLAMIC_UMALQURA && year < UMALQURA_YEAR_START )) {
|
||||
ms = (long)Math.ceil(29.5*realMonth)
|
||||
+ (realYear-1)*354 + (long)Math.floor((3+11*realYear)/30.0);
|
||||
|
@ -656,7 +668,8 @@ public class IslamicCalendar extends Calendar {
|
|||
|
||||
int length = 0;
|
||||
|
||||
if (cType == CalculationType.ISLAMIC_CIVIL
|
||||
if (cType == CalculationType.ISLAMIC_CIVIL
|
||||
|| cType == CalculationType.ISLAMIC_TBLA
|
||||
|| (cType == CalculationType.ISLAMIC_UMALQURA && (extendedYear < UMALQURA_YEAR_START || extendedYear > UMALQURA_YEAR_END) )) {
|
||||
length = 29 + (month+1) % 2;
|
||||
if (month == DHU_AL_HIJJAH && civilLeapYear(extendedYear)) {
|
||||
|
@ -683,6 +696,7 @@ public class IslamicCalendar extends Calendar {
|
|||
protected int handleGetYearLength(int extendedYear) {
|
||||
int length =0;
|
||||
if (cType == CalculationType.ISLAMIC_CIVIL
|
||||
|| cType == CalculationType.ISLAMIC_TBLA
|
||||
|| (cType == CalculationType.ISLAMIC_UMALQURA && (extendedYear < UMALQURA_YEAR_START || extendedYear > UMALQURA_YEAR_END) )) {
|
||||
length = 354 + (civilLeapYear(extendedYear) ? 1 : 0);
|
||||
} else if (cType == CalculationType.ISLAMIC) {
|
||||
|
@ -744,9 +758,12 @@ public class IslamicCalendar extends Calendar {
|
|||
protected void handleComputeFields(int julianDay) {
|
||||
int year =0, month=0, dayOfMonth=0, dayOfYear=0;
|
||||
long monthStart;
|
||||
long days = julianDay - 1948440;
|
||||
long days = julianDay - CIVIL_EPOC;
|
||||
|
||||
if (cType == CalculationType.ISLAMIC_CIVIL) {
|
||||
if (cType == CalculationType.ISLAMIC_CIVIL || cType == CalculationType.ISLAMIC_TBLA) {
|
||||
if (cType == CalculationType.ISLAMIC_TBLA) {
|
||||
days = julianDay - ASTRONOMICAL_EPOC;
|
||||
}
|
||||
// Use the civil calendar approximation, which is just arithmetic
|
||||
year = (int)Math.floor( (30 * days + 10646) / 10631.0 );
|
||||
month = (int)Math.ceil((days - 29 - yearStart(year)) / 29.5 );
|
||||
|
@ -823,7 +840,7 @@ public class IslamicCalendar extends Calendar {
|
|||
*
|
||||
* @draft ICU 52
|
||||
*/
|
||||
public enum CalculationType {ISLAMIC, ISLAMIC_CIVIL, ISLAMIC_UMALQURA};
|
||||
public enum CalculationType {ISLAMIC, ISLAMIC_CIVIL, ISLAMIC_UMALQURA, ISLAMIC_TBLA};
|
||||
|
||||
/**
|
||||
* sets the calculation type for this calendar.
|
||||
|
@ -840,6 +857,22 @@ public class IslamicCalendar extends Calendar {
|
|||
civil = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* set type based on locale
|
||||
*/
|
||||
private void setCalcTypeForLocale(ULocale locale) {
|
||||
String localeCalType = CalendarUtil.getCalendarType(locale);
|
||||
if("islamic-civil".equals(localeCalType))
|
||||
setType(CalculationType.ISLAMIC_CIVIL);
|
||||
else if("islamic-umalqura".equals(localeCalType))
|
||||
setType(CalculationType.ISLAMIC_UMALQURA);
|
||||
else if("islamic-tbla".equals(localeCalType))
|
||||
setType(CalculationType.ISLAMIC_TBLA);
|
||||
else
|
||||
setType(CalculationType.ISLAMIC); // needs to be last so it's always the default
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @stable ICU 3.8
|
||||
|
@ -847,6 +880,8 @@ public class IslamicCalendar extends Calendar {
|
|||
public String getType() {
|
||||
if(cType == CalculationType.ISLAMIC_CIVIL) {
|
||||
return "islamic-civil";
|
||||
} else if (cType == CalculationType.ISLAMIC_TBLA) {
|
||||
return "islamic-tbla";
|
||||
} else if (cType == CalculationType.ISLAMIC) {
|
||||
return "islamic";
|
||||
} else {
|
||||
|
|
|
@ -494,4 +494,56 @@ public class IslamicTest extends CalendarTest {
|
|||
}
|
||||
}
|
||||
|
||||
public void Test10249() {
|
||||
try {
|
||||
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
|
||||
Date date = formatter.parse("1975-05-06");
|
||||
IslamicCalendar is_cal = new IslamicCalendar();
|
||||
is_cal.setType(CalculationType.ISLAMIC_CIVIL);
|
||||
is_cal.setTime(date);
|
||||
IslamicCalendar is_cal2 = new IslamicCalendar();
|
||||
is_cal2.setType(CalculationType.ISLAMIC_TBLA);
|
||||
is_cal2.setTime(date);
|
||||
|
||||
int is_day = is_cal.get(Calendar.DAY_OF_MONTH);
|
||||
int is_day2 = is_cal2.get(Calendar.DAY_OF_MONTH);
|
||||
if(is_day2 - is_day != 1)
|
||||
errln("unexpected difference between civil and tbla: "+is_day2+" : "+is_day);
|
||||
|
||||
}catch(Exception e){
|
||||
errln(e.getLocalizedMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void TestCreationByLocale() {
|
||||
ULocale islamicLoc = new ULocale("ar_SA@calendar=islamic-umalqura");
|
||||
IslamicCalendar is_cal = new IslamicCalendar(islamicLoc);
|
||||
String thisCalcType = is_cal.getType();
|
||||
if(!"islamic-umalqura".equalsIgnoreCase(thisCalcType)) {
|
||||
errln("non umalqura calc type generated - " + thisCalcType);
|
||||
}
|
||||
|
||||
islamicLoc = new ULocale("ar_SA@calendar=islamic-civil");
|
||||
is_cal = new IslamicCalendar(islamicLoc);
|
||||
thisCalcType = is_cal.getType();
|
||||
if(!"islamic-civil".equalsIgnoreCase(thisCalcType)) {
|
||||
errln("non civil calc type generated - " + thisCalcType);
|
||||
}
|
||||
|
||||
islamicLoc = new ULocale("ar_SA@calendar=islamic-tbla");
|
||||
is_cal = new IslamicCalendar(islamicLoc);
|
||||
thisCalcType = is_cal.getType();
|
||||
if(!"islamic-tbla".equalsIgnoreCase(thisCalcType)) {
|
||||
errln("non tbla calc type generated - " + thisCalcType);
|
||||
}
|
||||
|
||||
islamicLoc = new ULocale("ar_SA@calendar=islamic-xyzzy");
|
||||
is_cal = new IslamicCalendar(islamicLoc);
|
||||
thisCalcType = is_cal.getType();
|
||||
if(!"islamic".equalsIgnoreCase(thisCalcType)) {
|
||||
errln("incorrect default calc type generated - " + thisCalcType);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue