Skip to content

Commit 1c1533b

Browse files
committed
ICU-23102 Refactor and simplify Calendar code
See #3470
1 parent b092784 commit 1c1533b

24 files changed

+224
-389
lines changed

icu4c/source/i18n/calendar.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1236,16 +1236,31 @@ Calendar::set(int32_t year, int32_t month, int32_t date, int32_t hour, int32_t m
12361236
// -------------------------------------
12371237
int32_t Calendar::getRelatedYear(UErrorCode &status) const
12381238
{
1239-
return get(UCAL_EXTENDED_YEAR, status);
1239+
int32_t year = get(UCAL_EXTENDED_YEAR, status);
1240+
if (U_FAILURE(status)) {
1241+
return 0;
1242+
}
1243+
if (uprv_add32_overflow(year, getRelatedYearDifference(), &year)) {
1244+
status = U_ILLEGAL_ARGUMENT_ERROR;
1245+
return 0;
1246+
}
1247+
return year;
12401248
}
12411249

12421250
// -------------------------------------
12431251
void Calendar::setRelatedYear(int32_t year)
12441252
{
12451253
// set extended year
1254+
if (uprv_add32_overflow(year, -getRelatedYearDifference(), &year)) {
1255+
return;
1256+
}
12461257
set(UCAL_EXTENDED_YEAR, year);
12471258
}
12481259

1260+
int32_t Calendar::getRelatedYearDifference() const {
1261+
return 0;
1262+
}
1263+
12491264
// -------------------------------------
12501265

12511266
void

icu4c/source/i18n/chnsecal.cpp

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1074,25 +1074,8 @@ void ChineseCalendar::offsetMonth(int32_t newMoon, int32_t dayOfMonth, int32_t d
10741074
}
10751075
}
10761076

1077-
constexpr uint32_t kChineseRelatedYearDiff = -2637;
1078-
1079-
int32_t ChineseCalendar::getRelatedYear(UErrorCode &status) const
1080-
{
1081-
int32_t year = get(UCAL_EXTENDED_YEAR, status);
1082-
if (U_FAILURE(status)) {
1083-
return 0;
1084-
}
1085-
if (uprv_add32_overflow(year, kChineseRelatedYearDiff, &year)) {
1086-
status = U_ILLEGAL_ARGUMENT_ERROR;
1087-
return 0;
1088-
}
1089-
return year;
1090-
}
1091-
1092-
void ChineseCalendar::setRelatedYear(int32_t year)
1093-
{
1094-
// set extended year
1095-
set(UCAL_EXTENDED_YEAR, year - kChineseRelatedYearDiff);
1077+
int32_t ChineseCalendar::getRelatedYearDifference() const {
1078+
return CHINESE_EPOCH_YEAR - 1;
10961079
}
10971080

10981081
IMPL_SYSTEM_DEFAULT_CENTURY(ChineseCalendar, "@calendar=chinese")

icu4c/source/i18n/chnsecal.h

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -204,19 +204,11 @@ class U_I18N_API ChineseCalendar : public Calendar {
204204
virtual void roll(UCalendarDateFields field, int32_t amount, UErrorCode &status) override;
205205
virtual void roll(EDateFields field, int32_t amount, UErrorCode &status) override;
206206

207+
protected:
207208
/**
208-
* @return The related Gregorian year; will be obtained by modifying the value
209-
* obtained by get from UCAL_EXTENDED_YEAR field
210-
* @internal
211-
*/
212-
virtual int32_t getRelatedYear(UErrorCode &status) const override;
213-
214-
/**
215-
* @param year The related Gregorian year to set; will be modified as necessary then
216-
* set in UCAL_EXTENDED_YEAR field
217209
* @internal
218210
*/
219-
virtual void setRelatedYear(int32_t year) override;
211+
int32_t getRelatedYearDifference() const override;
220212

221213
//----------------------------------------------------------------------
222214
// Internal methods & astronomical calculations

icu4c/source/i18n/coptccal.cpp

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -102,23 +102,6 @@ CopticCalendar::handleComputeFields(int32_t julianDay, UErrorCode& status)
102102
internalSet(UCAL_DAY_OF_YEAR, (30 * month) + day);
103103
}
104104

105-
constexpr uint32_t kCopticRelatedYearDiff = 284;
106-
107-
int32_t CopticCalendar::getRelatedYear(UErrorCode &status) const
108-
{
109-
int32_t year = get(UCAL_EXTENDED_YEAR, status);
110-
if (U_FAILURE(status)) {
111-
return 0;
112-
}
113-
return year + kCopticRelatedYearDiff;
114-
}
115-
116-
void CopticCalendar::setRelatedYear(int32_t year)
117-
{
118-
// set extended year
119-
set(UCAL_EXTENDED_YEAR, year - kCopticRelatedYearDiff);
120-
}
121-
122105
IMPL_SYSTEM_DEFAULT_CENTURY(CopticCalendar, "@calendar=coptic")
123106

124107
int32_t
@@ -127,6 +110,12 @@ CopticCalendar::getJDEpochOffset() const
127110
return COPTIC_JD_EPOCH_OFFSET;
128111
}
129112

113+
int32_t
114+
CopticCalendar::getRelatedYearDifference() const {
115+
constexpr int32_t kCopticCalendarRelatedYearDifference = 284;
116+
return kCopticCalendarRelatedYearDifference;
117+
}
118+
130119

131120
U_NAMESPACE_END
132121

icu4c/source/i18n/coptccal.h

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -154,25 +154,16 @@ class CopticCalendar : public CECalendar {
154154
*/
155155
const char * getType() const override;
156156

157-
/**
158-
* @return The related Gregorian year; will be obtained by modifying the value
159-
* obtained by get from UCAL_EXTENDED_YEAR field
160-
* @internal
161-
*/
162-
virtual int32_t getRelatedYear(UErrorCode &status) const override;
163-
164-
/**
165-
* @param year The related Gregorian year to set; will be modified as necessary then
166-
* set in UCAL_EXTENDED_YEAR field
167-
* @internal
168-
*/
169-
virtual void setRelatedYear(int32_t year) override;
170-
171157
protected:
172158
//-------------------------------------------------------------------------
173159
// Calendar framework
174160
//-------------------------------------------------------------------------
175161

162+
/**
163+
* @internal
164+
*/
165+
int32_t getRelatedYearDifference() const override;
166+
176167
/**
177168
* Return the extended year defined by the current fields.
178169
* @internal

icu4c/source/i18n/dangical.cpp

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -158,25 +158,8 @@ const TimeZone* getAstronomerTimeZone(UErrorCode &status) {
158158
return gAstronomerTimeZone;
159159
}
160160

161-
constexpr uint32_t kDangiRelatedYearDiff = -2333;
162-
163-
int32_t DangiCalendar::getRelatedYear(UErrorCode &status) const
164-
{
165-
int32_t year = get(UCAL_EXTENDED_YEAR, status);
166-
if (U_FAILURE(status)) {
167-
return 0;
168-
}
169-
if (uprv_add32_overflow(year, kDangiRelatedYearDiff, &year)) {
170-
status = U_ILLEGAL_ARGUMENT_ERROR;
171-
return 0;
172-
}
173-
return year;
174-
}
175-
176-
void DangiCalendar::setRelatedYear(int32_t year)
177-
{
178-
// set extended year
179-
set(UCAL_EXTENDED_YEAR, year - kDangiRelatedYearDiff);
161+
int32_t DangiCalendar::getRelatedYearDifference() const {
162+
return DANGI_EPOCH_YEAR - 1;
180163
}
181164

182165
ChineseCalendar::Setting DangiCalendar::getSetting(UErrorCode& status) const {

icu4c/source/i18n/dangical.h

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -68,24 +68,6 @@ class DangiCalendar : public ChineseCalendar {
6868
*/
6969
virtual DangiCalendar* clone() const override;
7070

71-
//----------------------------------------------------------------------
72-
// Internal methods & astronomical calculations
73-
//----------------------------------------------------------------------
74-
75-
/**
76-
* @return The related Gregorian year; will be obtained by modifying the value
77-
* obtained by get from UCAL_EXTENDED_YEAR field
78-
* @internal
79-
*/
80-
virtual int32_t getRelatedYear(UErrorCode &status) const override;
81-
82-
/**
83-
* @param year The related Gregorian year to set; will be modified as necessary then
84-
* set in UCAL_EXTENDED_YEAR field
85-
* @internal
86-
*/
87-
virtual void setRelatedYear(int32_t year) override;
88-
8971
private:
9072

9173
// UObject stuff
@@ -121,6 +103,11 @@ class DangiCalendar : public ChineseCalendar {
121103
protected:
122104
virtual Setting getSetting(UErrorCode& status) const override;
123105

106+
/*
107+
* @internal
108+
*/
109+
int32_t getRelatedYearDifference() const override;
110+
124111
private:
125112

126113
DangiCalendar(); // default constructor not implemented

icu4c/source/i18n/ethpccal.cpp

Lines changed: 10 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -95,23 +95,6 @@ EthiopicCalendar::handleComputeFields(int32_t julianDay, UErrorCode& status)
9595
internalSet(UCAL_DAY_OF_YEAR, (30 * month) + day);
9696
}
9797

98-
constexpr uint32_t kEthiopicRelatedYearDiff = 8;
99-
100-
int32_t EthiopicCalendar::getRelatedYear(UErrorCode &status) const
101-
{
102-
int32_t year = get(UCAL_EXTENDED_YEAR, status);
103-
if (U_FAILURE(status)) {
104-
return 0;
105-
}
106-
return year + kEthiopicRelatedYearDiff;
107-
}
108-
109-
void EthiopicCalendar::setRelatedYear(int32_t year)
110-
{
111-
// set extended year
112-
set(UCAL_EXTENDED_YEAR, year - kEthiopicRelatedYearDiff);
113-
}
114-
11598
IMPL_SYSTEM_DEFAULT_CENTURY(EthiopicCalendar, "@calendar=ethiopic")
11699

117100
int32_t
@@ -121,6 +104,11 @@ EthiopicCalendar::getJDEpochOffset() const
121104
}
122105

123106

107+
int32_t EthiopicCalendar::getRelatedYearDifference() const {
108+
constexpr int32_t kEthiopicCalendarRelatedYearDifference = 8;
109+
return kEthiopicCalendarRelatedYearDifference;
110+
}
111+
124112
//-------------------------------------------------------------------------
125113
// Constructors...
126114
//-------------------------------------------------------------------------
@@ -188,29 +176,17 @@ EthiopicAmeteAlemCalendar::handleGetLimit(UCalendarDateFields field, ELimitType
188176
return EthiopicCalendar::handleGetLimit(field, limitType);
189177
}
190178

191-
constexpr uint32_t kEthiopicAmeteAlemRelatedYearDiff = -5492;
192-
193-
int32_t EthiopicAmeteAlemCalendar::getRelatedYear(UErrorCode &status) const
194-
{
195-
int32_t year = get(UCAL_EXTENDED_YEAR, status);
196-
if (U_FAILURE(status)) {
197-
return 0;
198-
}
199-
return year + kEthiopicAmeteAlemRelatedYearDiff;
200-
}
201-
202-
void EthiopicAmeteAlemCalendar::setRelatedYear(int32_t year)
203-
{
204-
// set extended year
205-
set(UCAL_EXTENDED_YEAR, year - kEthiopicAmeteAlemRelatedYearDiff);
206-
}
207-
208179
int32_t
209180
EthiopicAmeteAlemCalendar::defaultCenturyStartYear() const
210181
{
211182
return EthiopicCalendar::defaultCenturyStartYear() + AMETE_MIHRET_DELTA;
212183
}
213184

185+
186+
int32_t EthiopicAmeteAlemCalendar::getRelatedYearDifference() const {
187+
constexpr int32_t kEthiopicAmeteAlemCalendarRelatedYearDifference = -5492;
188+
return kEthiopicAmeteAlemCalendarRelatedYearDifference;
189+
}
214190
U_NAMESPACE_END
215191

216192
#endif

icu4c/source/i18n/ethpccal.h

Lines changed: 10 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -141,25 +141,16 @@ class EthiopicCalendar : public CECalendar {
141141
*/
142142
virtual const char * getType() const override;
143143

144-
/**
145-
* @return The related Gregorian year; will be obtained by modifying the value
146-
* obtained by get from UCAL_EXTENDED_YEAR field
147-
* @internal
148-
*/
149-
virtual int32_t getRelatedYear(UErrorCode &status) const override;
150-
151-
/**
152-
* @param year The related Gregorian year to set; will be modified as necessary then
153-
* set in UCAL_EXTENDED_YEAR field
154-
* @internal
155-
*/
156-
virtual void setRelatedYear(int32_t year) override;
157-
158144
protected:
159145
//-------------------------------------------------------------------------
160146
// Calendar framework
161147
//-------------------------------------------------------------------------
162148

149+
/**
150+
* @internal
151+
*/
152+
int32_t getRelatedYearDifference() const override;
153+
163154
/**
164155
* Return the extended year defined by the current fields.
165156
* This calendar uses both AMETE_ALEM and AMETE_MIHRET.
@@ -302,25 +293,16 @@ class EthiopicAmeteAlemCalendar : public EthiopicCalendar {
302293
*/
303294
U_I18N_API static UClassID U_EXPORT2 getStaticClassID();
304295

305-
/**
306-
* @return The related Gregorian year; will be obtained by modifying the value
307-
* obtained by get from UCAL_EXTENDED_YEAR field
308-
* @internal
309-
*/
310-
virtual int32_t getRelatedYear(UErrorCode &status) const override;
311-
312-
/**
313-
* @param year The related Gregorian year to set; will be modified as necessary then
314-
* set in UCAL_EXTENDED_YEAR field
315-
* @internal
316-
*/
317-
virtual void setRelatedYear(int32_t year) override;
318-
319296
protected:
320297
//-------------------------------------------------------------------------
321298
// Calendar framework
322299
//-------------------------------------------------------------------------
323300

301+
/**
302+
* @internal
303+
*/
304+
int32_t getRelatedYearDifference() const override;
305+
324306
/**
325307
* Return the extended year defined by the current fields.
326308
* This calendar use only AMETE_ALEM for the era.

icu4c/source/i18n/hebrwcal.cpp

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -790,23 +790,6 @@ int64_t HebrewCalendar::handleComputeMonthStart(
790790
return day + 347997LL;
791791
}
792792

793-
constexpr uint32_t kHebrewRelatedYearDiff = -3760;
794-
795-
int32_t HebrewCalendar::getRelatedYear(UErrorCode &status) const
796-
{
797-
int32_t year = get(UCAL_EXTENDED_YEAR, status);
798-
if (U_FAILURE(status)) {
799-
return 0;
800-
}
801-
return year + kHebrewRelatedYearDiff;
802-
}
803-
804-
void HebrewCalendar::setRelatedYear(int32_t year)
805-
{
806-
// set extended year
807-
set(UCAL_EXTENDED_YEAR, year - kHebrewRelatedYearDiff);
808-
}
809-
810793
IMPL_SYSTEM_DEFAULT_CENTURY(HebrewCalendar, "@calendar=hebrew")
811794

812795
bool HebrewCalendar::inTemporalLeapYear(UErrorCode& status) const {
@@ -872,6 +855,11 @@ int32_t HebrewCalendar::internalGetMonth(UErrorCode& status) const {
872855
return Calendar::internalGetMonth(status);
873856
}
874857

858+
int32_t HebrewCalendar::getRelatedYearDifference() const {
859+
constexpr int32_t kHebrewCalendarRelatedYearDifference = -3760;
860+
return kHebrewCalendarRelatedYearDifference;
861+
}
862+
875863
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(HebrewCalendar)
876864

877865
U_NAMESPACE_END

0 commit comments

Comments
 (0)