}
// -------------------------------------
-// For now the full getRelatedYear implementation is here;
-// per #10752 move the non-default implementation to subclasses
-// (default implementation will do no year adjustment)
-
-static int32_t gregoYearFromIslamicStart(int32_t year) {
- // ad hoc conversion, improve under #10752
- // rough est for now, ok for grego 1846-2138,
- // otherwise occasionally wrong (for 3% of years)
- int cycle, offset, shift = 0;
- if (year >= 1397) {
- cycle = (year - 1397) / 67;
- offset = (year - 1397) % 67;
- shift = 2*cycle + ((offset >= 33)? 1: 0);
- } else {
- cycle = (year - 1396) / 67 - 1;
- offset = -(year - 1396) % 67;
- shift = 2*cycle + ((offset <= 33)? 1: 0);
- }
- return year + 579 - shift;
-}
-
int32_t Calendar::getRelatedYear(UErrorCode &status) const
{
- if (U_FAILURE(status)) {
- return 0;
- }
- int32_t year = get(UCAL_EXTENDED_YEAR, status);
- if (U_FAILURE(status)) {
- return 0;
- }
- // modify for calendar type
- ECalType type = getCalendarType(getType());
- switch (type) {
- case CALTYPE_PERSIAN:
- year += 622; break;
- case CALTYPE_HEBREW:
- year -= 3760; break;
- case CALTYPE_CHINESE:
- year -= 2637; break;
- case CALTYPE_INDIAN:
- year += 79; break;
- case CALTYPE_COPTIC:
- year += 284; break;
- case CALTYPE_ETHIOPIC:
- year += 8; break;
- case CALTYPE_ETHIOPIC_AMETE_ALEM:
- year -=5492; break;
- case CALTYPE_DANGI:
- year -= 2333; break;
- case CALTYPE_ISLAMIC_CIVIL:
- case CALTYPE_ISLAMIC:
- case CALTYPE_ISLAMIC_UMALQURA:
- case CALTYPE_ISLAMIC_TBLA:
- case CALTYPE_ISLAMIC_RGSA:
- year = gregoYearFromIslamicStart(year); break;
- default:
- // CALTYPE_GREGORIAN
- // CALTYPE_JAPANESE
- // CALTYPE_BUDDHIST
- // CALTYPE_ROC
- // CALTYPE_ISO8601
- // do nothing, EXTENDED_YEAR same as Gregorian
- break;
- }
- return year;
+ return get(UCAL_EXTENDED_YEAR, status);
}
// -------------------------------------
-// For now the full setRelatedYear implementation is here;
-// per #10752 move the non-default implementation to subclasses
-// (default implementation will do no year adjustment)
-
-static int32_t firstIslamicStartYearFromGrego(int32_t year) {
- // ad hoc conversion, improve under #10752
- // rough est for now, ok for grego 1846-2138,
- // otherwise occasionally wrong (for 3% of years)
- int cycle, offset, shift = 0;
- if (year >= 1977) {
- cycle = (year - 1977) / 65;
- offset = (year - 1977) % 65;
- shift = 2*cycle + ((offset >= 32)? 1: 0);
- } else {
- cycle = (year - 1976) / 65 - 1;
- offset = -(year - 1976) % 65;
- shift = 2*cycle + ((offset <= 32)? 1: 0);
- }
- return year - 579 + shift;
-}
void Calendar::setRelatedYear(int32_t year)
{
- // modify for calendar type
- ECalType type = getCalendarType(getType());
- switch (type) {
- case CALTYPE_PERSIAN:
- year -= 622; break;
- case CALTYPE_HEBREW:
- year += 3760; break;
- case CALTYPE_CHINESE:
- year += 2637; break;
- case CALTYPE_INDIAN:
- year -= 79; break;
- case CALTYPE_COPTIC:
- year -= 284; break;
- case CALTYPE_ETHIOPIC:
- year -= 8; break;
- case CALTYPE_ETHIOPIC_AMETE_ALEM:
- year +=5492; break;
- case CALTYPE_DANGI:
- year += 2333; break;
- case CALTYPE_ISLAMIC_CIVIL:
- case CALTYPE_ISLAMIC:
- case CALTYPE_ISLAMIC_UMALQURA:
- case CALTYPE_ISLAMIC_TBLA:
- case CALTYPE_ISLAMIC_RGSA:
- year = firstIslamicStartYearFromGrego(year); break;
- default:
- // CALTYPE_GREGORIAN
- // CALTYPE_JAPANESE
- // CALTYPE_BUDDHIST
- // CALTYPE_ROC
- // CALTYPE_ISO8601
- // do nothing, EXTENDED_YEAR same as Gregorian
- break;
- }
// set extended year
set(UCAL_EXTENDED_YEAR, year);
}
}
}
+constexpr uint32_t kChineseRelatedYearDiff = -2637;
+
+int32_t ChineseCalendar::getRelatedYear(UErrorCode &status) const
+{
+ int32_t year = get(UCAL_EXTENDED_YEAR, status);
+ if (U_FAILURE(status)) {
+ return 0;
+ }
+ return year + kChineseRelatedYearDiff;
+}
+
+void ChineseCalendar::setRelatedYear(int32_t year)
+{
+ // set extended year
+ set(UCAL_EXTENDED_YEAR, year - kChineseRelatedYearDiff);
+}
// default century
virtual void roll(UCalendarDateFields field, int32_t amount, UErrorCode &status) override;
virtual void roll(EDateFields field, int32_t amount, UErrorCode &status) override;
+ /**
+ * @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;
+
//----------------------------------------------------------------------
// Internal methods & astronomical calculations
//----------------------------------------------------------------------
internalSet(UCAL_DAY_OF_YEAR, (30 * month) + day);
}
+constexpr uint32_t kCopticRelatedYearDiff = 284;
+
+int32_t CopticCalendar::getRelatedYear(UErrorCode &status) const
+{
+ int32_t year = get(UCAL_EXTENDED_YEAR, status);
+ if (U_FAILURE(status)) {
+ return 0;
+ }
+ return year + kCopticRelatedYearDiff;
+}
+
+void CopticCalendar::setRelatedYear(int32_t year)
+{
+ // set extended year
+ set(UCAL_EXTENDED_YEAR, year - kCopticRelatedYearDiff);
+}
+
/**
* The system maintains a static default century start date and Year. They are
* initialized the first time they are used. Once the system default century date
*/
const char * getType() const override;
+ /**
+ * @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 gDangiCalendarZoneAstroCalc;
}
+constexpr uint32_t kDangiRelatedYearDiff = -2333;
+
+int32_t DangiCalendar::getRelatedYear(UErrorCode &status) const
+{
+ int32_t year = get(UCAL_EXTENDED_YEAR, status);
+ if (U_FAILURE(status)) {
+ return 0;
+ }
+ return year + kDangiRelatedYearDiff;
+}
+
+void DangiCalendar::setRelatedYear(int32_t year)
+{
+ // set extended year
+ set(UCAL_EXTENDED_YEAR, year - kDangiRelatedYearDiff);
+}
+
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(DangiCalendar)
// Internal methods & astronomical calculations
//----------------------------------------------------------------------
+ /**
+ * @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;
+
private:
const TimeZone* getDangiCalZoneAstroCalc(UErrorCode &status) const;
return CECalendar::handleGetLimit(field, limitType);
}
+
+constexpr uint32_t kEthiopicRelatedYearDiff = 8;
+constexpr uint32_t kEthiopicAmeteAlemRelatedYearDiff = -5492;
+
+int32_t EthiopicCalendar::getRelatedYear(UErrorCode &status) const
+{
+ int32_t year = get(UCAL_EXTENDED_YEAR, status);
+ if (U_FAILURE(status)) {
+ return 0;
+ }
+ return year + (isAmeteAlemEra() ? kEthiopicAmeteAlemRelatedYearDiff : kEthiopicRelatedYearDiff);
+}
+
+void EthiopicCalendar::setRelatedYear(int32_t year)
+{
+ // set extended year
+ set(UCAL_EXTENDED_YEAR, year -
+ (isAmeteAlemEra() ? kEthiopicAmeteAlemRelatedYearDiff : kEthiopicRelatedYearDiff));
+}
+
/**
* The system maintains a static default century start date and Year. They are
* initialized the first time they are used. Once the system default century date
*/
UBool isAmeteAlemEra() const;
+ /**
+ * @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 (int) (day + 347997);
}
+constexpr uint32_t kHebrewRelatedYearDiff = -3760;
+
+int32_t HebrewCalendar::getRelatedYear(UErrorCode &status) const
+{
+ int32_t year = get(UCAL_EXTENDED_YEAR, status);
+ if (U_FAILURE(status)) {
+ return 0;
+ }
+ return year + kHebrewRelatedYearDiff;
+}
+
+void HebrewCalendar::setRelatedYear(int32_t year)
+{
+ // set extended year
+ set(UCAL_EXTENDED_YEAR, year - kHebrewRelatedYearDiff);
+}
+
/**
* The system maintains a static default century start date and Year. They are
* initialized the first time they are used. Once the system default century date
*/
static UBool isLeapYear(int32_t year) ;
+ /**
+ * @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:
/**
internalSet(UCAL_DAY_OF_YEAR, yday + 1); // yday is 0-based
}
+constexpr uint32_t kIndianRelatedYearDiff = 79;
+
+int32_t IndianCalendar::getRelatedYear(UErrorCode &status) const
+{
+ int32_t year = get(UCAL_EXTENDED_YEAR, status);
+ if (U_FAILURE(status)) {
+ return 0;
+ }
+ return year + kIndianRelatedYearDiff;
+}
+
+void IndianCalendar::setRelatedYear(int32_t year)
+{
+ // set extended year
+ set(UCAL_EXTENDED_YEAR, year - kIndianRelatedYearDiff);
+}
+
/**
* The system maintains a static default century start date and Year. They are
* initialized the first time they are used. Once the system default century date
*/
virtual const char * getType() const override;
+ /**
+ * @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;
+
+
private:
IndianCalendar() = delete; // default constructor not implemented
internalSet(UCAL_DAY_OF_YEAR, dayOfYear);
}
+static int32_t gregoYearFromIslamicStart(int32_t year) {
+ // ad hoc conversion, improve under #10752
+ // rough est for now, ok for grego 1846-2138,
+ // otherwise occasionally wrong (for 3% of years)
+ int cycle, offset, shift = 0;
+ if (year >= 1397) {
+ cycle = (year - 1397) / 67;
+ offset = (year - 1397) % 67;
+ shift = 2*cycle + ((offset >= 33)? 1: 0);
+ } else {
+ cycle = (year - 1396) / 67 - 1;
+ offset = -(year - 1396) % 67;
+ shift = 2*cycle + ((offset <= 33)? 1: 0);
+ }
+ return year + 579 - shift;
+}
+
+int32_t IslamicCalendar::getRelatedYear(UErrorCode &status) const
+{
+ int32_t year = get(UCAL_EXTENDED_YEAR, status);
+ if (U_FAILURE(status)) {
+ return 0;
+ }
+ return gregoYearFromIslamicStart(year);
+}
+
+static int32_t firstIslamicStartYearFromGrego(int32_t year) {
+ // ad hoc conversion, improve under #10752
+ // rough est for now, ok for grego 1846-2138,
+ // otherwise occasionally wrong (for 3% of years)
+ int cycle, offset, shift = 0;
+ if (year >= 1977) {
+ cycle = (year - 1977) / 65;
+ offset = (year - 1977) % 65;
+ shift = 2*cycle + ((offset >= 32)? 1: 0);
+ } else {
+ cycle = (year - 1976) / 65 - 1;
+ offset = -(year - 1976) % 65;
+ shift = 2*cycle + ((offset <= 32)? 1: 0);
+ }
+ return year - 579 + shift;
+}
+
+void IslamicCalendar::setRelatedYear(int32_t year)
+{
+ set(UCAL_EXTENDED_YEAR, firstIslamicStartYearFromGrego(year));
+}
+
/**
* The system maintains a static default century start date and Year. They are
* initialized the first time they are used. Once the system default century date
*/
virtual const char * getType() const override;
+ /**
+ * @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;
+
private:
IslamicCalendar() = delete; // default constructor not implemented
internalSet(UCAL_DAY_OF_YEAR, dayOfYear);
}
+constexpr uint32_t kPersianRelatedYearDiff = 622;
+
+int32_t PersianCalendar::getRelatedYear(UErrorCode &status) const
+{
+ int32_t year = get(UCAL_EXTENDED_YEAR, status);
+ if (U_FAILURE(status)) {
+ return 0;
+ }
+ return year + kPersianRelatedYearDiff;
+}
+
+void PersianCalendar::setRelatedYear(int32_t year)
+{
+ // set extended year
+ set(UCAL_EXTENDED_YEAR, year - kPersianRelatedYearDiff);
+}
+
// default century
static UDate gSystemDefaultCenturyStart = DBL_MIN;
*/
virtual const char * getType() const override;
+ /**
+ * @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;
+
private:
PersianCalendar(); // default constructor not implemented