#include "hebrwcal.h"
#include "persncal.h"
#include "indiancal.h"
+#include "iso8601cal.h"
#include "chnsecal.h"
#include "coptccal.h"
#include "dangical.h"
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);
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);
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;
//-------------------------------------------------------------------------
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)
{
}
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
//-------------------------------------------------------------------------
{
// 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
{
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);
}
/**
{
// lazy-evaluate systemDefaultCenturyStartYear
umtx_initOnce(gSystemDefaultCenturyInit, &initializeSystemDefaultCentury);
- if (isAmeteAlemEra()) {
- return gSystemDefaultCenturyStartYear + AMETE_MIHRET_DELTA;
- }
return gSystemDefaultCenturyStartYear;
}
}
#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
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
* 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.
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
/**
* 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;
*/
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
*/
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
#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 */
<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" />
<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" />
<ClCompile Include="indiancal.cpp">
<Filter>formatting</Filter>
</ClCompile>
+ <ClCompile Include="iso8601cal.cpp">
+ <Filter>formatting</Filter>
+ </ClCompile>
<ClCompile Include="islamcal.cpp">
<Filter>formatting</Filter>
</ClCompile>
<ClInclude Include="indiancal.h">
<Filter>formatting</Filter>
</ClInclude>
+ <ClInclude Include="iso8601cal.h">
+ <Filter>formatting</Filter>
+ </ClInclude>
<ClInclude Include="islamcal.h">
<Filter>formatting</Filter>
</ClInclude>
<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" />
<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" />
//-------------------------------------------------------------------------
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
//-------------------------------------------------------------------------
* 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));
}
/**
* @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);
}
/**
* @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) ;
}
/**
* @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));
}
//-------------------------------------------------------------------------
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
* @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--;
- }
+ 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++;
+ }
- 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
+ // 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--;
}
- dayOfMonth = (days - monthStart(year, month)) + 1;
+ 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
// 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
* 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
* 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
*
//-------------------------------------------------------------------------
// Constants...
//-------------------------------------------------------------------------
-
- /**
- * Calendar type - civil or religious or um alqura
- * @internal
- */
- enum ECalculationType {
- ASTRONOMICAL,
- CIVIL,
- UMALQURA,
- TBLA
- };
-
/**
* Constants for the months
* @internal
* @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.
*/
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
* @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
*/
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
*/
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
//----------------------------------------------------------------------
*/
virtual void handleComputeFields(int32_t julianDay, UErrorCode &status) override;
+ /**
+ * Return the epoc.
+ * @internal
+ */
+ virtual int32_t getEpoc() const;
+
// UObject stuff
public:
/**
/*U_I18N_API*/ static UClassID U_EXPORT2 getStaticClassID(void);
/**
- * return the calendar type, "buddhist".
+ * return the calendar type, "islamic".
*
* @return calendar type
* @internal
static void U_CALLCONV initializeSystemDefaultCentury(void);
};
-U_NAMESPACE_END
+/*
+ * 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);
-#endif
-#endif
+ /**
+ * 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
--- /dev/null
+// © 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
--- /dev/null
+// © 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
indiancal.cpp
inputext.cpp
islamcal.cpp
+iso8601cal.cpp
japancal.cpp
listformatter.cpp
measfmt.cpp
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
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;
}
}
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++) {
{ "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" },
}
}
+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);
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 */
{ "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" },