-
-
Notifications
You must be signed in to change notification settings - Fork 767
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ICU-23006 Fix Chinese Calendar getActualMaximize #3348
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -253,11 +253,16 @@ int32_t ChineseCalendar::handleGetExtendedYear(UErrorCode& status) { | |
* @stable ICU 2.8 | ||
*/ | ||
int32_t ChineseCalendar::handleGetMonthLength(int32_t extendedYear, int32_t month, UErrorCode& status) const { | ||
bool isLeapMonth = internalGet(UCAL_IS_LEAP_MONTH) == 1; | ||
return handleGetMonthLengthWithLeap(extendedYear, month, isLeapMonth, status); | ||
} | ||
|
||
int32_t ChineseCalendar::handleGetMonthLengthWithLeap(int32_t extendedYear, int32_t month, bool leap, UErrorCode& status) const { | ||
const Setting setting = getSetting(status); | ||
if (U_FAILURE(status)) { | ||
return 0; | ||
} | ||
int32_t thisStart = handleComputeMonthStart(extendedYear, month, true, status); | ||
int32_t thisStart = handleComputeMonthStartWithLeap(extendedYear, month, leap, status); | ||
if (U_FAILURE(status)) { | ||
return 0; | ||
} | ||
|
@@ -333,6 +338,14 @@ struct MonthInfo computeMonthInfo( | |
* @stable ICU 2.8 | ||
*/ | ||
int64_t ChineseCalendar::handleComputeMonthStart(int32_t eyear, int32_t month, UBool useMonth, UErrorCode& status) const { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same question here: Is it really worth it to split There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is necessary because we cannot change the signature of handleComputeMonthStart since it is defined by the superclass but we need to pass in the leap information separately to avoid infinity recusion |
||
bool isLeapMonth = false; | ||
if (useMonth) { | ||
isLeapMonth = internalGet(UCAL_IS_LEAP_MONTH) != 0; | ||
} | ||
return handleComputeMonthStartWithLeap(eyear, month, isLeapMonth, status); | ||
} | ||
|
||
int64_t ChineseCalendar::handleComputeMonthStartWithLeap(int32_t eyear, int32_t month, bool isLeapMonth, UErrorCode& status) const { | ||
if (U_FAILURE(status)) { | ||
return 0; | ||
} | ||
|
@@ -363,12 +376,6 @@ int64_t ChineseCalendar::handleComputeMonthStart(int32_t eyear, int32_t month, U | |
return 0; | ||
} | ||
|
||
// Ignore IS_LEAP_MONTH field if useMonth is false | ||
bool isLeapMonth = false; | ||
if (useMonth) { | ||
isLeapMonth = internalGet(UCAL_IS_LEAP_MONTH) != 0; | ||
} | ||
|
||
int32_t newMonthYear = Grego::dayToYear(newMoon, status); | ||
|
||
struct MonthInfo monthInfo = computeMonthInfo(setting, newMonthYear, newMoon, status); | ||
|
@@ -1184,6 +1191,27 @@ ChineseCalendar::Setting ChineseCalendar::getSetting(UErrorCode&) const { | |
}; | ||
} | ||
|
||
int32_t | ||
ChineseCalendar::getActualMaximum(UCalendarDateFields field, UErrorCode& status) const | ||
{ | ||
if (U_FAILURE(status)) { | ||
return 0; | ||
} | ||
if (field == UCAL_DATE) { | ||
LocalPointer<ChineseCalendar> cal(clone(), status); | ||
if(U_FAILURE(status)) { | ||
return 0; | ||
} | ||
cal->setLenient(true); | ||
cal->prepareGetActual(field,false,status); | ||
int32_t year = cal->get(UCAL_EXTENDED_YEAR, status); | ||
int32_t month = cal->get(UCAL_MONTH, status); | ||
bool leap = cal->get(UCAL_IS_LEAP_MONTH, status) != 0; | ||
return handleGetMonthLengthWithLeap(year, month, leap, status); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm guessing this is a partial answer to my question is here, but if you just left There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The problem is one usage need to use get (to force the calculation of all fields) and the other need to use internalGet (to avoid infinity recursion) and I cannot change the function signature (because it is defined in the base class as a protected method for all subclass of Calendar). The tricky part of this fix is it is very easy to get into infinity recursion There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Okay. Thanks for the explanation. |
||
} | ||
return Calendar::getActualMaximum(field, status); | ||
} | ||
|
||
U_NAMESPACE_END | ||
|
||
#endif | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it really worth it to split
handleGetMonthLength()
into two functions like this? Wouldn't it be easier to just make the change insidehandleGetMonthLength()
?