mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-07 06:25:30 +00:00
ICU-10249 Implement new islamic calendar variants tbla, rgsa
X-SVN-Rev: 34354
This commit is contained in:
parent
1e57298e3f
commit
c42e57a06c
5 changed files with 66 additions and 12 deletions
|
@ -323,9 +323,14 @@ static Calendar *createStandardCalendar(ECalType calType, const Locale &loc, UEr
|
|||
case CALTYPE_PERSIAN:
|
||||
cal = new PersianCalendar(loc, status);
|
||||
break;
|
||||
case CALTYPE_ISLAMIC_TBLA:
|
||||
cal = new IslamicCalendar(loc, status, IslamicCalendar::TBLA);
|
||||
break;
|
||||
case CALTYPE_ISLAMIC_CIVIL:
|
||||
cal = new IslamicCalendar(loc, status, IslamicCalendar::CIVIL);
|
||||
break;
|
||||
case CALTYPE_ISLAMIC_RGSA:
|
||||
// default any region specific not handled individually to islamic
|
||||
case CALTYPE_ISLAMIC:
|
||||
cal = new IslamicCalendar(loc, status, IslamicCalendar::ASTRONOMICAL);
|
||||
break;
|
||||
|
@ -358,9 +363,6 @@ static Calendar *createStandardCalendar(ECalType calType, const Locale &loc, UEr
|
|||
case CALTYPE_DANGI:
|
||||
cal = new DangiCalendar(loc, status);
|
||||
break;
|
||||
case CALTYPE_ISLAMIC_TBLA:
|
||||
case CALTYPE_ISLAMIC_RGSA:
|
||||
// Need to add handling for these, meanwhile fall through to default
|
||||
default:
|
||||
status = U_UNSUPPORTED_ERROR;
|
||||
}
|
||||
|
|
|
@ -82,6 +82,8 @@ const char *IslamicCalendar::getType() const {
|
|||
return "islamic-civil";
|
||||
} else if(civil==ASTRONOMICAL){
|
||||
return "islamic";
|
||||
} else if(civil==TBLA){
|
||||
return "islamic-tbla";
|
||||
} else {
|
||||
return "islamic-umalqura";
|
||||
}
|
||||
|
@ -198,7 +200,7 @@ UBool IslamicCalendar::civilLeapYear(int32_t year)
|
|||
* from the Hijri epoch, origin 0.
|
||||
*/
|
||||
int32_t IslamicCalendar::yearStart(int32_t year) const{
|
||||
if (civil == CIVIL ||
|
||||
if (civil == CIVIL || civil == TBLA ||
|
||||
(civil == UMALQURA && year < UMALQURA_YEAR_START))
|
||||
{
|
||||
return (year-1)*354 + ClockMath::floorDivide((3+11*year),30);
|
||||
|
@ -222,7 +224,7 @@ int32_t IslamicCalendar::yearStart(int32_t year) const{
|
|||
* @param year The hijri month, 0-based
|
||||
*/
|
||||
int32_t IslamicCalendar::monthStart(int32_t year, int32_t month) const {
|
||||
if (civil == CIVIL) {
|
||||
if (civil == CIVIL || civil == TBLA) {
|
||||
return (int32_t)uprv_ceil(29.5*month)
|
||||
+ (year-1)*354 + (int32_t)ClockMath::floorDivide((3+11*year),30);
|
||||
} else if(civil==ASTRONOMICAL){
|
||||
|
@ -340,7 +342,7 @@ int32_t IslamicCalendar::handleGetMonthLength(int32_t extendedYear, int32_t mont
|
|||
|
||||
int32_t length = 0;
|
||||
|
||||
if (civil == CIVIL ||
|
||||
if (civil == CIVIL || civil == TBLA ||
|
||||
(civil == UMALQURA && (extendedYear<UMALQURA_YEAR_START || extendedYear>UMALQURA_YEAR_END)) ) {
|
||||
length = 29 + (month+1) % 2;
|
||||
if (month == DHU_AL_HIJJAH && civilLeapYear(extendedYear)) {
|
||||
|
@ -360,7 +362,7 @@ int32_t IslamicCalendar::handleGetMonthLength(int32_t extendedYear, int32_t mont
|
|||
* @draft ICU 2.4
|
||||
*/
|
||||
int32_t IslamicCalendar::handleGetYearLength(int32_t extendedYear) const {
|
||||
if (civil == CIVIL ||
|
||||
if (civil == CIVIL || civil == TBLA ||
|
||||
(civil == UMALQURA && (extendedYear<UMALQURA_YEAR_START || extendedYear>UMALQURA_YEAR_END)) ) {
|
||||
return 354 + (civilLeapYear(extendedYear) ? 1 : 0);
|
||||
} else if(civil == ASTRONOMICAL){
|
||||
|
@ -422,9 +424,11 @@ int32_t IslamicCalendar::handleGetExtendedYear() {
|
|||
void IslamicCalendar::handleComputeFields(int32_t julianDay, UErrorCode &status) {
|
||||
int32_t year, month, dayOfMonth, dayOfYear;
|
||||
UDate startDate;
|
||||
int32_t days = julianDay - 1948440;
|
||||
int32_t days = julianDay - CIVIL_EPOC;
|
||||
|
||||
if (civil == CIVIL) {
|
||||
if (civil == CIVIL || civil == TBLA) {
|
||||
if(civil == TBLA)
|
||||
days = julianDay - ASTRONOMICAL_EPOC;
|
||||
// Use the civil calendar approximation, which is just arithmetic
|
||||
year = (int)ClockMath::floorDivide( (double)(30 * days + 10646) , 10631.0 );
|
||||
month = (int32_t)uprv_ceil((days - 29 - yearStart(year)) / 29.5 );
|
||||
|
|
|
@ -94,7 +94,8 @@ class U_I18N_API IslamicCalendar : public Calendar {
|
|||
enum ECivil {
|
||||
ASTRONOMICAL,
|
||||
CIVIL,
|
||||
UMALQURA
|
||||
UMALQURA,
|
||||
TBLA
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -178,7 +179,6 @@ class U_I18N_API IslamicCalendar : public Calendar {
|
|||
};
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Constructors...
|
||||
//-------------------------------------------------------------------------
|
||||
|
@ -441,6 +441,17 @@ class U_I18N_API IslamicCalendar : public Calendar {
|
|||
static const int32_t UMALQURA_YEAR_END = 1480;
|
||||
|
||||
|
||||
/**
|
||||
* Friday EPOC
|
||||
*/
|
||||
static const int32_t CIVIL_EPOC = 1948440;
|
||||
|
||||
/**
|
||||
* Thursday EPOC
|
||||
*/
|
||||
static const int32_t ASTRONOMICAL_EPOC = 1948439;
|
||||
|
||||
|
||||
static const int getUmalqura_MonthLength(int i, int j){
|
||||
|
||||
static const int UMALQURA_MONTHLENGTH[] = {
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
* Copyright (c) 1997-2013, International Business Machines Corporation
|
||||
* and others. All Rights Reserved.
|
||||
************************************************************************/
|
||||
|
||||
#include "unicode/utypes.h"
|
||||
|
||||
#if !UCONFIG_NO_FORMATTING
|
||||
|
@ -286,6 +285,13 @@ void CalendarTest::runIndexedTest( int32_t index, UBool exec, const char* &name,
|
|||
logln("Test8449---"); logln("");
|
||||
Test8449();
|
||||
}
|
||||
break;
|
||||
case 32:
|
||||
name = "Test10249";
|
||||
if(exec) {
|
||||
logln("Test10249---"); logln("");
|
||||
Test10249();
|
||||
}
|
||||
break;
|
||||
default: name = ""; break;
|
||||
}
|
||||
|
@ -2844,6 +2850,36 @@ void CalendarTest::Test8449() {
|
|||
delete tstCal;
|
||||
}
|
||||
|
||||
void CalendarTest::Test10249() {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
Locale islamicLoc("ar_SA@calendar=islamic-civil");
|
||||
Locale tblaLoc("ar_SA@calendar=islamic-tbla");
|
||||
SimpleDateFormat* formatter = new SimpleDateFormat("yyyy-MM-dd", Locale::getUS(), status);
|
||||
UDate date = formatter->parse("1975-05-06", status);
|
||||
|
||||
Calendar* tstCal = Calendar::createInstance(islamicLoc, status);
|
||||
tstCal->setTime(date, status);
|
||||
int32_t is_day = tstCal->get(UCAL_DAY_OF_MONTH,status);
|
||||
int32_t is_month = tstCal->get(UCAL_MONTH,status);
|
||||
int32_t is_year = tstCal->get(UCAL_YEAR,status);
|
||||
TEST_CHECK_STATUS;
|
||||
delete tstCal;
|
||||
|
||||
tstCal = Calendar::createInstance(tblaLoc, status);
|
||||
tstCal->setTime(date, status);
|
||||
int32_t tbla_day = tstCal->get(UCAL_DAY_OF_MONTH,status);
|
||||
int32_t tbla_month = tstCal->get(UCAL_MONTH,status);
|
||||
int32_t tbla_year = tstCal->get(UCAL_YEAR,status);
|
||||
TEST_CHECK_STATUS;
|
||||
|
||||
if(tbla_month != is_month || tbla_year != is_year)
|
||||
errln("unexpected difference between islamic and tbla month %d : %d and/or year %d : %d",tbla_month,is_month,tbla_year,is_year);
|
||||
|
||||
if(tbla_day - is_day != 1)
|
||||
errln("unexpected day difference between islamic and tbla: %d : %d ",tbla_day,is_day);
|
||||
delete tstCal;
|
||||
delete formatter;
|
||||
}
|
||||
|
||||
|
||||
#endif /* #if !UCONFIG_NO_FORMATTING */
|
||||
|
|
|
@ -220,6 +220,7 @@ public: // package
|
|||
void Test3785(void);
|
||||
void Test1624(void);
|
||||
void Test8449(void);
|
||||
void Test10249(void);
|
||||
|
||||
/**
|
||||
* Test the time stamp array recalculation during heavy Calendar usage
|
||||
|
|
Loading…
Add table
Reference in a new issue