diff options
author | romankoshelev <romankoshelev@yandex-team.com> | 2024-05-13 11:00:27 +0300 |
---|---|---|
committer | romankoshelev <romankoshelev@yandex-team.com> | 2024-05-13 11:13:05 +0300 |
commit | 5b22fadb0f035a3b82c328e0ae710ad2b92f6eac (patch) | |
tree | e15dc649c79c4fb78f35cd6694dfe9af9bfcc0ad /contrib/libs/icu/i18n/persncal.cpp | |
parent | 5946aa7d3cbca62f6bcf074e8a2b9346e7a96af4 (diff) | |
download | ydb-5b22fadb0f035a3b82c328e0ae710ad2b92f6eac.tar.gz |
Update ICU to 75.1
904da4ae1c86fc5542eac7f1cd18d97b72eb8517
Diffstat (limited to 'contrib/libs/icu/i18n/persncal.cpp')
-rw-r--r-- | contrib/libs/icu/i18n/persncal.cpp | 117 |
1 files changed, 50 insertions, 67 deletions
diff --git a/contrib/libs/icu/i18n/persncal.cpp b/contrib/libs/icu/i18n/persncal.cpp index ab13f43434..c97a32197a 100644 --- a/contrib/libs/icu/i18n/persncal.cpp +++ b/contrib/libs/icu/i18n/persncal.cpp @@ -21,6 +21,7 @@ #if !UCONFIG_NO_FORMATTING +#include "uassert.h" #include "umutex.h" #include "gregoimp.h" // Math #include <float.h> @@ -110,17 +111,16 @@ int32_t PersianCalendar::handleGetLimit(UCalendarDateFields field, ELimitType li */ UBool PersianCalendar::isLeapYear(int32_t year) { - int32_t remainder; - ClockMath::floorDivide(25 * year + 11, 33, &remainder); - return (remainder < 8); + int64_t y = static_cast<int64_t>(year) * 25LL + 11LL; + return (y % 33L < 8); } /** * Return the day # on which the given year starts. Days are counted * from the Persian epoch, origin 0. */ -int32_t PersianCalendar::yearStart(int32_t year) { - return handleComputeMonthStart(year,0,false); +int32_t PersianCalendar::yearStart(int32_t year, UErrorCode& status) { + return handleComputeMonthStart(year,0,false, status); } /** @@ -130,8 +130,8 @@ int32_t PersianCalendar::yearStart(int32_t year) { * @param year The Persian year * @param year The Persian month, 0-based */ -int32_t PersianCalendar::monthStart(int32_t year, int32_t month) const { - return handleComputeMonthStart(year,month,true); +int32_t PersianCalendar::monthStart(int32_t year, int32_t month, UErrorCode& status) const { + return handleComputeMonthStart(year,month,true, status); } //---------------------------------------------------------------------- @@ -144,7 +144,7 @@ int32_t PersianCalendar::monthStart(int32_t year, int32_t month) const { * @param year The Persian year * @param year The Persian month, 0-based */ -int32_t PersianCalendar::handleGetMonthLength(int32_t extendedYear, int32_t month) const { +int32_t PersianCalendar::handleGetMonthLength(int32_t extendedYear, int32_t month, UErrorCode& /*status*/) const { // If the month is out of range, adjust it into range, and // modify the extended year value accordingly. if (month < 0 || month > 11) { @@ -166,14 +166,20 @@ int32_t PersianCalendar::handleGetYearLength(int32_t extendedYear) const { //------------------------------------------------------------------------- // Return JD of start of given month/year -int32_t PersianCalendar::handleComputeMonthStart(int32_t eyear, int32_t month, UBool /*useMonth*/) const { +int64_t PersianCalendar::handleComputeMonthStart(int32_t eyear, int32_t month, UBool /*useMonth*/, UErrorCode& status) const { + if (U_FAILURE(status)) { + return 0; + } // If the month is out of range, adjust it into range, and // modify the extended year value accordingly. if (month < 0 || month > 11) { - eyear += ClockMath::floorDivide(month, 12, &month); + if (uprv_add32_overflow(eyear, ClockMath::floorDivide(month, 12, &month), &eyear)) { + status = U_ILLEGAL_ARGUMENT_ERROR; + return 0; + } } - int32_t julianDay = PERSIAN_EPOCH - 1 + 365 * (eyear - 1) + ClockMath::floorDivide(8 * eyear + 21, 33); + int64_t julianDay = PERSIAN_EPOCH - 1LL + 365LL * (eyear - 1LL) + ClockMath::floorDivide(8LL * eyear + 21, 33); if (month != 0) { julianDay += kPersianNumDays[month]; @@ -186,14 +192,14 @@ int32_t PersianCalendar::handleComputeMonthStart(int32_t eyear, int32_t month, U // Functions for converting from milliseconds to field values //------------------------------------------------------------------------- -int32_t PersianCalendar::handleGetExtendedYear() { - int32_t year; +int32_t PersianCalendar::handleGetExtendedYear(UErrorCode& status) { + if (U_FAILURE(status)) { + return 0; + } if (newerField(UCAL_EXTENDED_YEAR, UCAL_YEAR) == UCAL_EXTENDED_YEAR) { - year = internalGet(UCAL_EXTENDED_YEAR, 1); // Default to year 1 - } else { - year = internalGet(UCAL_YEAR, 1); // Default to year 1 + return internalGet(UCAL_EXTENDED_YEAR, 1); // Default to year 1 } - return year; + return internalGet(UCAL_YEAR, 1); // Default to year 1 } /** @@ -210,20 +216,33 @@ int32_t PersianCalendar::handleGetExtendedYear() { * The DAY_OF_WEEK and DOW_LOCAL fields are already set when this * method is called. */ -void PersianCalendar::handleComputeFields(int32_t julianDay, UErrorCode &/*status*/) { - int32_t year, month, dayOfMonth, dayOfYear; - - int32_t daysSinceEpoch = julianDay - PERSIAN_EPOCH; - year = 1 + (int32_t)ClockMath::floorDivide(33 * (int64_t)daysSinceEpoch + 3, (int64_t)12053); +void PersianCalendar::handleComputeFields(int32_t julianDay, UErrorCode& status) { + int64_t daysSinceEpoch = julianDay - PERSIAN_EPOCH; + int64_t year = ClockMath::floorDivideInt64( + 33LL * daysSinceEpoch + 3LL, 12053LL) + 1LL; + if (year > INT32_MAX || year < INT32_MIN) { + status = U_ILLEGAL_ARGUMENT_ERROR; + return; + } - int32_t farvardin1 = 365 * (year - 1) + ClockMath::floorDivide(8 * year + 21, 33); - dayOfYear = (daysSinceEpoch - farvardin1); // 0-based + int64_t farvardin1 = 365LL * (year - 1) + ClockMath::floorDivide(8LL * year + 21, 33); + int32_t dayOfYear = daysSinceEpoch - farvardin1; // 0-based + U_ASSERT(dayOfYear >= 0); + U_ASSERT(dayOfYear < 366); + // + int32_t month; if (dayOfYear < 216) { // Compute 0-based month month = dayOfYear / 31; } else { month = (dayOfYear - 6) / 30; } - dayOfMonth = dayOfYear - kPersianNumDays[month] + 1; + U_ASSERT(month >= 0); + U_ASSERT(month < 12); + + int32_t dayOfMonth = dayOfYear - kPersianNumDays[month] + 1; + U_ASSERT(dayOfMonth > 0); + U_ASSERT(dayOfMonth <= 31); + ++dayOfYear; // Make it 1-based now internalSet(UCAL_ERA, 0); @@ -243,7 +262,11 @@ int32_t PersianCalendar::getRelatedYear(UErrorCode &status) const if (U_FAILURE(status)) { return 0; } - return year + kPersianRelatedYearDiff; + if (uprv_add32_overflow(year, kPersianRelatedYearDiff, &year)) { + status = U_ILLEGAL_ARGUMENT_ERROR; + return 0; + } + return year; } void PersianCalendar::setRelatedYear(int32_t year) @@ -252,50 +275,10 @@ void PersianCalendar::setRelatedYear(int32_t year) set(UCAL_EXTENDED_YEAR, year - kPersianRelatedYearDiff); } -// default century - -static UDate gSystemDefaultCenturyStart = DBL_MIN; -static int32_t gSystemDefaultCenturyStartYear = -1; -static icu::UInitOnce gSystemDefaultCenturyInit {}; - -UBool PersianCalendar::haveDefaultCentury() const -{ - return true; -} - -static void U_CALLCONV initializeSystemDefaultCentury() { - // initialize systemDefaultCentury and systemDefaultCenturyYear based - // on the current time. They'll be set to 80 years before - // the current time. - UErrorCode status = U_ZERO_ERROR; - PersianCalendar calendar(Locale("@calendar=persian"),status); - if (U_SUCCESS(status)) - { - calendar.setTime(Calendar::getNow(), status); - calendar.add(UCAL_YEAR, -80, status); - - gSystemDefaultCenturyStart = calendar.getTime(status); - gSystemDefaultCenturyStartYear = calendar.get(UCAL_YEAR, status); - } - // We have no recourse upon failure unless we want to propagate the failure - // out. -} - -UDate PersianCalendar::defaultCenturyStart() const { - // lazy-evaluate systemDefaultCenturyStart - umtx_initOnce(gSystemDefaultCenturyInit, &initializeSystemDefaultCentury); - return gSystemDefaultCenturyStart; -} - -int32_t PersianCalendar::defaultCenturyStartYear() const { - // lazy-evaluate systemDefaultCenturyStartYear - umtx_initOnce(gSystemDefaultCenturyInit, &initializeSystemDefaultCentury); - return gSystemDefaultCenturyStartYear; -} +IMPL_SYSTEM_DEFAULT_CENTURY(PersianCalendar, "@calendar=persian") UOBJECT_DEFINE_RTTI_IMPLEMENTATION(PersianCalendar) U_NAMESPACE_END #endif - |