mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-07 06:25:30 +00:00
parent
b0ab1171ad
commit
9c1fb785b3
15 changed files with 1458 additions and 373 deletions
|
@ -45,6 +45,7 @@
|
|||
#include "hebrwcal.h"
|
||||
#include "persncal.h"
|
||||
#include "indiancal.h"
|
||||
#include "iso8601cal.h"
|
||||
#include "chnsecal.h"
|
||||
#include "coptccal.h"
|
||||
#include "dangical.h"
|
||||
|
@ -354,18 +355,19 @@ static Calendar *createStandardCalendar(ECalType calType, const Locale &loc, UEr
|
|||
cal.adoptInsteadAndCheckErrorCode(new PersianCalendar(loc, status), status);
|
||||
break;
|
||||
case CALTYPE_ISLAMIC_TBLA:
|
||||
cal.adoptInsteadAndCheckErrorCode(new IslamicCalendar(loc, status, IslamicCalendar::TBLA), status);
|
||||
cal.adoptInsteadAndCheckErrorCode(new IslamicTBLACalendar(loc, status), status);
|
||||
break;
|
||||
case CALTYPE_ISLAMIC_CIVIL:
|
||||
cal.adoptInsteadAndCheckErrorCode(new IslamicCalendar(loc, status, IslamicCalendar::CIVIL), status);
|
||||
cal.adoptInsteadAndCheckErrorCode(new IslamicCivilCalendar(loc, status), status);
|
||||
break;
|
||||
case CALTYPE_ISLAMIC_RGSA:
|
||||
// default any region specific not handled individually to islamic
|
||||
cal.adoptInsteadAndCheckErrorCode(new IslamicRGSACalendar(loc, status), status);
|
||||
break;
|
||||
case CALTYPE_ISLAMIC:
|
||||
cal.adoptInsteadAndCheckErrorCode(new IslamicCalendar(loc, status, IslamicCalendar::ASTRONOMICAL), status);
|
||||
cal.adoptInsteadAndCheckErrorCode(new IslamicCalendar(loc, status), status);
|
||||
break;
|
||||
case CALTYPE_ISLAMIC_UMALQURA:
|
||||
cal.adoptInsteadAndCheckErrorCode(new IslamicCalendar(loc, status, IslamicCalendar::UMALQURA), status);
|
||||
cal.adoptInsteadAndCheckErrorCode(new IslamicUmalquraCalendar(loc, status), status);
|
||||
break;
|
||||
case CALTYPE_HEBREW:
|
||||
cal.adoptInsteadAndCheckErrorCode(new HebrewCalendar(loc, status), status);
|
||||
|
@ -380,17 +382,13 @@ static Calendar *createStandardCalendar(ECalType calType, const Locale &loc, UEr
|
|||
cal.adoptInsteadAndCheckErrorCode(new CopticCalendar(loc, status), status);
|
||||
break;
|
||||
case CALTYPE_ETHIOPIC:
|
||||
cal.adoptInsteadAndCheckErrorCode(new EthiopicCalendar(loc, status, EthiopicCalendar::AMETE_MIHRET_ERA), status);
|
||||
cal.adoptInsteadAndCheckErrorCode(new EthiopicCalendar(loc, status), status);
|
||||
break;
|
||||
case CALTYPE_ETHIOPIC_AMETE_ALEM:
|
||||
cal.adoptInsteadAndCheckErrorCode(new EthiopicCalendar(loc, status, EthiopicCalendar::AMETE_ALEM_ERA), status);
|
||||
cal.adoptInsteadAndCheckErrorCode(new EthiopicAmeteAlemCalendar(loc, status), status);
|
||||
break;
|
||||
case CALTYPE_ISO8601:
|
||||
cal.adoptInsteadAndCheckErrorCode(new GregorianCalendar(loc, status), status);
|
||||
if (cal.isValid()) {
|
||||
cal->setFirstDayOfWeek(UCAL_MONDAY);
|
||||
cal->setMinimalDaysInFirstWeek(4);
|
||||
}
|
||||
cal.adoptInsteadAndCheckErrorCode(new ISO8601Calendar(loc, status), status);
|
||||
break;
|
||||
case CALTYPE_DANGI:
|
||||
cal.adoptInsteadAndCheckErrorCode(new DangiCalendar(loc, status), status);
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
U_NAMESPACE_BEGIN
|
||||
|
||||
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(EthiopicCalendar)
|
||||
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(EthiopicAmeteAlemCalendar)
|
||||
|
||||
//static const int32_t JD_EPOCH_OFFSET_AMETE_ALEM = -285019;
|
||||
static const int32_t JD_EPOCH_OFFSET_AMETE_MIHRET = 1723856;
|
||||
|
@ -29,16 +30,8 @@ static const int32_t AMETE_MIHRET_DELTA = 5500; // 5501 - 1 (Amete Alem 5501 = A
|
|||
//-------------------------------------------------------------------------
|
||||
|
||||
EthiopicCalendar::EthiopicCalendar(const Locale& aLocale,
|
||||
UErrorCode& success,
|
||||
EEraType type /*= AMETE_MIHRET_ERA*/)
|
||||
: CECalendar(aLocale, success),
|
||||
eraType(type)
|
||||
{
|
||||
}
|
||||
|
||||
EthiopicCalendar::EthiopicCalendar(const EthiopicCalendar& other)
|
||||
: CECalendar(other),
|
||||
eraType(other.eraType)
|
||||
UErrorCode& success)
|
||||
: CECalendar(aLocale, success)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -55,24 +48,9 @@ EthiopicCalendar::clone() const
|
|||
const char *
|
||||
EthiopicCalendar::getType() const
|
||||
{
|
||||
if (isAmeteAlemEra()) {
|
||||
return "ethiopic-amete-alem";
|
||||
}
|
||||
return "ethiopic";
|
||||
}
|
||||
|
||||
void
|
||||
EthiopicCalendar::setAmeteAlemEra(UBool onOff)
|
||||
{
|
||||
eraType = onOff ? AMETE_ALEM_ERA : AMETE_MIHRET_ERA;
|
||||
}
|
||||
|
||||
UBool
|
||||
EthiopicCalendar::isAmeteAlemEra() const
|
||||
{
|
||||
return (eraType == AMETE_ALEM_ERA);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Calendar framework
|
||||
//-------------------------------------------------------------------------
|
||||
|
@ -82,63 +60,31 @@ EthiopicCalendar::handleGetExtendedYear()
|
|||
{
|
||||
// Ethiopic calendar uses EXTENDED_YEAR aligned to
|
||||
// Amelete Hihret year always.
|
||||
int32_t eyear;
|
||||
if (newerField(UCAL_EXTENDED_YEAR, UCAL_YEAR) == UCAL_EXTENDED_YEAR) {
|
||||
eyear = internalGet(UCAL_EXTENDED_YEAR, 1); // Default to year 1
|
||||
} else if (isAmeteAlemEra()) {
|
||||
eyear = internalGet(UCAL_YEAR, 1 + AMETE_MIHRET_DELTA)
|
||||
- AMETE_MIHRET_DELTA; // Default to year 1 of Amelete Mihret
|
||||
} else {
|
||||
// The year defaults to the epoch start, the era to AMETE_MIHRET
|
||||
int32_t era = internalGet(UCAL_ERA, AMETE_MIHRET);
|
||||
if (era == AMETE_MIHRET) {
|
||||
eyear = internalGet(UCAL_YEAR, 1); // Default to year 1
|
||||
} else {
|
||||
eyear = internalGet(UCAL_YEAR, 1) - AMETE_MIHRET_DELTA;
|
||||
}
|
||||
return internalGet(UCAL_EXTENDED_YEAR, 1); // Default to year 1
|
||||
}
|
||||
return eyear;
|
||||
// The year defaults to the epoch start, the era to AMETE_MIHRET
|
||||
if (internalGet(UCAL_ERA, AMETE_MIHRET) == AMETE_MIHRET) {
|
||||
return internalGet(UCAL_YEAR, 1); // Default to year 1
|
||||
}
|
||||
return internalGet(UCAL_YEAR, 1) - AMETE_MIHRET_DELTA;
|
||||
}
|
||||
|
||||
void
|
||||
EthiopicCalendar::handleComputeFields(int32_t julianDay, UErrorCode &/*status*/)
|
||||
{
|
||||
int32_t eyear, month, day, era, year;
|
||||
int32_t eyear, month, day;
|
||||
jdToCE(julianDay, getJDEpochOffset(), eyear, month, day);
|
||||
|
||||
if (isAmeteAlemEra()) {
|
||||
era = AMETE_ALEM;
|
||||
year = eyear + AMETE_MIHRET_DELTA;
|
||||
} else {
|
||||
if (eyear > 0) {
|
||||
era = AMETE_MIHRET;
|
||||
year = eyear;
|
||||
} else {
|
||||
era = AMETE_ALEM;
|
||||
year = eyear + AMETE_MIHRET_DELTA;
|
||||
}
|
||||
}
|
||||
|
||||
internalSet(UCAL_EXTENDED_YEAR, eyear);
|
||||
internalSet(UCAL_ERA, era);
|
||||
internalSet(UCAL_YEAR, year);
|
||||
internalSet(UCAL_ERA, (eyear > 0) ? AMETE_MIHRET : AMETE_ALEM);
|
||||
internalSet(UCAL_YEAR, (eyear > 0) ? eyear : (eyear + AMETE_MIHRET_DELTA));
|
||||
internalSet(UCAL_MONTH, month);
|
||||
internalSet(UCAL_DATE, day);
|
||||
internalSet(UCAL_DAY_OF_YEAR, (30 * month) + day);
|
||||
}
|
||||
|
||||
int32_t
|
||||
EthiopicCalendar::handleGetLimit(UCalendarDateFields field, ELimitType limitType) const
|
||||
{
|
||||
if (isAmeteAlemEra() && field == UCAL_ERA) {
|
||||
return 0; // Only one era in this mode, era is always 0
|
||||
}
|
||||
return CECalendar::handleGetLimit(field, limitType);
|
||||
}
|
||||
|
||||
|
||||
constexpr uint32_t kEthiopicRelatedYearDiff = 8;
|
||||
constexpr uint32_t kEthiopicAmeteAlemRelatedYearDiff = -5492;
|
||||
|
||||
int32_t EthiopicCalendar::getRelatedYear(UErrorCode &status) const
|
||||
{
|
||||
|
@ -146,14 +92,13 @@ int32_t EthiopicCalendar::getRelatedYear(UErrorCode &status) const
|
|||
if (U_FAILURE(status)) {
|
||||
return 0;
|
||||
}
|
||||
return year + (isAmeteAlemEra() ? kEthiopicAmeteAlemRelatedYearDiff : kEthiopicRelatedYearDiff);
|
||||
return year + kEthiopicRelatedYearDiff;
|
||||
}
|
||||
|
||||
void EthiopicCalendar::setRelatedYear(int32_t year)
|
||||
{
|
||||
// set extended year
|
||||
set(UCAL_EXTENDED_YEAR, year -
|
||||
(isAmeteAlemEra() ? kEthiopicAmeteAlemRelatedYearDiff : kEthiopicRelatedYearDiff));
|
||||
set(UCAL_EXTENDED_YEAR, year - kEthiopicRelatedYearDiff);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -193,9 +138,6 @@ EthiopicCalendar::defaultCenturyStartYear() const
|
|||
{
|
||||
// lazy-evaluate systemDefaultCenturyStartYear
|
||||
umtx_initOnce(gSystemDefaultCenturyInit, &initializeSystemDefaultCentury);
|
||||
if (isAmeteAlemEra()) {
|
||||
return gSystemDefaultCenturyStartYear + AMETE_MIHRET_DELTA;
|
||||
}
|
||||
return gSystemDefaultCenturyStartYear;
|
||||
}
|
||||
|
||||
|
@ -222,6 +164,94 @@ EthiopicCalendar::ethiopicToJD(int32_t year, int32_t month, int32_t date)
|
|||
}
|
||||
#endif
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Constructors...
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
EthiopicAmeteAlemCalendar::EthiopicAmeteAlemCalendar(const Locale& aLocale,
|
||||
UErrorCode& success)
|
||||
: EthiopicCalendar(aLocale, success)
|
||||
{
|
||||
}
|
||||
|
||||
EthiopicAmeteAlemCalendar::~EthiopicAmeteAlemCalendar()
|
||||
{
|
||||
}
|
||||
|
||||
EthiopicAmeteAlemCalendar*
|
||||
EthiopicAmeteAlemCalendar::clone() const
|
||||
{
|
||||
return new EthiopicAmeteAlemCalendar(*this);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Calendar framework
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
const char *
|
||||
EthiopicAmeteAlemCalendar::getType() const
|
||||
{
|
||||
return "ethiopic-amete-alem";
|
||||
}
|
||||
|
||||
int32_t
|
||||
EthiopicAmeteAlemCalendar::handleGetExtendedYear()
|
||||
{
|
||||
// Ethiopic calendar uses EXTENDED_YEAR aligned to
|
||||
// Amelete Hihret year always.
|
||||
if (newerField(UCAL_EXTENDED_YEAR, UCAL_YEAR) == UCAL_EXTENDED_YEAR) {
|
||||
return internalGet(UCAL_EXTENDED_YEAR, 1); // Default to year 1
|
||||
}
|
||||
return internalGet(UCAL_YEAR, 1 + AMETE_MIHRET_DELTA)
|
||||
- AMETE_MIHRET_DELTA; // Default to year 1 of Amelete Mihret
|
||||
}
|
||||
|
||||
void
|
||||
EthiopicAmeteAlemCalendar::handleComputeFields(int32_t julianDay, UErrorCode &/*status*/)
|
||||
{
|
||||
int32_t eyear, month, day;
|
||||
jdToCE(julianDay, getJDEpochOffset(), eyear, month, day);
|
||||
|
||||
internalSet(UCAL_EXTENDED_YEAR, eyear);
|
||||
internalSet(UCAL_ERA, AMETE_ALEM);
|
||||
internalSet(UCAL_YEAR, eyear + AMETE_MIHRET_DELTA);
|
||||
internalSet(UCAL_MONTH, month);
|
||||
internalSet(UCAL_DATE, day);
|
||||
internalSet(UCAL_DAY_OF_YEAR, (30 * month) + day);
|
||||
}
|
||||
|
||||
int32_t
|
||||
EthiopicAmeteAlemCalendar::handleGetLimit(UCalendarDateFields field, ELimitType limitType) const
|
||||
{
|
||||
if (field == UCAL_ERA) {
|
||||
return 0; // Only one era in this mode, era is always 0
|
||||
}
|
||||
return EthiopicCalendar::handleGetLimit(field, limitType);
|
||||
}
|
||||
|
||||
constexpr uint32_t kEthiopicAmeteAlemRelatedYearDiff = -5492;
|
||||
|
||||
int32_t EthiopicAmeteAlemCalendar::getRelatedYear(UErrorCode &status) const
|
||||
{
|
||||
int32_t year = get(UCAL_EXTENDED_YEAR, status);
|
||||
if (U_FAILURE(status)) {
|
||||
return 0;
|
||||
}
|
||||
return year + kEthiopicAmeteAlemRelatedYearDiff;
|
||||
}
|
||||
|
||||
void EthiopicAmeteAlemCalendar::setRelatedYear(int32_t year)
|
||||
{
|
||||
// set extended year
|
||||
set(UCAL_EXTENDED_YEAR, year - kEthiopicAmeteAlemRelatedYearDiff);
|
||||
}
|
||||
|
||||
int32_t
|
||||
EthiopicAmeteAlemCalendar::defaultCenturyStartYear() const
|
||||
{
|
||||
return EthiopicCalendar::defaultCenturyStartYear() + AMETE_MIHRET_DELTA;
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
|
|
|
@ -26,15 +26,6 @@ U_NAMESPACE_BEGIN
|
|||
class EthiopicCalendar : public CECalendar {
|
||||
|
||||
public:
|
||||
/**
|
||||
* Calendar type - use Amete Alem era for all the time or not
|
||||
* @internal
|
||||
*/
|
||||
enum EEraType {
|
||||
AMETE_MIHRET_ERA,
|
||||
AMETE_ALEM_ERA
|
||||
};
|
||||
|
||||
/**
|
||||
* Useful constants for EthiopicCalendar.
|
||||
* @internal
|
||||
|
@ -122,13 +113,13 @@ public:
|
|||
* only use Amete Alem for all the time.
|
||||
* @internal
|
||||
*/
|
||||
EthiopicCalendar(const Locale& aLocale, UErrorCode& success, EEraType type = AMETE_MIHRET_ERA);
|
||||
EthiopicCalendar(const Locale& aLocale, UErrorCode& success);
|
||||
|
||||
/**
|
||||
* Copy Constructor
|
||||
* @internal
|
||||
*/
|
||||
EthiopicCalendar(const EthiopicCalendar& other);
|
||||
EthiopicCalendar(const EthiopicCalendar& other) = default;
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
|
@ -144,26 +135,12 @@ public:
|
|||
virtual EthiopicCalendar* clone() const override;
|
||||
|
||||
/**
|
||||
* return the calendar type, "ethiopic"
|
||||
* Return the calendar type, "ethiopic"
|
||||
* @return calendar type
|
||||
* @internal
|
||||
*/
|
||||
virtual const char * getType() const override;
|
||||
|
||||
/**
|
||||
* Set Alem or Mihret era.
|
||||
* @param onOff Set Amete Alem era if true, otherwise set Amete Mihret era.
|
||||
* @internal
|
||||
*/
|
||||
void setAmeteAlemEra (UBool onOff);
|
||||
|
||||
/**
|
||||
* Return true if this calendar is set to the Amete Alem era.
|
||||
* @return true if set to the Amete Alem era.
|
||||
* @internal
|
||||
*/
|
||||
UBool isAmeteAlemEra() const;
|
||||
|
||||
/**
|
||||
* @return The related Gregorian year; will be obtained by modifying the value
|
||||
* obtained by get from UCAL_EXTENDED_YEAR field
|
||||
|
@ -185,6 +162,11 @@ protected:
|
|||
|
||||
/**
|
||||
* Return the extended year defined by the current fields.
|
||||
* This calendar uses both AMETE_ALEM and AMETE_MIHRET.
|
||||
*
|
||||
* EXTENDED_YEAR ERA YEAR
|
||||
* 0 AMETE_ALEM 5500
|
||||
* 1 AMETE_MIHRET 1
|
||||
* @internal
|
||||
*/
|
||||
virtual int32_t handleGetExtendedYear() override;
|
||||
|
@ -195,12 +177,6 @@ protected:
|
|||
*/
|
||||
virtual void handleComputeFields(int32_t julianDay, UErrorCode &status) override;
|
||||
|
||||
/**
|
||||
* Calculate the limit for a specified type of limit and field
|
||||
* @internal
|
||||
*/
|
||||
virtual int32_t handleGetLimit(UCalendarDateFields field, ELimitType limitType) const override;
|
||||
|
||||
/**
|
||||
* Returns the date of the start of the default century
|
||||
* @return start of century - in milliseconds since epoch, 1970
|
||||
|
@ -220,18 +196,6 @@ protected:
|
|||
*/
|
||||
virtual int32_t getJDEpochOffset() const override;
|
||||
|
||||
private:
|
||||
/**
|
||||
* When eraType is AMETE_ALEM_ERA, then this calendar use only AMETE_ALEM
|
||||
* for the era. Otherwise (default), this calendar uses both AMETE_ALEM
|
||||
* and AMETE_MIHRET.
|
||||
*
|
||||
* EXTENDED_YEAR AMETE_ALEM_ERA AMETE_MIHRET_ERA
|
||||
* 0 Amete Alem 5500 Amete Alem 5500
|
||||
* 1 Amete Mihret 1 Amete Alem 5501
|
||||
*/
|
||||
EEraType eraType;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Override Calendar Returns a unique class ID POLYMORPHICALLY. Pure virtual
|
||||
|
@ -280,6 +244,123 @@ public:
|
|||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* Implement the Ethiopic Amete Alem calendar system.
|
||||
* @internal
|
||||
*/
|
||||
class EthiopicAmeteAlemCalendar : public EthiopicCalendar {
|
||||
|
||||
public:
|
||||
/**
|
||||
* Constructs a EthiopicAmeteAlemCalendar based on the current time in the default time zone
|
||||
* with the given locale.
|
||||
*
|
||||
* @param aLocale The given locale.
|
||||
* @param success Indicates the status of EthiopicCalendar object construction.
|
||||
* Returns U_ZERO_ERROR if constructed successfully.
|
||||
* @internal
|
||||
*/
|
||||
EthiopicAmeteAlemCalendar(const Locale& aLocale, UErrorCode& success);
|
||||
|
||||
/**
|
||||
* Copy Constructor
|
||||
* @internal
|
||||
*/
|
||||
EthiopicAmeteAlemCalendar(const EthiopicAmeteAlemCalendar& other) = default;
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
* @internal
|
||||
*/
|
||||
virtual ~EthiopicAmeteAlemCalendar();
|
||||
|
||||
/**
|
||||
* Create and return a polymorphic copy of this calendar.
|
||||
* @return return a polymorphic copy of this calendar.
|
||||
* @internal
|
||||
*/
|
||||
virtual EthiopicAmeteAlemCalendar* clone() const override;
|
||||
|
||||
/**
|
||||
* Return the calendar type, "ethiopic-amete-alem"
|
||||
* @return calendar type
|
||||
* @internal
|
||||
*/
|
||||
virtual const char * getType() const override;
|
||||
|
||||
/**
|
||||
* Override Calendar Returns a unique class ID POLYMORPHICALLY. Pure virtual
|
||||
* override. This method is to implement a simple version of RTTI, since not all C++
|
||||
* compilers support genuine RTTI. Polymorphic operator==() and clone() methods call
|
||||
* this method.
|
||||
*
|
||||
* @return The class ID for this object. All objects of a given class have the
|
||||
* same class ID. Objects of other classes have different class IDs.
|
||||
* @internal
|
||||
*/
|
||||
virtual UClassID getDynamicClassID(void) const override;
|
||||
|
||||
/**
|
||||
* Return the class ID for this class. This is useful only for comparing to a return
|
||||
* value from getDynamicClassID(). For example:
|
||||
*
|
||||
* Base* polymorphic_pointer = createPolymorphicObject();
|
||||
* if (polymorphic_pointer->getDynamicClassID() ==
|
||||
* Derived::getStaticClassID()) ...
|
||||
*
|
||||
* @return The class ID for all objects of this class.
|
||||
* @internal
|
||||
*/
|
||||
U_I18N_API static UClassID U_EXPORT2 getStaticClassID(void);
|
||||
|
||||
/**
|
||||
* @return The related Gregorian year; will be obtained by modifying the value
|
||||
* obtained by get from UCAL_EXTENDED_YEAR field
|
||||
* @internal
|
||||
*/
|
||||
virtual int32_t getRelatedYear(UErrorCode &status) const override;
|
||||
|
||||
/**
|
||||
* @param year The related Gregorian year to set; will be modified as necessary then
|
||||
* set in UCAL_EXTENDED_YEAR field
|
||||
* @internal
|
||||
*/
|
||||
virtual void setRelatedYear(int32_t year) override;
|
||||
|
||||
protected:
|
||||
//-------------------------------------------------------------------------
|
||||
// Calendar framework
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Return the extended year defined by the current fields.
|
||||
* This calendar use only AMETE_ALEM for the era.
|
||||
*
|
||||
* EXTENDED_YEAR ERA YEAR
|
||||
* 0 AMETE_ALEM 5500
|
||||
* 1 AMETE_ALEM 5501
|
||||
* @internal
|
||||
*/
|
||||
virtual int32_t handleGetExtendedYear() override;
|
||||
|
||||
/**
|
||||
* Compute fields from the JD
|
||||
* @internal
|
||||
*/
|
||||
virtual void handleComputeFields(int32_t julianDay, UErrorCode &status) override;
|
||||
|
||||
/**
|
||||
* Calculate the limit for a specified type of limit and field
|
||||
* @internal
|
||||
*/
|
||||
virtual int32_t handleGetLimit(UCalendarDateFields field, ELimitType limitType) const override;
|
||||
/**
|
||||
* Returns the year in which the default century begins
|
||||
* @internal
|
||||
*/
|
||||
virtual int32_t defaultCenturyStartYear() const override;
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif /* #if !UCONFIG_NO_FORMATTING */
|
||||
#endif /* ETHPCCAL_H */
|
||||
|
|
|
@ -166,6 +166,7 @@
|
|||
<ClCompile Include="hebrwcal.cpp" />
|
||||
<ClCompile Include="indiancal.cpp" />
|
||||
<ClCompile Include="islamcal.cpp" />
|
||||
<ClCompile Include="iso8601cal.cpp" />
|
||||
<ClCompile Include="japancal.cpp" />
|
||||
<ClCompile Include="listformatter.cpp" />
|
||||
<ClCompile Include="ulistformatter.cpp" />
|
||||
|
@ -384,6 +385,7 @@
|
|||
<ClInclude Include="hebrwcal.h" />
|
||||
<ClInclude Include="indiancal.h" />
|
||||
<ClInclude Include="islamcal.h" />
|
||||
<ClInclude Include="iso8601cal.h" />
|
||||
<ClInclude Include="japancal.h" />
|
||||
<ClInclude Include="measunit_impl.h" />
|
||||
<ClInclude Include="msgfmt_impl.h" />
|
||||
|
|
|
@ -186,6 +186,9 @@
|
|||
<ClCompile Include="indiancal.cpp">
|
||||
<Filter>formatting</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="iso8601cal.cpp">
|
||||
<Filter>formatting</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="islamcal.cpp">
|
||||
<Filter>formatting</Filter>
|
||||
</ClCompile>
|
||||
|
@ -851,6 +854,9 @@
|
|||
<ClInclude Include="indiancal.h">
|
||||
<Filter>formatting</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="iso8601cal.h">
|
||||
<Filter>formatting</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="islamcal.h">
|
||||
<Filter>formatting</Filter>
|
||||
</ClInclude>
|
||||
|
|
|
@ -399,6 +399,7 @@
|
|||
<ClCompile Include="hebrwcal.cpp" />
|
||||
<ClCompile Include="indiancal.cpp" />
|
||||
<ClCompile Include="islamcal.cpp" />
|
||||
<ClCompile Include="iso8601cal.cpp" />
|
||||
<ClCompile Include="japancal.cpp" />
|
||||
<ClCompile Include="listformatter.cpp" />
|
||||
<ClCompile Include="ulistformatter.cpp" />
|
||||
|
@ -615,6 +616,7 @@
|
|||
<ClInclude Include="hebrwcal.h" />
|
||||
<ClInclude Include="indiancal.h" />
|
||||
<ClInclude Include="islamcal.h" />
|
||||
<ClInclude Include="iso8601cal.h" />
|
||||
<ClInclude Include="japancal.h" />
|
||||
<ClInclude Include="measunit_impl.h" />
|
||||
<ClInclude Include="msgfmt_impl.h" />
|
||||
|
|
|
@ -206,67 +206,22 @@ int32_t getUmalqura_MonthLength(int32_t y, int32_t m) {
|
|||
//-------------------------------------------------------------------------
|
||||
|
||||
const char *IslamicCalendar::getType() const {
|
||||
const char *sType = NULL;
|
||||
|
||||
switch (cType) {
|
||||
case CIVIL:
|
||||
sType = "islamic-civil";
|
||||
break;
|
||||
case ASTRONOMICAL:
|
||||
sType = "islamic";
|
||||
break;
|
||||
case TBLA:
|
||||
sType = "islamic-tbla";
|
||||
break;
|
||||
case UMALQURA:
|
||||
sType = "islamic-umalqura";
|
||||
break;
|
||||
default:
|
||||
UPRV_UNREACHABLE_EXIT; // out of range
|
||||
}
|
||||
return sType;
|
||||
return "islamic";
|
||||
}
|
||||
|
||||
IslamicCalendar* IslamicCalendar::clone() const {
|
||||
return new IslamicCalendar(*this);
|
||||
}
|
||||
|
||||
IslamicCalendar::IslamicCalendar(const Locale& aLocale, UErrorCode& success, ECalculationType type)
|
||||
: Calendar(TimeZone::forLocaleOrDefault(aLocale), aLocale, success),
|
||||
cType(type)
|
||||
IslamicCalendar::IslamicCalendar(const Locale& aLocale, UErrorCode& success)
|
||||
: Calendar(TimeZone::forLocaleOrDefault(aLocale), aLocale, success)
|
||||
{
|
||||
setTimeInMillis(getNow(), success); // Call this again now that the vtable is set up properly.
|
||||
}
|
||||
|
||||
IslamicCalendar::IslamicCalendar(const IslamicCalendar& other) : Calendar(other), cType(other.cType) {
|
||||
}
|
||||
|
||||
IslamicCalendar::~IslamicCalendar()
|
||||
{
|
||||
}
|
||||
|
||||
void IslamicCalendar::setCalculationType(ECalculationType type, UErrorCode &status)
|
||||
{
|
||||
if (cType != type) {
|
||||
// The fields of the calendar will become invalid, because the calendar
|
||||
// rules are different
|
||||
UDate m = getTimeInMillis(status);
|
||||
cType = type;
|
||||
clear();
|
||||
setTimeInMillis(m, status);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if this object is using the fixed-cycle civil
|
||||
* calendar, or <code>false</code> if using the religious, astronomical
|
||||
* calendar.
|
||||
* @draft ICU 2.4
|
||||
*/
|
||||
UBool IslamicCalendar::isCivil() {
|
||||
return (cType == CIVIL);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Minimum / Maximum access functions
|
||||
//-------------------------------------------------------------------------
|
||||
|
@ -365,19 +320,7 @@ UBool IslamicCalendar::civilLeapYear(int32_t year)
|
|||
* from the Hijri epoch, origin 0.
|
||||
*/
|
||||
int32_t IslamicCalendar::yearStart(int32_t year) const{
|
||||
if (cType == CIVIL || cType == TBLA ||
|
||||
(cType == UMALQURA && (year < UMALQURA_YEAR_START || year > UMALQURA_YEAR_END)))
|
||||
{
|
||||
return (year-1)*354 + ClockMath::floorDivide((3+11*(int64_t)year),(int64_t)30);
|
||||
} else if(cType==ASTRONOMICAL){
|
||||
return trueMonthStart(12*(year-1));
|
||||
} else {
|
||||
year -= UMALQURA_YEAR_START;
|
||||
// rounded least-squares fit of the dates previously calculated from UMALQURA_MONTHLENGTH iteration
|
||||
int32_t yrStartLinearEstimate = (int32_t)((354.36720 * (double)year) + 460322.05 + 0.5);
|
||||
// need a slight correction to some
|
||||
return yrStartLinearEstimate + umAlQuraYrStartEstimateFix[year];
|
||||
}
|
||||
return trueMonthStart(12*(year-1));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -388,19 +331,7 @@ int32_t IslamicCalendar::yearStart(int32_t year) const{
|
|||
* @param month The hijri month, 0-based (assumed to be in range 0..11)
|
||||
*/
|
||||
int32_t IslamicCalendar::monthStart(int32_t year, int32_t month) const {
|
||||
if (cType == CIVIL || cType == TBLA) {
|
||||
// This does not handle months out of the range 0..11
|
||||
return (int32_t)uprv_ceil(29.5*month)
|
||||
+ (year-1)*354 + (int32_t)ClockMath::floorDivide((3+11*(int64_t)year),(int64_t)30);
|
||||
} else if(cType==ASTRONOMICAL){
|
||||
return trueMonthStart(12*(year-1) + month);
|
||||
} else {
|
||||
int32_t ms = yearStart(year);
|
||||
for(int i=0; i< month; i++){
|
||||
ms+= handleGetMonthLength(year, i);
|
||||
}
|
||||
return ms;
|
||||
}
|
||||
return trueMonthStart(12*(year-1) + month);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -506,22 +437,8 @@ double IslamicCalendar::moonAge(UDate time, UErrorCode &status)
|
|||
* @draft ICU 2.4
|
||||
*/
|
||||
int32_t IslamicCalendar::handleGetMonthLength(int32_t extendedYear, int32_t month) const {
|
||||
|
||||
int32_t length = 0;
|
||||
|
||||
if (cType == CIVIL || cType == TBLA ||
|
||||
(cType == UMALQURA && (extendedYear<UMALQURA_YEAR_START || extendedYear>UMALQURA_YEAR_END)) ) {
|
||||
length = 29 + (month+1) % 2;
|
||||
if (month == DHU_AL_HIJJAH && civilLeapYear(extendedYear)) {
|
||||
length++;
|
||||
}
|
||||
} else if(cType == ASTRONOMICAL){
|
||||
month = 12*(extendedYear-1) + month;
|
||||
length = trueMonthStart(month+1) - trueMonthStart(month) ;
|
||||
} else {
|
||||
length = getUmalqura_MonthLength(extendedYear - UMALQURA_YEAR_START, month);
|
||||
}
|
||||
return length;
|
||||
month = 12*(extendedYear-1) + month;
|
||||
return trueMonthStart(month+1) - trueMonthStart(month) ;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -529,19 +446,8 @@ int32_t IslamicCalendar::handleGetMonthLength(int32_t extendedYear, int32_t mont
|
|||
* @draft ICU 2.4
|
||||
*/
|
||||
int32_t IslamicCalendar::handleGetYearLength(int32_t extendedYear) const {
|
||||
if (cType == CIVIL || cType == TBLA ||
|
||||
(cType == UMALQURA && (extendedYear<UMALQURA_YEAR_START || extendedYear>UMALQURA_YEAR_END)) ) {
|
||||
return 354 + (civilLeapYear(extendedYear) ? 1 : 0);
|
||||
} else if(cType == ASTRONOMICAL){
|
||||
int32_t month = 12*(extendedYear-1);
|
||||
return (trueMonthStart(month + 12) - trueMonthStart(month));
|
||||
} else {
|
||||
int len = 0;
|
||||
for(int i=0; i<12; i++) {
|
||||
len += handleGetMonthLength(extendedYear, i);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
int32_t month = 12*(extendedYear-1);
|
||||
return (trueMonthStart(month + 12) - trueMonthStart(month));
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
@ -567,8 +473,8 @@ int32_t IslamicCalendar::handleComputeMonthStart(int32_t eyear, int32_t month, U
|
|||
eyear += (month / 12) - 1;
|
||||
month = (month % 12) + 11;
|
||||
}
|
||||
return monthStart(eyear, month) + ((cType == TBLA)? ASTRONOMICAL_EPOC: CIVIL_EPOC) - 1;
|
||||
}
|
||||
return monthStart(eyear, month) + getEpoc() - 1;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Functions for converting from milliseconds to field values
|
||||
|
@ -604,93 +510,49 @@ int32_t IslamicCalendar::handleGetExtendedYear() {
|
|||
* @draft ICU 2.4
|
||||
*/
|
||||
void IslamicCalendar::handleComputeFields(int32_t julianDay, UErrorCode &status) {
|
||||
int32_t year, month, dayOfMonth, dayOfYear;
|
||||
int32_t startDate;
|
||||
int32_t days = julianDay - CIVIL_EPOC;
|
||||
if (U_FAILURE(status)) return;
|
||||
int32_t days = julianDay - getEpoc();
|
||||
|
||||
if (cType == CIVIL || cType == TBLA) {
|
||||
if(cType == TBLA) {
|
||||
days = julianDay - ASTRONOMICAL_EPOC;
|
||||
}
|
||||
// Use the civil calendar approximation, which is just arithmetic
|
||||
year = (int32_t)ClockMath::floorDivide(30 * (int64_t)days + 10646, (int64_t)10631);
|
||||
month = (int32_t)uprv_ceil((days - 29 - yearStart(year)) / 29.5 );
|
||||
month = month<11?month:11;
|
||||
startDate = monthStart(year, month);
|
||||
} else if(cType == ASTRONOMICAL){
|
||||
// Guess at the number of elapsed full months since the epoch
|
||||
int32_t months = (int32_t)uprv_floor((double)days / CalendarAstronomer::SYNODIC_MONTH);
|
||||
// Guess at the number of elapsed full months since the epoch
|
||||
int32_t month = (int32_t)uprv_floor((double)days / CalendarAstronomer::SYNODIC_MONTH);
|
||||
|
||||
startDate = (int32_t)uprv_floor(months * CalendarAstronomer::SYNODIC_MONTH);
|
||||
int32_t startDate = (int32_t)uprv_floor(month * CalendarAstronomer::SYNODIC_MONTH);
|
||||
|
||||
double age = moonAge(internalGetTime(), status);
|
||||
if (U_FAILURE(status)) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
return;
|
||||
}
|
||||
if ( days - startDate >= 25 && age > 0) {
|
||||
// If we're near the end of the month, assume next month and search backwards
|
||||
months++;
|
||||
}
|
||||
|
||||
// Find out the last time that the new moon was actually visible at this longitude
|
||||
// This returns midnight the night that the moon was visible at sunset.
|
||||
while ((startDate = trueMonthStart(months)) > days) {
|
||||
// If it was after the date in question, back up a month and try again
|
||||
months--;
|
||||
}
|
||||
|
||||
year = months >= 0 ? ((months / 12) + 1) : ((months + 1 ) / 12);
|
||||
month = ((months % 12) + 12 ) % 12;
|
||||
} else if(cType == UMALQURA) {
|
||||
int32_t umalquraStartdays = yearStart(UMALQURA_YEAR_START) ;
|
||||
if( days < umalquraStartdays){
|
||||
//Use Civil calculation
|
||||
year = (int32_t)ClockMath::floorDivide(
|
||||
(30 * (int64_t)days + 10646) , (int64_t)10631.0 );
|
||||
month = (int32_t)uprv_ceil((days - 29 - yearStart(year)) / 29.5 );
|
||||
month = month<11?month:11;
|
||||
startDate = monthStart(year, month);
|
||||
}else{
|
||||
int y =UMALQURA_YEAR_START-1, m =0;
|
||||
long d = 1;
|
||||
while(d > 0){
|
||||
y++;
|
||||
d = days - yearStart(y) +1;
|
||||
if(d == handleGetYearLength(y)){
|
||||
m=11;
|
||||
break;
|
||||
}else if(d < handleGetYearLength(y) ){
|
||||
int monthLen = handleGetMonthLength(y, m);
|
||||
m=0;
|
||||
while(d > monthLen){
|
||||
d -= monthLen;
|
||||
m++;
|
||||
monthLen = handleGetMonthLength(y, m);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
year = y;
|
||||
month = m;
|
||||
}
|
||||
} else { // invalid 'civil'
|
||||
UPRV_UNREACHABLE_EXIT; // should not get here, out of range
|
||||
double age = moonAge(internalGetTime(), status);
|
||||
if (U_FAILURE(status)) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
return;
|
||||
}
|
||||
if ( days - startDate >= 25 && age > 0) {
|
||||
// If we're near the end of the month, assume next month and search backwards
|
||||
month++;
|
||||
}
|
||||
|
||||
dayOfMonth = (days - monthStart(year, month)) + 1;
|
||||
// Find out the last time that the new moon was actually visible at this longitude
|
||||
// This returns midnight the night that the moon was visible at sunset.
|
||||
while ((startDate = trueMonthStart(month)) > days) {
|
||||
// If it was after the date in question, back up a month and try again
|
||||
month--;
|
||||
}
|
||||
|
||||
int32_t year = month >= 0 ? ((month / 12) + 1) : ((month + 1 ) / 12);
|
||||
month = ((month % 12) + 12 ) % 12;
|
||||
int32_t dayOfMonth = (days - monthStart(year, month)) + 1;
|
||||
|
||||
// Now figure out the day of the year.
|
||||
dayOfYear = (days - monthStart(year, 0)) + 1;
|
||||
|
||||
int32_t dayOfYear = (days - monthStart(year, 0)) + 1;
|
||||
|
||||
internalSet(UCAL_ERA, 0);
|
||||
internalSet(UCAL_YEAR, year);
|
||||
internalSet(UCAL_EXTENDED_YEAR, year);
|
||||
internalSet(UCAL_MONTH, month);
|
||||
internalSet(UCAL_DAY_OF_MONTH, dayOfMonth);
|
||||
internalSet(UCAL_DAY_OF_YEAR, dayOfYear);
|
||||
}
|
||||
internalSet(UCAL_DAY_OF_YEAR, dayOfYear);
|
||||
}
|
||||
|
||||
int32_t IslamicCalendar::getEpoc() const {
|
||||
return CIVIL_EPOC;
|
||||
}
|
||||
|
||||
static int32_t gregoYearFromIslamicStart(int32_t year) {
|
||||
// ad hoc conversion, improve under #10752
|
||||
|
@ -789,9 +651,315 @@ IslamicCalendar::initializeSystemDefaultCentury()
|
|||
// out.
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* IslamicCivilCalendar
|
||||
*****************************************************************************/
|
||||
IslamicCivilCalendar::IslamicCivilCalendar(const Locale& aLocale, UErrorCode& success)
|
||||
: IslamicCalendar(aLocale, success)
|
||||
{
|
||||
}
|
||||
|
||||
IslamicCivilCalendar::~IslamicCivilCalendar()
|
||||
{
|
||||
}
|
||||
|
||||
const char *IslamicCivilCalendar::getType() const {
|
||||
return "islamic-civil";
|
||||
}
|
||||
|
||||
IslamicCivilCalendar* IslamicCivilCalendar::clone() const {
|
||||
return new IslamicCivilCalendar(*this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the day # on which the given year starts. Days are counted
|
||||
* from the Hijri epoch, origin 0.
|
||||
*/
|
||||
int32_t IslamicCivilCalendar::yearStart(int32_t year) const{
|
||||
return static_cast<int32_t>(
|
||||
(year-1)*354 + ClockMath::floorDivide((3+11*static_cast<int64_t>(year)),
|
||||
static_cast<int64_t>(30)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the day # on which the given month starts. Days are counted
|
||||
* from the Hijri epoch, origin 0.
|
||||
*
|
||||
* @param year The hijri year
|
||||
* @param month The hijri month, 0-based (assumed to be in range 0..11)
|
||||
*/
|
||||
int32_t IslamicCivilCalendar::monthStart(int32_t year, int32_t month) const {
|
||||
// This does not handle months out of the range 0..11
|
||||
return static_cast<int32_t>(
|
||||
uprv_ceil(29.5*month) + (year-1)*354 +
|
||||
static_cast<int32_t>(ClockMath::floorDivide(
|
||||
3+11*static_cast<int64_t>(year),
|
||||
static_cast<int64_t>(30))));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the length (in days) of the given month.
|
||||
*
|
||||
* @param year The hijri year
|
||||
* @param year The hijri month, 0-based
|
||||
* @draft ICU 2.4
|
||||
*/
|
||||
int32_t IslamicCivilCalendar::handleGetMonthLength(int32_t extendedYear, int32_t month) const {
|
||||
int32_t length = 29 + (month+1) % 2;
|
||||
if (month == DHU_AL_HIJJAH && civilLeapYear(extendedYear)) {
|
||||
length++;
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of days in the given Islamic year
|
||||
* @draft ICU 2.4
|
||||
*/
|
||||
int32_t IslamicCivilCalendar::handleGetYearLength(int32_t extendedYear) const {
|
||||
return 354 + (civilLeapYear(extendedYear) ? 1 : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Override Calendar to compute several fields specific to the Islamic
|
||||
* calendar system. These are:
|
||||
*
|
||||
* <ul><li>ERA
|
||||
* <li>YEAR
|
||||
* <li>MONTH
|
||||
* <li>DAY_OF_MONTH
|
||||
* <li>DAY_OF_YEAR
|
||||
* <li>EXTENDED_YEAR</ul>
|
||||
*
|
||||
* The DAY_OF_WEEK and DOW_LOCAL fields are already set when this
|
||||
* method is called. The getGregorianXxx() methods return Gregorian
|
||||
* calendar equivalents for the given Julian day.
|
||||
* @draft ICU 2.4
|
||||
*/
|
||||
void IslamicCivilCalendar::handleComputeFields(int32_t julianDay, UErrorCode &status) {
|
||||
if (U_FAILURE(status)) return;
|
||||
int32_t days = julianDay - getEpoc();
|
||||
|
||||
// Use the civil calendar approximation, which is just arithmetic
|
||||
int32_t year = static_cast<int32_t>(
|
||||
ClockMath::floorDivide(30 * static_cast<int64_t>(days) + 10646,
|
||||
static_cast<int64_t>(10631)));
|
||||
int32_t month = static_cast<int32_t>(
|
||||
uprv_ceil((days - 29 - yearStart(year)) / 29.5 ));
|
||||
month = month<11?month:11;
|
||||
|
||||
int32_t dayOfMonth = (days - monthStart(year, month)) + 1;
|
||||
|
||||
// Now figure out the day of the year.
|
||||
int32_t dayOfYear = (days - monthStart(year, 0)) + 1;
|
||||
|
||||
internalSet(UCAL_ERA, 0);
|
||||
internalSet(UCAL_YEAR, year);
|
||||
internalSet(UCAL_EXTENDED_YEAR, year);
|
||||
internalSet(UCAL_MONTH, month);
|
||||
internalSet(UCAL_DAY_OF_MONTH, dayOfMonth);
|
||||
internalSet(UCAL_DAY_OF_YEAR, dayOfYear);
|
||||
}
|
||||
/*****************************************************************************
|
||||
* IslamicTBLACalendar
|
||||
*****************************************************************************/
|
||||
IslamicTBLACalendar::IslamicTBLACalendar(const Locale& aLocale, UErrorCode& success)
|
||||
: IslamicCivilCalendar(aLocale, success)
|
||||
{
|
||||
}
|
||||
|
||||
IslamicTBLACalendar::~IslamicTBLACalendar()
|
||||
{
|
||||
}
|
||||
|
||||
const char *IslamicTBLACalendar::getType() const {
|
||||
return "islamic-tbla";
|
||||
}
|
||||
|
||||
IslamicTBLACalendar* IslamicTBLACalendar::clone() const {
|
||||
return new IslamicTBLACalendar(*this);
|
||||
}
|
||||
|
||||
int32_t IslamicTBLACalendar::getEpoc() const {
|
||||
return ASTRONOMICAL_EPOC;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* IslamicUmalquraCalendar
|
||||
*****************************************************************************/
|
||||
IslamicUmalquraCalendar::IslamicUmalquraCalendar(const Locale& aLocale, UErrorCode& success)
|
||||
: IslamicCalendar(aLocale, success)
|
||||
{
|
||||
}
|
||||
|
||||
IslamicUmalquraCalendar::~IslamicUmalquraCalendar()
|
||||
{
|
||||
}
|
||||
|
||||
const char *IslamicUmalquraCalendar::getType() const {
|
||||
return "islamic-umalqura";
|
||||
}
|
||||
|
||||
IslamicUmalquraCalendar* IslamicUmalquraCalendar::clone() const {
|
||||
return new IslamicUmalquraCalendar(*this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the day # on which the given year starts. Days are counted
|
||||
* from the Hijri epoch, origin 0.
|
||||
*/
|
||||
int32_t IslamicUmalquraCalendar::yearStart(int32_t year) const {
|
||||
if (year < UMALQURA_YEAR_START || year > UMALQURA_YEAR_END) {
|
||||
return static_cast<int32_t>(
|
||||
(year-1)*354 + ClockMath::floorDivide((3+11*static_cast<int64_t>(year)),
|
||||
static_cast<int64_t>(30)));
|
||||
}
|
||||
year -= UMALQURA_YEAR_START;
|
||||
// rounded least-squares fit of the dates previously calculated from UMALQURA_MONTHLENGTH iteration
|
||||
int32_t yrStartLinearEstimate = static_cast<int32_t>(
|
||||
(354.36720 * (double)year) + 460322.05 + 0.5);
|
||||
// need a slight correction to some
|
||||
return yrStartLinearEstimate + umAlQuraYrStartEstimateFix[year];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the day # on which the given month starts. Days are counted
|
||||
* from the Hijri epoch, origin 0.
|
||||
*
|
||||
* @param year The hijri year
|
||||
* @param month The hijri month, 0-based (assumed to be in range 0..11)
|
||||
*/
|
||||
int32_t IslamicUmalquraCalendar::monthStart(int32_t year, int32_t month) const {
|
||||
int32_t ms = yearStart(year);
|
||||
for(int i=0; i< month; i++){
|
||||
ms+= handleGetMonthLength(year, i);
|
||||
}
|
||||
return ms;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the length (in days) of the given month.
|
||||
*
|
||||
* @param year The hijri year
|
||||
* @param year The hijri month, 0-based
|
||||
*/
|
||||
int32_t IslamicUmalquraCalendar::handleGetMonthLength(int32_t extendedYear, int32_t month) const {
|
||||
int32_t length = 0;
|
||||
if (extendedYear<UMALQURA_YEAR_START || extendedYear>UMALQURA_YEAR_END) {
|
||||
length = 29 + (month+1) % 2;
|
||||
if (month == DHU_AL_HIJJAH && civilLeapYear(extendedYear)) {
|
||||
length++;
|
||||
}
|
||||
return length;
|
||||
}
|
||||
return getUmalqura_MonthLength(extendedYear - UMALQURA_YEAR_START, month);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of days in the given Islamic year
|
||||
* @draft ICU 2.4
|
||||
*/
|
||||
int32_t IslamicUmalquraCalendar::handleGetYearLength(int32_t extendedYear) const {
|
||||
if (extendedYear<UMALQURA_YEAR_START || extendedYear>UMALQURA_YEAR_END) {
|
||||
return 354 + (civilLeapYear(extendedYear) ? 1 : 0);
|
||||
}
|
||||
int len = 0;
|
||||
for(int i=0; i<12; i++) {
|
||||
len += handleGetMonthLength(extendedYear, i);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override Calendar to compute several fields specific to the Islamic
|
||||
* calendar system. These are:
|
||||
*
|
||||
* <ul><li>ERA
|
||||
* <li>YEAR
|
||||
* <li>MONTH
|
||||
* <li>DAY_OF_MONTH
|
||||
* <li>DAY_OF_YEAR
|
||||
* <li>EXTENDED_YEAR</ul>
|
||||
*
|
||||
* The DAY_OF_WEEK and DOW_LOCAL fields are already set when this
|
||||
* method is called. The getGregorianXxx() methods return Gregorian
|
||||
* calendar equivalents for the given Julian day.
|
||||
* @draft ICU 2.4
|
||||
*/
|
||||
void IslamicUmalquraCalendar::handleComputeFields(int32_t julianDay, UErrorCode &status) {
|
||||
if (U_FAILURE(status)) return;
|
||||
int32_t year, month, dayOfMonth, dayOfYear;
|
||||
int32_t days = julianDay - getEpoc();
|
||||
|
||||
int32_t umalquraStartdays = yearStart(UMALQURA_YEAR_START) ;
|
||||
if (days < umalquraStartdays) {
|
||||
//Use Civil calculation
|
||||
year = (int32_t)ClockMath::floorDivide(
|
||||
(30 * (int64_t)days + 10646) , (int64_t)10631.0 );
|
||||
month = (int32_t)uprv_ceil((days - 29 - yearStart(year)) / 29.5 );
|
||||
month = month < 11 ? month : 11;
|
||||
} else {
|
||||
int y =UMALQURA_YEAR_START-1, m =0;
|
||||
long d = 1;
|
||||
while (d > 0) {
|
||||
y++;
|
||||
d = days - yearStart(y) +1;
|
||||
if (d == handleGetYearLength(y)) {
|
||||
m=11;
|
||||
break;
|
||||
}
|
||||
if (d < handleGetYearLength(y)){
|
||||
int monthLen = handleGetMonthLength(y, m);
|
||||
m=0;
|
||||
while(d > monthLen){
|
||||
d -= monthLen;
|
||||
m++;
|
||||
monthLen = handleGetMonthLength(y, m);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
year = y;
|
||||
month = m;
|
||||
}
|
||||
|
||||
dayOfMonth = (days - monthStart(year, month)) + 1;
|
||||
|
||||
// Now figure out the day of the year.
|
||||
dayOfYear = (days - monthStart(year, 0)) + 1;
|
||||
|
||||
internalSet(UCAL_ERA, 0);
|
||||
internalSet(UCAL_YEAR, year);
|
||||
internalSet(UCAL_EXTENDED_YEAR, year);
|
||||
internalSet(UCAL_MONTH, month);
|
||||
internalSet(UCAL_DAY_OF_MONTH, dayOfMonth);
|
||||
internalSet(UCAL_DAY_OF_YEAR, dayOfYear);
|
||||
}
|
||||
/*****************************************************************************
|
||||
* IslamicRGSACalendar
|
||||
*****************************************************************************/
|
||||
IslamicRGSACalendar::IslamicRGSACalendar(const Locale& aLocale, UErrorCode& success)
|
||||
: IslamicCalendar(aLocale, success)
|
||||
{
|
||||
}
|
||||
|
||||
IslamicRGSACalendar::~IslamicRGSACalendar()
|
||||
{
|
||||
}
|
||||
|
||||
const char *IslamicRGSACalendar::getType() const {
|
||||
return "islamic-rgsa";
|
||||
}
|
||||
|
||||
IslamicRGSACalendar* IslamicRGSACalendar::clone() const {
|
||||
return new IslamicRGSACalendar(*this);
|
||||
}
|
||||
|
||||
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IslamicCalendar)
|
||||
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IslamicCivilCalendar)
|
||||
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IslamicUmalquraCalendar)
|
||||
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IslamicTBLACalendar)
|
||||
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IslamicRGSACalendar)
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
||||
|
|
|
@ -53,7 +53,8 @@ U_NAMESPACE_BEGIN
|
|||
* every 30 years. This calendar is easily calculated and thus predictable in
|
||||
* advance, so it is used as the civil calendar in a number of Arab countries.
|
||||
* This is the default behavior of a newly-created <code>IslamicCalendar</code>
|
||||
* object.
|
||||
* object. This calendar variant is implemented in the IslamicCivilCalendar
|
||||
* class.
|
||||
* <p>
|
||||
* The Islamic <em>religious</em> calendar, however, is based on the <em>observation</em>
|
||||
* of the crescent moon. It is thus affected by the position at which the
|
||||
|
@ -71,10 +72,6 @@ U_NAMESPACE_BEGIN
|
|||
* calculations. At present, the approximations used in this class are fairly
|
||||
* simplistic; they will be improved in later versions of the code.
|
||||
* <p>
|
||||
* The {@link #setCivil setCivil} method determines
|
||||
* which approach is used to determine the start of a month. By default, the
|
||||
* fixed-cycle civil calendar is used. However, if <code>setCivil(false)</code>
|
||||
* is called, an approximation of the true lunar calendar will be used.
|
||||
*
|
||||
* @see GregorianCalendar
|
||||
*
|
||||
|
@ -88,18 +85,6 @@ class U_I18N_API IslamicCalendar : public Calendar {
|
|||
//-------------------------------------------------------------------------
|
||||
// Constants...
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Calendar type - civil or religious or um alqura
|
||||
* @internal
|
||||
*/
|
||||
enum ECalculationType {
|
||||
ASTRONOMICAL,
|
||||
CIVIL,
|
||||
UMALQURA,
|
||||
TBLA
|
||||
};
|
||||
|
||||
/**
|
||||
* Constants for the months
|
||||
* @internal
|
||||
|
@ -192,16 +177,15 @@ class U_I18N_API IslamicCalendar : public Calendar {
|
|||
* @param aLocale The given locale.
|
||||
* @param success Indicates the status of IslamicCalendar object construction.
|
||||
* Returns U_ZERO_ERROR if constructed successfully.
|
||||
* @param type The Islamic calendar calculation type. The default value is CIVIL.
|
||||
* @internal
|
||||
*/
|
||||
IslamicCalendar(const Locale& aLocale, UErrorCode &success, ECalculationType type = CIVIL);
|
||||
IslamicCalendar(const Locale& aLocale, UErrorCode &success);
|
||||
|
||||
/**
|
||||
* Copy Constructor
|
||||
* @internal
|
||||
*/
|
||||
IslamicCalendar(const IslamicCalendar& other);
|
||||
IslamicCalendar(const IslamicCalendar& other) = default;
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
|
@ -209,40 +193,20 @@ class U_I18N_API IslamicCalendar : public Calendar {
|
|||
*/
|
||||
virtual ~IslamicCalendar();
|
||||
|
||||
/**
|
||||
* Sets Islamic calendar calculation type used by this instance.
|
||||
*
|
||||
* @param type The calendar calculation type, <code>CIVIL</code> to use the civil
|
||||
* calendar, <code>ASTRONOMICAL</code> to use the astronomical calendar.
|
||||
* @internal
|
||||
*/
|
||||
void setCalculationType(ECalculationType type, UErrorCode &status);
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if this object is using the fixed-cycle civil
|
||||
* calendar, or <code>false</code> if using the religious, astronomical
|
||||
* calendar.
|
||||
* @internal
|
||||
*/
|
||||
UBool isCivil();
|
||||
|
||||
|
||||
// TODO: copy c'tor, etc
|
||||
|
||||
// clone
|
||||
virtual IslamicCalendar* clone() const override;
|
||||
|
||||
private:
|
||||
protected:
|
||||
/**
|
||||
* Determine whether a year is a leap year in the Islamic civil calendar
|
||||
*/
|
||||
static UBool civilLeapYear(int32_t year);
|
||||
|
||||
|
||||
/**
|
||||
* Return the day # on which the given year starts. Days are counted
|
||||
* from the Hijri epoch, origin 0.
|
||||
*/
|
||||
int32_t yearStart(int32_t year) const;
|
||||
virtual int32_t yearStart(int32_t year) const;
|
||||
|
||||
/**
|
||||
* Return the day # on which the given month starts. Days are counted
|
||||
|
@ -251,7 +215,7 @@ class U_I18N_API IslamicCalendar : public Calendar {
|
|||
* @param year The hijri year
|
||||
* @param year The hijri month, 0-based
|
||||
*/
|
||||
int32_t monthStart(int32_t year, int32_t month) const;
|
||||
virtual int32_t monthStart(int32_t year, int32_t month) const;
|
||||
|
||||
/**
|
||||
* Find the day number on which a particular month of the true/lunar
|
||||
|
@ -263,6 +227,7 @@ class U_I18N_API IslamicCalendar : public Calendar {
|
|||
*/
|
||||
int32_t trueMonthStart(int32_t month) const;
|
||||
|
||||
private:
|
||||
/**
|
||||
* Return the "age" of the moon at the given time; this is the difference
|
||||
* in ecliptic latitude between the moon and the sun. This method simply
|
||||
|
@ -274,17 +239,6 @@ class U_I18N_API IslamicCalendar : public Calendar {
|
|||
*/
|
||||
static double moonAge(UDate time, UErrorCode &status);
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Internal data....
|
||||
//
|
||||
|
||||
/**
|
||||
* <code>CIVIL</code> if this object uses the fixed-cycle Islamic civil calendar,
|
||||
* and <code>ASTRONOMICAL</code> if it approximates the true religious calendar using
|
||||
* astronomical calculations for the time of the new moon.
|
||||
*/
|
||||
ECalculationType cType;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Calendar framework
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -346,6 +300,12 @@ class U_I18N_API IslamicCalendar : public Calendar {
|
|||
*/
|
||||
virtual void handleComputeFields(int32_t julianDay, UErrorCode &status) override;
|
||||
|
||||
/**
|
||||
* Return the epoc.
|
||||
* @internal
|
||||
*/
|
||||
virtual int32_t getEpoc() const;
|
||||
|
||||
// UObject stuff
|
||||
public:
|
||||
/**
|
||||
|
@ -369,7 +329,7 @@ class U_I18N_API IslamicCalendar : public Calendar {
|
|||
/*U_I18N_API*/ static UClassID U_EXPORT2 getStaticClassID(void);
|
||||
|
||||
/**
|
||||
* return the calendar type, "buddhist".
|
||||
* return the calendar type, "islamic".
|
||||
*
|
||||
* @return calendar type
|
||||
* @internal
|
||||
|
@ -423,10 +383,372 @@ class U_I18N_API IslamicCalendar : public Calendar {
|
|||
static void U_CALLCONV initializeSystemDefaultCentury(void);
|
||||
};
|
||||
|
||||
/*
|
||||
* IslamicCivilCalendar is one of the two main variants of the Islamic calendar.
|
||||
* The <em>civil</em> calendar, which uses a fixed cycle of alternating 29-
|
||||
* and 30-day months, with a leap day added to the last month of 11 out of
|
||||
* every 30 years. This calendar is easily calculated and thus predictable in
|
||||
* advance, so it is used as the civil calendar in a number of Arab countries.
|
||||
* This calendar is referring as "Islamic calendar, tabular (intercalary years
|
||||
* [2,5,7,10,13,16,18,21,24,26,29]- civil epoch" in CLDR.
|
||||
*/
|
||||
class U_I18N_API IslamicCivilCalendar : public IslamicCalendar {
|
||||
public:
|
||||
/**
|
||||
* Constructs an IslamicCivilCalendar based on the current time in the default time zone
|
||||
* with the given locale.
|
||||
*
|
||||
* @param aLocale The given locale.
|
||||
* @param success Indicates the status of IslamicCivilCalendar object construction.
|
||||
* Returns U_ZERO_ERROR if constructed successfully.
|
||||
* @internal
|
||||
*/
|
||||
IslamicCivilCalendar(const Locale& aLocale, UErrorCode &success);
|
||||
|
||||
/**
|
||||
* Copy Constructor
|
||||
* @internal
|
||||
*/
|
||||
IslamicCivilCalendar(const IslamicCivilCalendar& other) = default;
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
* @internal
|
||||
*/
|
||||
virtual ~IslamicCivilCalendar();
|
||||
|
||||
// clone
|
||||
virtual IslamicCivilCalendar* clone() const override;
|
||||
|
||||
/**
|
||||
* @return The class ID for this object. All objects of a given class have the
|
||||
* same class ID. Objects of other classes have different class IDs.
|
||||
* @internal
|
||||
*/
|
||||
virtual UClassID getDynamicClassID(void) const override;
|
||||
|
||||
/**
|
||||
* Return the class ID for this class. This is useful only for comparing to a return
|
||||
* value from getDynamicClassID(). For example:
|
||||
*
|
||||
* Base* polymorphic_pointer = createPolymorphicObject();
|
||||
* if (polymorphic_pointer->getDynamicClassID() ==
|
||||
* Derived::getStaticClassID()) ...
|
||||
*
|
||||
* @return The class ID for all objects of this class.
|
||||
* @internal
|
||||
*/
|
||||
static UClassID U_EXPORT2 getStaticClassID(void);
|
||||
|
||||
/**
|
||||
* return the calendar type, "islamic-civil".
|
||||
*
|
||||
* @return calendar type
|
||||
* @internal
|
||||
*/
|
||||
virtual const char * getType() const override;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Return the day # on which the given year starts. Days are counted
|
||||
* from the Hijri epoch, origin 0.
|
||||
* @internal
|
||||
*/
|
||||
virtual int32_t yearStart(int32_t year) const override;
|
||||
|
||||
/**
|
||||
* Return the day # on which the given month starts. Days are counted
|
||||
* from the Hijri epoch, origin 0.
|
||||
*
|
||||
* @param year The hijri year
|
||||
* @param year The hijri month, 0-based
|
||||
* @internal
|
||||
*/
|
||||
virtual int32_t monthStart(int32_t year, int32_t month) const override;
|
||||
|
||||
/**
|
||||
* Return the length (in days) of the given month.
|
||||
*
|
||||
* @param year The hijri year
|
||||
* @param year The hijri month, 0-based
|
||||
* @internal
|
||||
*/
|
||||
virtual int32_t handleGetMonthLength(int32_t extendedYear, int32_t month) const override;
|
||||
|
||||
/**
|
||||
* Return the number of days in the given Islamic year
|
||||
* @internal
|
||||
*/
|
||||
virtual int32_t handleGetYearLength(int32_t extendedYear) const override;
|
||||
|
||||
/**
|
||||
* Override Calendar to compute several fields specific to the Islamic
|
||||
* calendar system. These are:
|
||||
*
|
||||
* <ul><li>ERA
|
||||
* <li>YEAR
|
||||
* <li>MONTH
|
||||
* <li>DAY_OF_MONTH
|
||||
* <li>DAY_OF_YEAR
|
||||
* <li>EXTENDED_YEAR</ul>
|
||||
*
|
||||
* The DAY_OF_WEEK and DOW_LOCAL fields are already set when this
|
||||
* method is called. The getGregorianXxx() methods return Gregorian
|
||||
* calendar equivalents for the given Julian day.
|
||||
* @internal
|
||||
*/
|
||||
virtual void handleComputeFields(int32_t julianDay, UErrorCode &status) override;
|
||||
};
|
||||
|
||||
/*
|
||||
* IslamicTBLACalendar calendar.
|
||||
* This is a subclass of IslamicCivilCalendar. The only differences in the
|
||||
* calendar math is it uses different epoch.
|
||||
* This calendar is referring as "Islamic calendar, tabular (intercalary years
|
||||
* [2,5,7,10,13,16,18,21,24,26,29] - astronomical epoch" in CLDR.
|
||||
*/
|
||||
class U_I18N_API IslamicTBLACalendar : public IslamicCivilCalendar {
|
||||
public:
|
||||
/**
|
||||
* Constructs an IslamicTBLACalendar based on the current time in the default time zone
|
||||
* with the given locale.
|
||||
*
|
||||
* @param aLocale The given locale.
|
||||
* @param success Indicates the status of IslamicTBLACalendar object construction.
|
||||
* Returns U_ZERO_ERROR if constructed successfully.
|
||||
* @internal
|
||||
*/
|
||||
IslamicTBLACalendar(const Locale& aLocale, UErrorCode &success);
|
||||
|
||||
/**
|
||||
* Copy Constructor
|
||||
* @internal
|
||||
*/
|
||||
IslamicTBLACalendar(const IslamicTBLACalendar& other) = default;
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
* @internal
|
||||
*/
|
||||
virtual ~IslamicTBLACalendar();
|
||||
|
||||
/**
|
||||
* @return The class ID for this object. All objects of a given class have the
|
||||
* same class ID. Objects of other classes have different class IDs.
|
||||
* @internal
|
||||
*/
|
||||
virtual UClassID getDynamicClassID(void) const override;
|
||||
|
||||
/**
|
||||
* Return the class ID for this class. This is useful only for comparing to a return
|
||||
* value from getDynamicClassID(). For example:
|
||||
*
|
||||
* Base* polymorphic_pointer = createPolymorphicObject();
|
||||
* if (polymorphic_pointer->getDynamicClassID() ==
|
||||
* Derived::getStaticClassID()) ...
|
||||
*
|
||||
* @return The class ID for all objects of this class.
|
||||
* @internal
|
||||
*/
|
||||
static UClassID U_EXPORT2 getStaticClassID(void);
|
||||
|
||||
/**
|
||||
* return the calendar type, "islamic-tbla".
|
||||
*
|
||||
* @return calendar type
|
||||
* @internal
|
||||
*/
|
||||
virtual const char * getType() const override;
|
||||
|
||||
// clone
|
||||
virtual IslamicTBLACalendar* clone() const override;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Return the epoc.
|
||||
* @internal
|
||||
*/
|
||||
virtual int32_t getEpoc() const override;
|
||||
};
|
||||
|
||||
/*
|
||||
* IslamicUmalquraCalendar
|
||||
* This calendar is referred as "Islamic calendar, Umm al-Qura" in CLDR.
|
||||
*/
|
||||
class U_I18N_API IslamicUmalquraCalendar : public IslamicCalendar {
|
||||
public:
|
||||
/**
|
||||
* Constructs an IslamicUmalquraCalendar based on the current time in the default time zone
|
||||
* with the given locale.
|
||||
*
|
||||
* @param aLocale The given locale.
|
||||
* @param success Indicates the status of IslamicUmalquraCalendar object construction.
|
||||
* Returns U_ZERO_ERROR if constructed successfully.
|
||||
* @internal
|
||||
*/
|
||||
IslamicUmalquraCalendar(const Locale& aLocale, UErrorCode &success);
|
||||
|
||||
/**
|
||||
* Copy Constructor
|
||||
* @internal
|
||||
*/
|
||||
IslamicUmalquraCalendar(const IslamicUmalquraCalendar& other) = default;
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
* @internal
|
||||
*/
|
||||
virtual ~IslamicUmalquraCalendar();
|
||||
|
||||
/**
|
||||
* @return The class ID for this object. All objects of a given class have the
|
||||
* same class ID. Objects of other classes have different class IDs.
|
||||
* @internal
|
||||
*/
|
||||
virtual UClassID getDynamicClassID(void) const override;
|
||||
|
||||
/**
|
||||
* Return the class ID for this class. This is useful only for comparing to a return
|
||||
* value from getDynamicClassID(). For example:
|
||||
*
|
||||
* Base* polymorphic_pointer = createPolymorphicObject();
|
||||
* if (polymorphic_pointer->getDynamicClassID() ==
|
||||
* Derived::getStaticClassID()) ...
|
||||
*
|
||||
* @return The class ID for all objects of this class.
|
||||
* @internal
|
||||
*/
|
||||
static UClassID U_EXPORT2 getStaticClassID(void);
|
||||
|
||||
/**
|
||||
* return the calendar type, "islamic-umalqura".
|
||||
*
|
||||
* @return calendar type
|
||||
* @internal
|
||||
*/
|
||||
virtual const char * getType() const override;
|
||||
|
||||
// clone
|
||||
virtual IslamicUmalquraCalendar* clone() const override;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Return the day # on which the given year starts. Days are counted
|
||||
* from the Hijri epoch, origin 0.
|
||||
* @internal
|
||||
*/
|
||||
virtual int32_t yearStart(int32_t year) const override;
|
||||
|
||||
/**
|
||||
* Return the day # on which the given month starts. Days are counted
|
||||
* from the Hijri epoch, origin 0.
|
||||
*
|
||||
* @param year The hijri year
|
||||
* @param year The hijri month, 0-based
|
||||
* @internal
|
||||
*/
|
||||
virtual int32_t monthStart(int32_t year, int32_t month) const override;
|
||||
|
||||
/**
|
||||
* Return the length (in days) of the given month.
|
||||
*
|
||||
* @param year The hijri year
|
||||
* @param year The hijri month, 0-based
|
||||
* @internal
|
||||
*/
|
||||
virtual int32_t handleGetMonthLength(int32_t extendedYear, int32_t month) const override;
|
||||
|
||||
/**
|
||||
* Return the number of days in the given Islamic year
|
||||
* @internal
|
||||
*/
|
||||
virtual int32_t handleGetYearLength(int32_t extendedYear) const override;
|
||||
|
||||
/**
|
||||
* Override Calendar to compute several fields specific to the Islamic
|
||||
* calendar system. These are:
|
||||
*
|
||||
* <ul><li>ERA
|
||||
* <li>YEAR
|
||||
* <li>MONTH
|
||||
* <li>DAY_OF_MONTH
|
||||
* <li>DAY_OF_YEAR
|
||||
* <li>EXTENDED_YEAR</ul>
|
||||
*
|
||||
* The DAY_OF_WEEK and DOW_LOCAL fields are already set when this
|
||||
* method is called. The getGregorianXxx() methods return Gregorian
|
||||
* calendar equivalents for the given Julian day.
|
||||
* @internal
|
||||
*/
|
||||
virtual void handleComputeFields(int32_t julianDay, UErrorCode &status) override;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* IslamicRGSACalendar
|
||||
* Islamic calendar, Saudi Arabia sighting. Since the calendar depends on the
|
||||
* sighting, it is impossible to implement by algorithm ahead of time. It is
|
||||
* currently identical to IslamicCalendar except the getType will return
|
||||
* "islamic-rgsa".
|
||||
*/
|
||||
class U_I18N_API IslamicRGSACalendar : public IslamicCalendar {
|
||||
public:
|
||||
/**
|
||||
* Constructs an IslamicRGSACalendar based on the current time in the default time zone
|
||||
* with the given locale.
|
||||
*
|
||||
* @param aLocale The given locale.
|
||||
* @param success Indicates the status of IslamicRGSACalendar object construction.
|
||||
* Returns U_ZERO_ERROR if constructed successfully.
|
||||
* @internal
|
||||
*/
|
||||
IslamicRGSACalendar(const Locale& aLocale, UErrorCode &success);
|
||||
|
||||
/**
|
||||
* Copy Constructor
|
||||
* @internal
|
||||
*/
|
||||
IslamicRGSACalendar(const IslamicRGSACalendar& other) = default;
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
* @internal
|
||||
*/
|
||||
virtual ~IslamicRGSACalendar();
|
||||
|
||||
/**
|
||||
* @return The class ID for this object. All objects of a given class have the
|
||||
* same class ID. Objects of other classes have different class IDs.
|
||||
* @internal
|
||||
*/
|
||||
virtual UClassID getDynamicClassID(void) const override;
|
||||
|
||||
/**
|
||||
* Return the class ID for this class. This is useful only for comparing to a return
|
||||
* value from getDynamicClassID(). For example:
|
||||
*
|
||||
* Base* polymorphic_pointer = createPolymorphicObject();
|
||||
* if (polymorphic_pointer->getDynamicClassID() ==
|
||||
* Derived::getStaticClassID()) ...
|
||||
*
|
||||
* @return The class ID for all objects of this class.
|
||||
* @internal
|
||||
*/
|
||||
static UClassID U_EXPORT2 getStaticClassID(void);
|
||||
|
||||
/**
|
||||
* return the calendar type, "islamic-rgsa".
|
||||
*
|
||||
* @return calendar type
|
||||
* @internal
|
||||
*/
|
||||
virtual const char * getType() const override;
|
||||
|
||||
// clone
|
||||
virtual IslamicRGSACalendar* clone() const override;
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
|
37
icu4c/source/i18n/iso8601cal.cpp
Normal file
37
icu4c/source/i18n/iso8601cal.cpp
Normal file
|
@ -0,0 +1,37 @@
|
|||
// © 2022 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
#include "unicode/utypes.h"
|
||||
|
||||
#if !UCONFIG_NO_FORMATTING
|
||||
|
||||
#include "iso8601cal.h"
|
||||
#include "unicode/gregocal.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ISO8601Calendar)
|
||||
|
||||
ISO8601Calendar::ISO8601Calendar(const Locale& aLocale, UErrorCode& success)
|
||||
: GregorianCalendar(aLocale, success)
|
||||
{
|
||||
setFirstDayOfWeek(UCAL_MONDAY);
|
||||
setMinimalDaysInFirstWeek(4);
|
||||
}
|
||||
|
||||
ISO8601Calendar::~ISO8601Calendar()
|
||||
{
|
||||
}
|
||||
|
||||
ISO8601Calendar* ISO8601Calendar::clone() const
|
||||
{
|
||||
return new ISO8601Calendar(*this);
|
||||
}
|
||||
|
||||
const char *ISO8601Calendar::getType() const
|
||||
{
|
||||
return "iso8601";
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
||||
#endif
|
102
icu4c/source/i18n/iso8601cal.h
Normal file
102
icu4c/source/i18n/iso8601cal.h
Normal file
|
@ -0,0 +1,102 @@
|
|||
// © 2022 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
#ifndef ISO8601CAL_H
|
||||
#define ISO8601CAL_H
|
||||
|
||||
#include "unicode/utypes.h"
|
||||
|
||||
#if !UCONFIG_NO_FORMATTING
|
||||
|
||||
#include "unicode/calendar.h"
|
||||
#include "unicode/gregocal.h"
|
||||
#include "unicode/timezone.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
/**
|
||||
* Concrete class which provides the ISO8601 calendar.
|
||||
* <P>
|
||||
* <code>ISO8601Calendar</code> is a subclass of <code>GregorianCalendar</code>
|
||||
* that the first day of a week is Monday and the minimal days in the first
|
||||
* week of a year or month is four days.
|
||||
* <p>
|
||||
* The ISO8601 calendar is identical to the Gregorian calendar in all respects
|
||||
* except for the first day of week and the minimal days in the first week
|
||||
* of a year.
|
||||
* @internal
|
||||
*/
|
||||
class ISO8601Calendar : public GregorianCalendar {
|
||||
public:
|
||||
//-------------------------------------------------------------------------
|
||||
// Constructors...
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Constructs a DangiCalendar based on the current time in the default time zone
|
||||
* with the given locale.
|
||||
*
|
||||
* @param aLocale The given locale.
|
||||
* @param success Indicates the status of ISO8601Calendar object construction.
|
||||
* Returns U_ZERO_ERROR if constructed successfully.
|
||||
* @internal
|
||||
*/
|
||||
ISO8601Calendar(const Locale& aLocale, UErrorCode &success);
|
||||
|
||||
/**
|
||||
* Copy Constructor
|
||||
* @internal
|
||||
*/
|
||||
ISO8601Calendar(const ISO8601Calendar& other) = default;
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
* @internal
|
||||
*/
|
||||
virtual ~ISO8601Calendar();
|
||||
|
||||
/**
|
||||
* Clone.
|
||||
* @internal
|
||||
*/
|
||||
virtual ISO8601Calendar* clone() const override;
|
||||
|
||||
// UObject stuff
|
||||
public:
|
||||
/**
|
||||
* @return The class ID for this object. All objects of a given class have the
|
||||
* same class ID. Objects of other classes have different class IDs.
|
||||
* @internal
|
||||
*/
|
||||
virtual UClassID getDynamicClassID(void) const override;
|
||||
|
||||
/**
|
||||
* Return the class ID for this class. This is useful only for comparing to a return
|
||||
* value from getDynamicClassID(). For example:
|
||||
*
|
||||
* Base* polymorphic_pointer = createPolymorphicObject();
|
||||
* if (polymorphic_pointer->getDynamicClassID() ==
|
||||
* Derived::getStaticClassID()) ...
|
||||
*
|
||||
* @return The class ID for all objects of this class.
|
||||
* @internal
|
||||
*/
|
||||
U_I18N_API static UClassID U_EXPORT2 getStaticClassID(void);
|
||||
|
||||
/**
|
||||
* return the calendar type, "iso8601".
|
||||
*
|
||||
* @return calendar type
|
||||
* @internal
|
||||
*/
|
||||
virtual const char * getType() const override;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
ISO8601Calendar(); // default constructor not implemented
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
#endif
|
|
@ -86,6 +86,7 @@ hebrwcal.cpp
|
|||
indiancal.cpp
|
||||
inputext.cpp
|
||||
islamcal.cpp
|
||||
iso8601cal.cpp
|
||||
japancal.cpp
|
||||
listformatter.cpp
|
||||
measfmt.cpp
|
||||
|
|
|
@ -1078,7 +1078,7 @@ group: formatting
|
|||
measfmt.o quantityformatter.o
|
||||
# dateformat
|
||||
astro.o buddhcal.o calendar.o cecal.o chnsecal.o coptccal.o dangical.o ethpccal.o
|
||||
gregocal.o gregoimp.o hebrwcal.o indiancal.o islamcal.o japancal.o persncal.o taiwncal.o
|
||||
gregocal.o gregoimp.o hebrwcal.o indiancal.o islamcal.o iso8601cal.o japancal.o persncal.o taiwncal.o
|
||||
erarules.o # mostly for Japanese eras
|
||||
ucal.o
|
||||
basictz.o olsontz.o rbtz.o simpletz.o timezone.o tzrule.o tztrans.o
|
||||
|
|
|
@ -353,6 +353,34 @@ void CalendarTest::runIndexedTest( int32_t index, UBool exec, const char* &name,
|
|||
TestTimeZoneInLocale();
|
||||
}
|
||||
break;
|
||||
#define CASE(num, NAME) \
|
||||
case num: \
|
||||
name = #NAME; \
|
||||
if(exec) { \
|
||||
logln(#NAME "---"); logln(""); \
|
||||
NAME(); \
|
||||
} \
|
||||
break;
|
||||
|
||||
CASE(38, TestBasicConversionISO8601);
|
||||
CASE(39, TestBasicConversionJapanese);
|
||||
CASE(40, TestBasicConversionBuddhist);
|
||||
CASE(41, TestBasicConversionTaiwan);
|
||||
CASE(42, TestBasicConversionPersian);
|
||||
CASE(43, TestBasicConversionIslamic);
|
||||
CASE(44, TestBasicConversionIslamicTBLA);
|
||||
CASE(45, TestBasicConversionIslamicCivil);
|
||||
CASE(46, TestBasicConversionIslamicRGSA);
|
||||
CASE(47, TestBasicConversionIslamicUmalqura);
|
||||
CASE(48, TestBasicConversionHebrew);
|
||||
CASE(49, TestBasicConversionChinese);
|
||||
CASE(50, TestBasicConversionDangi);
|
||||
CASE(51, TestBasicConversionIndian);
|
||||
CASE(52, TestBasicConversionCoptic);
|
||||
CASE(53, TestBasicConversionEthiopic);
|
||||
CASE(54, TestBasicConversionEthiopicAmeteAlem);
|
||||
|
||||
#undef CASE
|
||||
default: name = ""; break;
|
||||
}
|
||||
}
|
||||
|
@ -2390,8 +2418,8 @@ void CalendarTest::TestISO8601() {
|
|||
errln("Error: Failed to create a calendar for locale: %s", TEST_LOCALES[i]);
|
||||
continue;
|
||||
}
|
||||
if (uprv_strcmp(cal->getType(), "gregorian") != 0) {
|
||||
errln("Error: Gregorian calendar is not used for locale: %s", TEST_LOCALES[i]);
|
||||
if (uprv_strcmp(cal->getType(), "iso8601") != 0) {
|
||||
errln("Error: iso8601 calendar is not used for locale: %s", TEST_LOCALES[i]);
|
||||
continue;
|
||||
}
|
||||
for (int j = 0; TEST_DATA[j][0] != 0; j++) {
|
||||
|
@ -2833,8 +2861,8 @@ void CalendarTest::TestTimeZoneInLocale(void) {
|
|||
{ "my-u-ca-islamic-umalqura-tz-kzala", "Asia/Almaty", "islamic-umalqura" },
|
||||
{ "lo-u-ca-islamic-tbla-tz-bmbda", "Atlantic/Bermuda", "islamic-tbla" },
|
||||
{ "km-u-ca-islamic-civil-tz-aqplm", "Antarctica/Palmer", "islamic-civil" },
|
||||
{ "kk-u-ca-islamic-rgsa-tz-usanc", "America/Anchorage", "islamic" },
|
||||
{ "ar-u-ca-iso8601-tz-bjptn", "Africa/Porto-Novo", "gregorian" },
|
||||
{ "kk-u-ca-islamic-rgsa-tz-usanc", "America/Anchorage", "islamic-rgsa" },
|
||||
{ "ar-u-ca-iso8601-tz-bjptn", "Africa/Porto-Novo", "iso8601" },
|
||||
{ "he-u-ca-japanese-tz-tzdar", "Africa/Dar_es_Salaam", "japanese" },
|
||||
{ "bs-u-ca-persian-tz-etadd", "Africa/Addis_Ababa", "persian" },
|
||||
{ "it-u-ca-roc-tz-aruaq", "America/Argentina/San_Juan", "roc" },
|
||||
|
@ -2859,6 +2887,286 @@ void CalendarTest::TestTimeZoneInLocale(void) {
|
|||
}
|
||||
}
|
||||
|
||||
void CalendarTest::AsssertCalendarFieldValue(
|
||||
Calendar* cal, double time, const char* type,
|
||||
int32_t era, int32_t year, int32_t month, int32_t week_of_year,
|
||||
int32_t week_of_month, int32_t date, int32_t day_of_year, int32_t day_of_week,
|
||||
int32_t day_of_week_in_month, int32_t am_pm, int32_t hour, int32_t hour_of_day,
|
||||
int32_t minute, int32_t second, int32_t millisecond, int32_t zone_offset,
|
||||
int32_t dst_offset, int32_t year_woy, int32_t dow_local, int32_t extended_year,
|
||||
int32_t julian_day, int32_t milliseconds_in_day, int32_t is_leap_month) {
|
||||
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
cal->setTime(time, status);
|
||||
assertEquals("getType", type, cal->getType());
|
||||
|
||||
assertEquals("UCAL_ERA", era, cal->get(UCAL_ERA, status));
|
||||
assertEquals("UCAL_YEAR", year, cal->get(UCAL_YEAR, status));
|
||||
assertEquals("UCAL_MONTH", month, cal->get(UCAL_MONTH, status));
|
||||
assertEquals("UCAL_WEEK_OF_YEAR", week_of_year, cal->get(UCAL_WEEK_OF_YEAR, status));
|
||||
assertEquals("UCAL_WEEK_OF_MONTH", week_of_month, cal->get(UCAL_WEEK_OF_MONTH, status));
|
||||
assertEquals("UCAL_DATE", date, cal->get(UCAL_DATE, status));
|
||||
assertEquals("UCAL_DAY_OF_YEAR", day_of_year, cal->get(UCAL_DAY_OF_YEAR, status));
|
||||
assertEquals("UCAL_DAY_OF_WEEK", day_of_week, cal->get(UCAL_DAY_OF_WEEK, status));
|
||||
assertEquals("UCAL_DAY_OF_WEEK_IN_MONTH", day_of_week_in_month, cal->get(UCAL_DAY_OF_WEEK_IN_MONTH, status));
|
||||
assertEquals("UCAL_AM_PM", am_pm, cal->get(UCAL_AM_PM, status));
|
||||
assertEquals("UCAL_HOUR", hour, cal->get(UCAL_HOUR, status));
|
||||
assertEquals("UCAL_HOUR_OF_DAY", hour_of_day, cal->get(UCAL_HOUR_OF_DAY, status));
|
||||
assertEquals("UCAL_MINUTE", minute, cal->get(UCAL_MINUTE, status));
|
||||
assertEquals("UCAL_SECOND", second, cal->get(UCAL_SECOND, status));
|
||||
assertEquals("UCAL_MILLISECOND", millisecond, cal->get(UCAL_MILLISECOND, status));
|
||||
assertEquals("UCAL_ZONE_OFFSET", zone_offset, cal->get(UCAL_ZONE_OFFSET, status));
|
||||
assertEquals("UCAL_DST_OFFSET", dst_offset, cal->get(UCAL_DST_OFFSET, status));
|
||||
assertEquals("UCAL_YEAR_WOY", year_woy, cal->get(UCAL_YEAR_WOY, status));
|
||||
assertEquals("UCAL_DOW_LOCAL", dow_local, cal->get(UCAL_DOW_LOCAL, status));
|
||||
assertEquals("UCAL_EXTENDED_YEAR", extended_year, cal->get(UCAL_EXTENDED_YEAR, status));
|
||||
assertEquals("UCAL_JULIAN_DAY", julian_day, cal->get(UCAL_JULIAN_DAY, status));
|
||||
assertEquals("UCAL_MILLISECONDS_IN_DAY", milliseconds_in_day, cal->get(UCAL_MILLISECONDS_IN_DAY, status));
|
||||
assertEquals("UCAL_IS_LEAP_MONTH", is_leap_month, cal->get(UCAL_IS_LEAP_MONTH, status));
|
||||
}
|
||||
|
||||
static constexpr double test_time = 1667277891323; // Nov 1, 2022 4:44:51 GMT
|
||||
|
||||
void CalendarTest::TestBasicConversionGregorian(void) {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
LocalPointer<Calendar> cal(icu::Calendar::createInstance(
|
||||
*TimeZone::getGMT(), Locale("en@calendar=gregorian"), status));
|
||||
if (U_FAILURE(status)) {
|
||||
errln("Fail: Cannot get Gregorian calendar");
|
||||
return;
|
||||
}
|
||||
AsssertCalendarFieldValue(
|
||||
cal.getAlias(), test_time, "gregorian",
|
||||
1, 2022, 10, 45, 1, 1, 305, 3, 1, 0, 4, 4, 44, 51,
|
||||
323, 0, 0, 2022, 3, 2022, 2459885, 17091323, 0);
|
||||
}
|
||||
void CalendarTest::TestBasicConversionISO8601(void) {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
LocalPointer<Calendar> cal(icu::Calendar::createInstance(
|
||||
*TimeZone::getGMT(), Locale("en@calendar=iso8601"), status));
|
||||
if (U_FAILURE(status)) {
|
||||
errln("Fail: Cannot get ISO8601 calendar");
|
||||
return;
|
||||
}
|
||||
AsssertCalendarFieldValue(
|
||||
cal.getAlias(), test_time, "iso8601",
|
||||
1, 2022, 10, 44, 1, 1, 305, 3, 1, 0, 4, 4, 44, 51,
|
||||
323, 0, 0, 2022, 2, 2022, 2459885, 17091323, 0);
|
||||
}
|
||||
void CalendarTest::TestBasicConversionJapanese(void) {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
LocalPointer<Calendar> cal(icu::Calendar::createInstance(
|
||||
*TimeZone::getGMT(), Locale("en@calendar=japanese"), status));
|
||||
if (U_FAILURE(status)) {
|
||||
errln("Fail: Cannot get Japanese calendar");
|
||||
return;
|
||||
}
|
||||
AsssertCalendarFieldValue(
|
||||
cal.getAlias(), test_time, "japanese",
|
||||
236, 4, 10, 45, 1, 1, 305, 3, 1, 0, 4, 4, 44, 51,
|
||||
323, 0, 0, 2022, 3, 2022, 2459885, 17091323, 0);
|
||||
}
|
||||
void CalendarTest::TestBasicConversionBuddhist(void) {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
LocalPointer<Calendar> cal(icu::Calendar::createInstance(
|
||||
*TimeZone::getGMT(), Locale("en@calendar=buddhist"), status));
|
||||
if (U_FAILURE(status)) {
|
||||
errln("Fail: Cannot get Buddhist calendar");
|
||||
return;
|
||||
}
|
||||
AsssertCalendarFieldValue(
|
||||
cal.getAlias(), test_time, "buddhist",
|
||||
0, 2565, 10, 45, 1, 1, 305, 3, 1, 0, 4, 4, 44, 51,
|
||||
323, 0, 0, 2022, 3, 2022, 2459885, 17091323, 0);
|
||||
}
|
||||
void CalendarTest::TestBasicConversionTaiwan(void) {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
LocalPointer<Calendar> cal(icu::Calendar::createInstance(
|
||||
*TimeZone::getGMT(), Locale("en@calendar=roc"), status));
|
||||
if (U_FAILURE(status)) {
|
||||
errln("Fail: Cannot get Taiwan calendar");
|
||||
return;
|
||||
}
|
||||
AsssertCalendarFieldValue(
|
||||
cal.getAlias(), test_time, "roc",
|
||||
1, 111, 10, 45, 1, 1, 305, 3, 1, 0, 4, 4, 44, 51,
|
||||
323, 0, 0, 2022, 3, 2022, 2459885, 17091323, 0);
|
||||
|
||||
}
|
||||
void CalendarTest::TestBasicConversionPersian(void) {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
LocalPointer<Calendar> cal(icu::Calendar::createInstance(
|
||||
*TimeZone::getGMT(), Locale("en@calendar=persian"), status));
|
||||
if (U_FAILURE(status)) {
|
||||
errln("Fail: Cannot get Persian calendar");
|
||||
return;
|
||||
}
|
||||
AsssertCalendarFieldValue(
|
||||
cal.getAlias(), test_time, "persian",
|
||||
0, 1401, 7, 33, 2, 10, 226, 3, 2, 0, 4, 4, 44, 51,
|
||||
323, 0, 0, 1401, 3, 1401, 2459885, 17091323, 0);
|
||||
}
|
||||
void CalendarTest::TestBasicConversionIslamic(void) {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
LocalPointer<Calendar> cal(icu::Calendar::createInstance(
|
||||
*TimeZone::getGMT(), Locale("en@calendar=islamic"), status));
|
||||
if (U_FAILURE(status)) {
|
||||
errln("Fail: Cannot get Islamic calendar");
|
||||
return;
|
||||
}
|
||||
AsssertCalendarFieldValue(
|
||||
cal.getAlias(), test_time, "islamic",
|
||||
0, 1444, 3, 15, 2, 7, 96, 3, 1, 0, 4, 4, 44, 51,
|
||||
323, 0, 0, 1444, 3, 1444, 2459885, 17091323, 0);
|
||||
}
|
||||
void CalendarTest::TestBasicConversionIslamicTBLA(void) {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
LocalPointer<Calendar> cal(icu::Calendar::createInstance(
|
||||
*TimeZone::getGMT(), Locale("en@calendar=islamic-tbla"), status));
|
||||
if (U_FAILURE(status)) {
|
||||
errln("Fail: Cannot get IslamicTBLA calendar");
|
||||
return;
|
||||
}
|
||||
AsssertCalendarFieldValue(
|
||||
cal.getAlias(), test_time, "islamic-tbla",
|
||||
0, 1444, 3, 15, 2, 7, 96, 3, 1, 0, 4, 4, 44, 51,
|
||||
323, 0, 0, 1444, 3, 1444, 2459885, 17091323, 0);
|
||||
|
||||
}
|
||||
void CalendarTest::TestBasicConversionIslamicCivil(void) {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
LocalPointer<Calendar> cal(icu::Calendar::createInstance(
|
||||
*TimeZone::getGMT(), Locale("en@calendar=islamic-civil"), status));
|
||||
if (U_FAILURE(status)) {
|
||||
errln("Fail: Cannot get IslamicCivil calendar");
|
||||
return;
|
||||
}
|
||||
AsssertCalendarFieldValue(
|
||||
cal.getAlias(), test_time, "islamic-civil",
|
||||
0, 1444, 3, 15, 2, 6, 95, 3, 1, 0, 4, 4, 44, 51,
|
||||
323, 0, 0, 1444, 3, 1444, 2459885, 17091323, 0);
|
||||
|
||||
}
|
||||
void CalendarTest::TestBasicConversionIslamicRGSA(void) {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
LocalPointer<Calendar> cal(icu::Calendar::createInstance(
|
||||
*TimeZone::getGMT(), Locale("en@calendar=islamic-rgsa"), status));
|
||||
if (U_FAILURE(status)) {
|
||||
errln("Fail: Cannot get IslamicRGSA calendar");
|
||||
return;
|
||||
}
|
||||
AsssertCalendarFieldValue(
|
||||
cal.getAlias(), test_time, "islamic-rgsa",
|
||||
0, 1444, 3, 15, 2, 7, 96, 3, 1, 0, 4, 4, 44, 51,
|
||||
323, 0, 0, 1444, 3, 1444, 2459885, 17091323, 0);
|
||||
|
||||
}
|
||||
void CalendarTest::TestBasicConversionIslamicUmalqura(void) {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
LocalPointer<Calendar> cal(icu::Calendar::createInstance(
|
||||
*TimeZone::getGMT(), Locale("en@calendar=islamic-umalqura"), status));
|
||||
if (U_FAILURE(status)) {
|
||||
errln("Fail: Cannot get IslamicUmalqura calendar");
|
||||
return;
|
||||
}
|
||||
AsssertCalendarFieldValue(
|
||||
cal.getAlias(), test_time, "islamic-umalqura",
|
||||
0, 1444, 3, 15, 2, 7, 95, 3, 1, 0, 4, 4, 44, 51,
|
||||
323, 0, 0, 1444, 3, 1444, 2459885, 17091323, 0);
|
||||
}
|
||||
void CalendarTest::TestBasicConversionHebrew(void) {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
LocalPointer<Calendar> cal(icu::Calendar::createInstance(
|
||||
*TimeZone::getGMT(), Locale("en@calendar=hebrew"), status));
|
||||
if (U_FAILURE(status)) {
|
||||
errln("Fail: Cannot get Hebrew calendar");
|
||||
return;
|
||||
}
|
||||
AsssertCalendarFieldValue(
|
||||
cal.getAlias(), test_time, "hebrew",
|
||||
0, 5783, 1, 6, 2, 7, 37, 3, 1, 0, 4, 4, 44, 51,
|
||||
323, 0, 0, 5783, 3, 5783, 2459885, 17091323, 0);
|
||||
}
|
||||
void CalendarTest::TestBasicConversionChinese(void) {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
LocalPointer<Calendar> cal(icu::Calendar::createInstance(
|
||||
*TimeZone::getGMT(), Locale("en@calendar=chinese"), status));
|
||||
if (U_FAILURE(status)) {
|
||||
errln("Fail: Cannot get Chinese calendar");
|
||||
return;
|
||||
}
|
||||
AsssertCalendarFieldValue(
|
||||
cal.getAlias(), test_time, "chinese",
|
||||
78, 39, 9, 40, 2, 8, 274, 3, 2, 0, 4, 4, 44, 51,
|
||||
323, 0, 0, 4659, 3, 4659, 2459885, 17091323, 0);
|
||||
}
|
||||
void CalendarTest::TestBasicConversionDangi(void) {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
LocalPointer<Calendar> cal(icu::Calendar::createInstance(
|
||||
*TimeZone::getGMT(), Locale("en@calendar=dangi"), status));
|
||||
if (U_FAILURE(status)) {
|
||||
errln("Fail: Cannot get Dangi calendar");
|
||||
return;
|
||||
}
|
||||
AsssertCalendarFieldValue(
|
||||
cal.getAlias(), test_time, "dangi",
|
||||
78, 39, 9, 40, 2, 8, 274, 3, 2, 0, 4, 4, 44, 51,
|
||||
323, 0, 0, 4355, 3, 4355, 2459885, 17091323, 0);
|
||||
}
|
||||
void CalendarTest::TestBasicConversionIndian(void) {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
LocalPointer<Calendar> cal(icu::Calendar::createInstance(
|
||||
*TimeZone::getGMT(), Locale("en@calendar=indian"), status));
|
||||
if (U_FAILURE(status)) {
|
||||
errln("Fail: Cannot get Indian calendar");
|
||||
return;
|
||||
}
|
||||
AsssertCalendarFieldValue(
|
||||
cal.getAlias(), test_time, "indian",
|
||||
0, 1944, 7, 33, 2, 10, 225, 3, 2, 0, 4, 4, 44, 51,
|
||||
323, 0, 0, 1944, 3, 1944, 2459885, 17091323, 0);
|
||||
}
|
||||
void CalendarTest::TestBasicConversionCoptic(void) {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
LocalPointer<Calendar> cal(icu::Calendar::createInstance(
|
||||
*TimeZone::getGMT(), Locale("en@calendar=coptic"), status));
|
||||
if (U_FAILURE(status)) {
|
||||
errln("Fail: Cannot get Coptic calendar");
|
||||
return;
|
||||
}
|
||||
AsssertCalendarFieldValue(
|
||||
cal.getAlias(), test_time, "coptic",
|
||||
1, 1739, 1, 8, 4, 22, 52, 3, 4, 0, 4, 4, 44, 51,
|
||||
323, 0, 0, 1739, 3, 1739, 2459885, 17091323, 0);
|
||||
}
|
||||
void CalendarTest::TestBasicConversionEthiopic(void) {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
LocalPointer<Calendar> cal(icu::Calendar::createInstance(
|
||||
*TimeZone::getGMT(), Locale("en@calendar=ethiopic"), status));
|
||||
if (U_FAILURE(status)) {
|
||||
errln("Fail: Cannot get Ethiopic calendar");
|
||||
return;
|
||||
}
|
||||
AsssertCalendarFieldValue(
|
||||
cal.getAlias(), test_time, "ethiopic",
|
||||
1, 2015, 1, 8, 4, 22, 52, 3, 4, 0, 4, 4, 44, 51,
|
||||
323, 0, 0, 2015, 3, 2015, 2459885, 17091323, 0);
|
||||
}
|
||||
void CalendarTest::TestBasicConversionEthiopicAmeteAlem(void) {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
LocalPointer<Calendar> cal(icu::Calendar::createInstance(
|
||||
*TimeZone::getGMT(), Locale("en@calendar=ethiopic-amete-alem"), status));
|
||||
if (U_FAILURE(status)) {
|
||||
errln("Fail: Cannot get EthiopicAmeteAlem calendar");
|
||||
return;
|
||||
}
|
||||
AsssertCalendarFieldValue(
|
||||
cal.getAlias(), test_time, "ethiopic-amete-alem",
|
||||
0, 7515, 1, 8, 4, 22, 52, 3, 4, 0, 4, 4, 44, 51,
|
||||
323, 0, 0, 2015, 3, 2015, 2459885, 17091323, 0);
|
||||
}
|
||||
|
||||
|
||||
void CalendarTest::setAndTestCalendar(Calendar* cal, int32_t initMonth, int32_t initDay, int32_t initYear, UErrorCode& status) {
|
||||
cal->clear();
|
||||
cal->setLenient(false);
|
||||
|
|
|
@ -257,6 +257,34 @@ public: // package
|
|||
void TestAddAcrossZoneTransition(void);
|
||||
|
||||
void TestChineseCalendarMapping(void);
|
||||
|
||||
void TestBasicConversionGregorian(void);
|
||||
void TestBasicConversionISO8601(void);
|
||||
void TestBasicConversionJapanese(void);
|
||||
void TestBasicConversionBuddhist(void);
|
||||
void TestBasicConversionTaiwan(void);
|
||||
void TestBasicConversionPersian(void);
|
||||
void TestBasicConversionIslamic(void);
|
||||
void TestBasicConversionIslamicTBLA(void);
|
||||
void TestBasicConversionIslamicCivil(void);
|
||||
void TestBasicConversionIslamicRGSA(void);
|
||||
void TestBasicConversionIslamicUmalqura(void);
|
||||
void TestBasicConversionHebrew(void);
|
||||
void TestBasicConversionChinese(void);
|
||||
void TestBasicConversionDangi(void);
|
||||
void TestBasicConversionIndian(void);
|
||||
void TestBasicConversionCoptic(void);
|
||||
void TestBasicConversionEthiopic(void);
|
||||
void TestBasicConversionEthiopicAmeteAlem(void);
|
||||
|
||||
void AsssertCalendarFieldValue(
|
||||
Calendar* cal, double time, const char* type,
|
||||
int32_t era, int32_t year, int32_t month, int32_t week_of_year,
|
||||
int32_t week_of_month, int32_t date, int32_t day_of_year, int32_t day_of_week,
|
||||
int32_t day_of_week_in_month, int32_t am_pm, int32_t hour, int32_t hour_of_day,
|
||||
int32_t minute, int32_t second, int32_t millisecond, int32_t zone_offset,
|
||||
int32_t dst_offset, int32_t year_woy, int32_t dow_local, int32_t extended_year,
|
||||
int32_t julian_day, int32_t milliseconds_in_day, int32_t is_leap_month);
|
||||
};
|
||||
|
||||
#endif /* #if !UCONFIG_NO_FORMATTING */
|
||||
|
|
|
@ -3477,8 +3477,8 @@ void DateFormatTest::TestTimeZoneInLocale()
|
|||
{ "my-u-ca-islamic-umalqura-tz-kzala", "Asia/Almaty", "islamic-umalqura" },
|
||||
{ "lo-u-ca-islamic-tbla-tz-bmbda", "Atlantic/Bermuda", "islamic-tbla" },
|
||||
{ "km-u-ca-islamic-civil-tz-aqplm", "Antarctica/Palmer", "islamic-civil" },
|
||||
{ "kk-u-ca-islamic-rgsa-tz-usanc", "America/Anchorage", "islamic" },
|
||||
{ "ar-u-ca-iso8601-tz-bjptn", "Africa/Porto-Novo", "gregorian" },
|
||||
{ "kk-u-ca-islamic-rgsa-tz-usanc", "America/Anchorage", "islamic-rgsa" },
|
||||
{ "ar-u-ca-iso8601-tz-bjptn", "Africa/Porto-Novo", "iso8601" },
|
||||
{ "he-u-ca-japanese-tz-tzdar", "Africa/Dar_es_Salaam", "japanese" },
|
||||
{ "bs-u-ca-persian-tz-etadd", "Africa/Addis_Ababa", "persian" },
|
||||
{ "it-u-ca-roc-tz-aruaq", "America/Argentina/San_Juan", "roc" },
|
||||
|
|
Loading…
Add table
Reference in a new issue