Skip to content

Commit

Permalink
ICU-22991 Simplified Grego code
Browse files Browse the repository at this point in the history
Use timeToFields instead of dayToFields
  • Loading branch information
FrankYFTang committed Jan 8, 2025
1 parent 9eafd8c commit 270b7d0
Show file tree
Hide file tree
Showing 6 changed files with 22 additions and 33 deletions.
4 changes: 1 addition & 3 deletions icu4c/source/i18n/chnsecal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -339,12 +339,10 @@ int64_t ChineseCalendar::handleComputeMonthStart(int32_t eyear, int32_t month, U
// If the month is out of range, adjust it into range, and
// modify the extended year value accordingly.
if (month < 0 || month > 11) {
double m = month;
if (uprv_add32_overflow(eyear, ClockMath::floorDivide(m, 12.0, &m), &eyear)) {
if (uprv_add32_overflow(eyear, ClockMath::floorDivide(month, 12, &month), &eyear)) {
status = U_ILLEGAL_ARGUMENT_ERROR;
return 0;
}
month = static_cast<int32_t>(m);
}

const Setting setting = getSetting(status);
Expand Down
19 changes: 12 additions & 7 deletions icu4c/source/i18n/gregoimp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,11 @@ double ClockMath::floorDivide(double numerator, int32_t denominator,
}

double ClockMath::floorDivide(double dividend, double divisor,
double* remainder) {
int32_t* remainder) {
// Only designed to work for positive divisors
U_ASSERT(divisor > 0);
double quotient = floorDivide(dividend, divisor);
double r = dividend - (quotient * divisor);
int32_t r = dividend - (quotient * divisor);
// N.B. For certain large dividends, on certain platforms, there
// is a bug such that the quotient is off by one. If you doubt
// this to be true, set a breakpoint below and run cintltst.
Expand Down Expand Up @@ -203,16 +203,21 @@ void Grego::timeToFields(UDate time, int32_t& year, int8_t& month,
void Grego::timeToFields(UDate time, int32_t& year, int8_t& month,
int8_t& dom, int8_t& dow, int16_t& doy, int32_t& mid, UErrorCode& status) {
if (U_FAILURE(status)) return;
double millisInDay;
double day = ClockMath::floorDivide(static_cast<double>(time), static_cast<double>(U_MILLIS_PER_DAY), &millisInDay);
mid = static_cast<int32_t>(millisInDay);
double day = ClockMath::floorDivide(time, U_MILLIS_PER_DAY, &mid);
if (day > INT32_MAX || day < INT32_MIN) {
status = U_ILLEGAL_ARGUMENT_ERROR;
return;
}
dayToFields(day, year, month, dom, dow, doy, status);
}

int32_t Grego::timeToYear(UDate time, UErrorCode& status) {
if (U_FAILURE(status)) return 0;
double millisInDay;
int32_t day = ClockMath::floorDivide(static_cast<double>(time), static_cast<double>(U_MILLIS_PER_DAY), &millisInDay);
double day = ClockMath::floorDivide(time, U_MILLIS_PER_DAY, nullptr);
if (day > INT32_MAX || day < INT32_MIN) {
status = U_ILLEGAL_ARGUMENT_ERROR;
return 0;
}
return Grego::dayToYear(day, status);
}

Expand Down
2 changes: 1 addition & 1 deletion icu4c/source/i18n/gregoimp.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ class ClockMath {
* Calling with a divisor <= 0 is disallowed.
*/
static double floorDivide(double dividend, double divisor,
double* remainder);
int32_t* remainder);
};

// Useful millisecond constants
Expand Down
10 changes: 5 additions & 5 deletions icu4c/source/i18n/olsontz.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -436,11 +436,11 @@ int32_t OlsonTimeZone::getRawOffset() const {

#if defined U_DEBUG_TZ
void printTime(double ms) {
int32_t year, month, dom, dow;
double millis=0;
double days = ClockMath::floorDivide(((double)ms), (double)U_MILLIS_PER_DAY, millis);

Grego::dayToFields(days, year, month, dom, dow);
int32_t year;
int8_t month, dom, dow;
int32_t millis=0;
UErrorCode status = U_ZERO_ERROR;
Grego::timeToFields(ms, year, month, dom, dow, millis, status);
U_DEBUG_TZ_MSG((" getHistoricalOffset: time %.1f (%04d.%02d.%02d+%.1fh)\n", ms,
year, month+1, dom, (millis/kOneHour)));
}
Expand Down
11 changes: 2 additions & 9 deletions icu4c/source/i18n/simpletz.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -520,14 +520,8 @@ SimpleTimeZone::getOffsetFromLocal(UDate date, UTimeZoneLocalOption nonExistingT
rawOffsetGMT = getRawOffset();
int32_t year, millis;
int8_t month, dom, dow;
double dday = ClockMath::floorDivide(date, U_MILLIS_PER_DAY, &millis);
if (dday > INT32_MAX || dday < INT32_MIN) {
status = U_ILLEGAL_ARGUMENT_ERROR;
return;
}
int32_t day = dday;

Grego::dayToFields(day, year, month, dom, dow, status);
Grego::timeToFields(date, year, month, dom, dow, millis, status);
if (U_FAILURE(status)) return;

savingsDST = getOffset(GregorianCalendar::AD, year, month, dom,
Expand Down Expand Up @@ -555,8 +549,7 @@ SimpleTimeZone::getOffsetFromLocal(UDate date, UTimeZoneLocalOption nonExistingT
}
}
if (recalc) {
day = ClockMath::floorDivide(date, U_MILLIS_PER_DAY, &millis);
Grego::dayToFields(day, year, month, dom, dow, status);
Grego::timeToFields(date, year, month, dom, dow, millis, status);
if (U_FAILURE(status)) return;
savingsDST = getOffset(GregorianCalendar::AD, year, month, dom,
static_cast<uint8_t>(dow), millis,
Expand Down
9 changes: 1 addition & 8 deletions icu4c/source/i18n/timezone.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -732,14 +732,7 @@ void TimeZone::getOffset(UDate date, UBool local, int32_t& rawOffset,
for (int32_t pass=0; ; ++pass) {
int32_t year, millis;
int8_t month, dom, dow;
double day = ClockMath::floorDivide(date, U_MILLIS_PER_DAY, &millis);

// out of the range
if (day < INT32_MIN || day > INT32_MAX) {
ec = U_ILLEGAL_ARGUMENT_ERROR;
return;
}
Grego::dayToFields(day, year, month, dom, dow, ec);
Grego::timeToFields(date, year, month, dom, dow, millis, ec);
if (U_FAILURE(ec)) return;

dstOffset = getOffset(GregorianCalendar::AD, year, month, dom,
Expand Down

0 comments on commit 270b7d0

Please sign in to comment.