aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/icu/i18n/persncal.cpp
diff options
context:
space:
mode:
authorromankoshelev <romankoshelev@yandex-team.com>2024-05-13 11:00:27 +0300
committerromankoshelev <romankoshelev@yandex-team.com>2024-05-13 11:13:05 +0300
commit5b22fadb0f035a3b82c328e0ae710ad2b92f6eac (patch)
treee15dc649c79c4fb78f35cd6694dfe9af9bfcc0ad /contrib/libs/icu/i18n/persncal.cpp
parent5946aa7d3cbca62f6bcf074e8a2b9346e7a96af4 (diff)
downloadydb-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.cpp117
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
-