Skip to content

Commit e3e8153

Browse files
committed
ICU-23102 Simplify Calendar code
Avoid calling unnecessary computeGregorianFields() Refactor and reduced handleComputeFields in CECalendar
1 parent 97c2c33 commit e3e8153

File tree

11 files changed

+171
-148
lines changed

11 files changed

+171
-148
lines changed

icu4c/source/i18n/cecal.cpp

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,8 @@ CECalendar::handleGetLimit(UCalendarDateFields field, ELimitType limitType) cons
101101
// Calendar system Conversion methods...
102102
//-------------------------------------------------------------------------
103103

104-
void
105-
CECalendar::jdToCE(int32_t julianDay, int32_t jdEpochOffset, int32_t& year, int32_t& month, int32_t& day, UErrorCode& status)
104+
namespace {
105+
void jdToCE(int32_t julianDay, int32_t jdEpochOffset, int32_t& year, int32_t& month, int32_t& day, int32_t& doy, UErrorCode& status)
106106
{
107107
int32_t c4; // number of 4 year cycle (1461 days)
108108
int32_t r4; // remainder of 4 year cycle, always positive
@@ -115,10 +115,30 @@ CECalendar::jdToCE(int32_t julianDay, int32_t jdEpochOffset, int32_t& year, int3
115115

116116
year = 4 * c4 + (r4/365 - r4/1460); // 4 * <number of 4year cycle> + <years within the last cycle>
117117

118-
int32_t doy = (r4 == 1460) ? 365 : (r4 % 365); // days in present year
118+
doy = (r4 == 1460) ? 365 : (r4 % 365); // days in present year
119119

120120
month = doy / 30; // 30 -> Coptic/Ethiopic month length up to 12th month
121121
day = (doy % 30) + 1; // 1-based days in a month
122+
doy++; // 1-based days in a year.
123+
}
124+
} // namespace
125+
126+
void
127+
CECalendar::handleComputeFields(int32_t julianDay, UErrorCode& status)
128+
{
129+
int32_t eyear, month, day, doy;
130+
jdToCE(julianDay, getJDEpochOffset(), eyear, month, day, doy, status);
131+
if (U_FAILURE(status)) return;
132+
int32_t era = extendedYearToEra(eyear);
133+
int32_t year = extendedYearToYear(eyear);
134+
135+
internalSet(UCAL_EXTENDED_YEAR, eyear);
136+
internalSet(UCAL_ERA, era);
137+
internalSet(UCAL_YEAR, year);
138+
internalSet(UCAL_MONTH, month);
139+
internalSet(UCAL_ORDINAL_MONTH, month);
140+
internalSet(UCAL_DATE, day);
141+
internalSet(UCAL_DAY_OF_YEAR, doy);
122142
}
123143

124144
static const char* kMonthCode13 = "M13";

icu4c/source/i18n/cecal.h

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,12 @@ class U_I18N_API CECalendar : public Calendar {
9999
*/
100100
virtual int32_t handleGetLimit(UCalendarDateFields field, ELimitType limitType) const override;
101101

102+
/**
103+
* Compute fields from the JD
104+
* @internal
105+
*/
106+
virtual void handleComputeFields(int32_t julianDay, UErrorCode &status) override;
107+
102108
protected:
103109
/**
104110
* The Coptic and Ethiopic calendars differ only in their epochs.
@@ -109,17 +115,16 @@ class U_I18N_API CECalendar : public Calendar {
109115
virtual int32_t getJDEpochOffset() const = 0;
110116

111117
/**
112-
* Convert a Julian day to an Coptic/Ethiopic year, month and day
113-
*
114-
* @param julianDay the Julian day
115-
* @param jdEpochOffset the epoch offset from Julian epoch
116-
* @param year receives the extended year
117-
* @param month receives the month
118-
* @param date receives the day
118+
* Compute the era from extended year.
119+
* @internal
120+
*/
121+
virtual int32_t extendedYearToEra(int32_t extendedYear) const = 0;
122+
123+
/**
124+
* Compute the year from extended year.
119125
* @internal
120126
*/
121-
static void jdToCE(int32_t julianDay, int32_t jdEpochOffset,
122-
int32_t& year, int32_t& month, int32_t& day, UErrorCode& status);
127+
virtual int32_t extendedYearToYear(int32_t extendedYear) const = 0;
123128
};
124129

125130
U_NAMESPACE_END

icu4c/source/i18n/coptccal.cpp

Lines changed: 12 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -78,30 +78,6 @@ CopticCalendar::handleGetExtendedYear(UErrorCode& status)
7878
return 0;
7979
}
8080

81-
void
82-
CopticCalendar::handleComputeFields(int32_t julianDay, UErrorCode& status)
83-
{
84-
int32_t eyear, month, day, era, year;
85-
jdToCE(julianDay, getJDEpochOffset(), eyear, month, day, status);
86-
if (U_FAILURE(status)) return;
87-
88-
if (eyear <= 0) {
89-
era = BCE;
90-
year = 1 - eyear;
91-
} else {
92-
era = CE;
93-
year = eyear;
94-
}
95-
96-
internalSet(UCAL_EXTENDED_YEAR, eyear);
97-
internalSet(UCAL_ERA, era);
98-
internalSet(UCAL_YEAR, year);
99-
internalSet(UCAL_MONTH, month);
100-
internalSet(UCAL_ORDINAL_MONTH, month);
101-
internalSet(UCAL_DATE, day);
102-
internalSet(UCAL_DAY_OF_YEAR, (30 * month) + day);
103-
}
104-
10581
IMPL_SYSTEM_DEFAULT_CENTURY(CopticCalendar, "@calendar=coptic")
10682

10783
int32_t
@@ -110,6 +86,18 @@ CopticCalendar::getJDEpochOffset() const
11086
return COPTIC_JD_EPOCH_OFFSET;
11187
}
11288

89+
int32_t CopticCalendar::extendedYearToEra(int32_t extendedYear) const {
90+
return extendedYear <= 0 ? BCE : CE;
91+
}
92+
93+
int32_t CopticCalendar::extendedYearToYear(int32_t extendedYear) const {
94+
return extendedYear <= 0 ? 1 - extendedYear : extendedYear;
95+
}
96+
97+
bool CopticCalendar::isEra0CountingBackward() const {
98+
return true;
99+
}
100+
113101
int32_t
114102
CopticCalendar::getRelatedYearDifference() const {
115103
constexpr int32_t kCopticCalendarRelatedYearDifference = 284;

icu4c/source/i18n/coptccal.h

Lines changed: 15 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -170,21 +170,30 @@ class CopticCalendar : public CECalendar {
170170
*/
171171
virtual int32_t handleGetExtendedYear(UErrorCode& status) override;
172172

173+
DECLARE_OVERRIDE_SYSTEM_DEFAULT_CENTURY
174+
173175
/**
174-
* Compute fields from the JD
176+
* Return the date offset from Julian
175177
* @internal
176178
*/
177-
virtual void handleComputeFields(int32_t julianDay, UErrorCode &status) override;
179+
int32_t getJDEpochOffset() const override;
178180

179-
DECLARE_OVERRIDE_SYSTEM_DEFAULT_CENTURY
181+
/**
182+
* Compute the era from extended year.
183+
* @internal
184+
*/
185+
int32_t extendedYearToEra(int32_t extendedYear) const override;
180186

181187
/**
182-
* Return the date offset from Julian
188+
* Compute the year from extended year.
183189
* @internal
184190
*/
185-
virtual int32_t getJDEpochOffset() const override;
191+
int32_t extendedYearToYear(int32_t extendedYear) const override;
186192

187-
virtual bool isEra0CountingBackward() const override { return true; }
193+
/**
194+
* @internal
195+
*/
196+
bool isEra0CountingBackward() const override;
188197
public:
189198
/**
190199
* Override Calendar Returns a unique class ID POLYMORPHICALLY. Pure virtual
@@ -211,24 +220,6 @@ class CopticCalendar : public CECalendar {
211220
*/
212221
U_I18N_API static UClassID U_EXPORT2 getStaticClassID();
213222

214-
#if 0
215-
// We do not want to introduce this API in ICU4C.
216-
// It was accidentally introduced in ICU4J as a public API.
217-
public:
218-
//-------------------------------------------------------------------------
219-
// Calendar system Conversion methods...
220-
//-------------------------------------------------------------------------
221-
/**
222-
* Convert an Coptic year, month, and day to a Julian day.
223-
*
224-
* @param year the extended year
225-
* @param month the month
226-
* @param day the day
227-
* @return Julian day
228-
* @internal
229-
*/
230-
static int32_t copticToJD(int32_t year, int32_t month, int32_t day);
231-
#endif
232223
};
233224

234225
U_NAMESPACE_END

icu4c/source/i18n/ethpccal.cpp

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -79,22 +79,6 @@ EthiopicCalendar::handleGetExtendedYear(UErrorCode& status)
7979
return year;
8080
}
8181

82-
void
83-
EthiopicCalendar::handleComputeFields(int32_t julianDay, UErrorCode& status)
84-
{
85-
int32_t eyear, month, day;
86-
jdToCE(julianDay, getJDEpochOffset(), eyear, month, day, status);
87-
if (U_FAILURE(status)) return;
88-
89-
internalSet(UCAL_EXTENDED_YEAR, eyear);
90-
internalSet(UCAL_ERA, (eyear > 0) ? AMETE_MIHRET : AMETE_ALEM);
91-
internalSet(UCAL_YEAR, (eyear > 0) ? eyear : (eyear + AMETE_MIHRET_DELTA));
92-
internalSet(UCAL_MONTH, month);
93-
internalSet(UCAL_ORDINAL_MONTH, month);
94-
internalSet(UCAL_DATE, day);
95-
internalSet(UCAL_DAY_OF_YEAR, (30 * month) + day);
96-
}
97-
9882
IMPL_SYSTEM_DEFAULT_CENTURY(EthiopicCalendar, "@calendar=ethiopic")
9983

10084
int32_t
@@ -103,6 +87,13 @@ EthiopicCalendar::getJDEpochOffset() const
10387
return JD_EPOCH_OFFSET_AMETE_MIHRET;
10488
}
10589

90+
int32_t EthiopicCalendar::extendedYearToEra(int32_t extendedYear) const {
91+
return extendedYear <= 0 ? AMETE_ALEM : AMETE_MIHRET;
92+
}
93+
94+
int32_t EthiopicCalendar::extendedYearToYear(int32_t extendedYear) const {
95+
return extendedYear <= 0 ? extendedYear + AMETE_MIHRET_DELTA : extendedYear;
96+
}
10697

10798
int32_t EthiopicCalendar::getRelatedYearDifference() const {
10899
constexpr int32_t kEthiopicCalendarRelatedYearDifference = 8;
@@ -159,14 +150,15 @@ EthiopicAmeteAlemCalendar::handleGetExtendedYear(UErrorCode& status)
159150
return year;
160151
}
161152

162-
void
163-
EthiopicAmeteAlemCalendar::handleComputeFields(int32_t julianDay, UErrorCode& status)
164-
{
165-
EthiopicCalendar::handleComputeFields(julianDay, status);
166-
internalSet(UCAL_ERA, AMETE_ALEM);
167-
internalSet(UCAL_YEAR, internalGet(UCAL_EXTENDED_YEAR, 1) + AMETE_MIHRET_DELTA);
153+
int32_t EthiopicAmeteAlemCalendar::extendedYearToEra(int32_t /* extendedYear */) const {
154+
return AMETE_ALEM;
168155
}
169156

157+
int32_t EthiopicAmeteAlemCalendar::extendedYearToYear(int32_t extendedYear) const {
158+
return extendedYear + AMETE_MIHRET_DELTA;
159+
}
160+
161+
170162
int32_t
171163
EthiopicAmeteAlemCalendar::handleGetLimit(UCalendarDateFields field, ELimitType limitType) const
172164
{

icu4c/source/i18n/ethpccal.h

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -162,19 +162,25 @@ class EthiopicCalendar : public CECalendar {
162162
*/
163163
virtual int32_t handleGetExtendedYear(UErrorCode& status) override;
164164

165+
DECLARE_OVERRIDE_SYSTEM_DEFAULT_CENTURY
166+
165167
/**
166-
* Compute fields from the JD
168+
* Return the date offset from Julian
167169
* @internal
168170
*/
169-
virtual void handleComputeFields(int32_t julianDay, UErrorCode &status) override;
171+
int32_t getJDEpochOffset() const override;
170172

171-
DECLARE_OVERRIDE_SYSTEM_DEFAULT_CENTURY
173+
/**
174+
* Compute the era from extended year.
175+
* @internal
176+
*/
177+
int32_t extendedYearToEra(int32_t extendedYear) const override;
172178

173179
/**
174-
* Return the date offset from Julian
180+
* Compute the year from extended year.
175181
* @internal
176182
*/
177-
virtual int32_t getJDEpochOffset() const override;
183+
int32_t extendedYearToYear(int32_t extendedYear) const override;
178184

179185
public:
180186
/**
@@ -314,12 +320,6 @@ class EthiopicAmeteAlemCalendar : public EthiopicCalendar {
314320
*/
315321
virtual int32_t handleGetExtendedYear(UErrorCode& status) override;
316322

317-
/**
318-
* Compute fields from the JD
319-
* @internal
320-
*/
321-
virtual void handleComputeFields(int32_t julianDay, UErrorCode &status) override;
322-
323323
/**
324324
* Calculate the limit for a specified type of limit and field
325325
* @internal
@@ -330,6 +330,18 @@ class EthiopicAmeteAlemCalendar : public EthiopicCalendar {
330330
* @internal
331331
*/
332332
virtual int32_t defaultCenturyStartYear() const override;
333+
334+
/**
335+
* Compute the era from extended year.
336+
* @internal
337+
*/
338+
int32_t extendedYearToEra(int32_t extendedYear) const override;
339+
340+
/**
341+
* Compute the year from extended year.
342+
* @internal
343+
*/
344+
int32_t extendedYearToYear(int32_t extendedYear) const override;
333345
};
334346

335347
U_NAMESPACE_END

icu4c/source/i18n/indiancal.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -251,13 +251,12 @@ int32_t IndianCalendar::handleGetExtendedYear(UErrorCode& status) {
251251
* method is called. The getGregorianXxx() methods return Gregorian
252252
* calendar equivalents for the given Julian day.
253253
*/
254-
void IndianCalendar::handleComputeFields(int32_t julianDay, UErrorCode& status) {
254+
void IndianCalendar::handleComputeFields(int32_t julianDay, UErrorCode& /* status */) {
255255
double jdAtStartOfGregYear;
256256
int32_t leapMonth, IndianYear, yday, IndianMonth, IndianDayOfMonth, mday;
257257
// Stores gregorian date corresponding to Julian day;
258-
int32_t gregorianYear = Grego::dayToYear(julianDay - kEpochStartAsJulianDay, status);
258+
int32_t gregorianYear = getGregorianYear();
259259

260-
if (U_FAILURE(status)) return;
261260
IndianYear = gregorianYear - INDIAN_ERA_START; // Year in Saka era
262261
jdAtStartOfGregYear = gregorianToJD(gregorianYear, 0, 1); // JD at start of Gregorian year
263262
yday = static_cast<int32_t>(julianDay - jdAtStartOfGregYear); // Day number in Gregorian year (starting from 0)
@@ -294,7 +293,7 @@ void IndianCalendar::handleComputeFields(int32_t julianDay, UErrorCode& status)
294293
internalSet(UCAL_ORDINAL_MONTH, IndianMonth);
295294
internalSet(UCAL_DAY_OF_MONTH, IndianDayOfMonth);
296295
internalSet(UCAL_DAY_OF_YEAR, yday + 1); // yday is 0-based
297-
}
296+
}
298297

299298
IMPL_SYSTEM_DEFAULT_CENTURY(IndianCalendar, "@calendar=indian")
300299

icu4j/main/core/src/main/java/com/ibm/icu/util/CECalendar.java

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,42 @@ protected CECalendar(int year, int month, int date, int hour,
174174
*/
175175
abstract protected int getJDEpochOffset();
176176

177+
/**
178+
* {@inheritDoc}
179+
* @internal
180+
* @deprecated This API is ICU internal only.
181+
*/
182+
@Override
183+
@Deprecated
184+
protected void handleComputeFields(int julianDay) {
185+
int era, year;
186+
int[] fields = new int[3];
187+
jdToCE(julianDay, getJDEpochOffset(), fields);
188+
internalSet(EXTENDED_YEAR, fields[0]);
189+
internalSet(ERA, extendedYearToEra(fields[0]));
190+
internalSet(YEAR, extendedYearToYear(fields[0]));
191+
internalSet(MONTH, fields[1]);
192+
internalSet(ORDINAL_MONTH, fields[1]);
193+
internalSet(DAY_OF_MONTH, fields[2]);
194+
internalSet(DAY_OF_YEAR, (30 * fields[1]) + fields[2]);
195+
}
196+
197+
/**
198+
* Convert extended year to era
199+
* @internal
200+
* @deprecated This API is ICU internal only.
201+
*/
202+
@Deprecated
203+
abstract protected int extendedYearToEra(int eyear);
204+
205+
/**
206+
* Convert extended year to year
207+
* @internal
208+
* @deprecated This API is ICU internal only.
209+
*/
210+
@Deprecated
211+
abstract protected int extendedYearToYear(int eyear);
212+
177213
/**
178214
* Return JD of start of given month/extended year
179215
*/

0 commit comments

Comments
 (0)