summaryrefslogtreecommitdiff
path: root/deps/icu-small/source/i18n/gregocal.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'deps/icu-small/source/i18n/gregocal.cpp')
-rw-r--r--deps/icu-small/source/i18n/gregocal.cpp32
1 files changed, 16 insertions, 16 deletions
diff --git a/deps/icu-small/source/i18n/gregocal.cpp b/deps/icu-small/source/i18n/gregocal.cpp
index 4db66758df..028ab05aa9 100644
--- a/deps/icu-small/source/i18n/gregocal.cpp
+++ b/deps/icu-small/source/i18n/gregocal.cpp
@@ -286,7 +286,7 @@ fIsGregorian(source.fIsGregorian), fInvertGregorian(source.fInvertGregorian)
// -------------------------------------
-Calendar* GregorianCalendar::clone() const
+GregorianCalendar* GregorianCalendar::clone() const
{
return new GregorianCalendar(*this);
}
@@ -324,26 +324,26 @@ GregorianCalendar::setGregorianChange(UDate date, UErrorCode& status)
if (U_FAILURE(status))
return;
- fGregorianCutover = date;
-
// Precompute two internal variables which we use to do the actual
// cutover computations. These are the normalized cutover, which is the
// midnight at or before the cutover, and the cutover year. The
// normalized cutover is in pure date milliseconds; it contains no time
// of day or timezone component, and it used to compare against other
// pure date values.
- int32_t cutoverDay = (int32_t)ClockMath::floorDivide(fGregorianCutover, (double)kOneDay);
- fNormalizedGregorianCutover = cutoverDay * kOneDay;
-
- // Handle the rare case of numeric overflow. If the user specifies a
- // change of UDate(Long.MIN_VALUE), in order to get a pure Gregorian
- // calendar, then the epoch day is -106751991168, which when multiplied
- // by ONE_DAY gives 9223372036794351616 -- the negative value is too
- // large for 64 bits, and overflows into a positive value. We correct
- // this by using the next day, which for all intents is semantically
- // equivalent.
- if (cutoverDay < 0 && fNormalizedGregorianCutover > 0) {
- fNormalizedGregorianCutover = (cutoverDay + 1) * kOneDay;
+ double cutoverDay = ClockMath::floorDivide(date, (double)kOneDay);
+
+ // Handle the rare case of numeric overflow where the user specifies a time
+ // outside of INT32_MIN .. INT32_MAX number of days.
+
+ if (cutoverDay <= INT32_MIN) {
+ cutoverDay = INT32_MIN;
+ fGregorianCutover = fNormalizedGregorianCutover = cutoverDay * kOneDay;
+ } else if (cutoverDay >= INT32_MAX) {
+ cutoverDay = INT32_MAX;
+ fGregorianCutover = fNormalizedGregorianCutover = cutoverDay * kOneDay;
+ } else {
+ fNormalizedGregorianCutover = cutoverDay * kOneDay;
+ fGregorianCutover = date;
}
// Normalize the year so BC values are represented as 0 and negative
@@ -360,7 +360,7 @@ GregorianCalendar::setGregorianChange(UDate date, UErrorCode& status)
fGregorianCutoverYear = cal->get(UCAL_YEAR, status);
if (cal->get(UCAL_ERA, status) == BC)
fGregorianCutoverYear = 1 - fGregorianCutoverYear;
- fCutoverJulianDay = cutoverDay;
+ fCutoverJulianDay = (int32_t)cutoverDay;
delete cal;
}