11cb0ef41Sopenharmony_ci// © 2016 and later: Unicode, Inc. and others. 21cb0ef41Sopenharmony_ci// License & terms of use: http://www.unicode.org/copyright.html 31cb0ef41Sopenharmony_ci/* 41cb0ef41Sopenharmony_ci * Copyright (C) 2003-2014, International Business Machines Corporation 51cb0ef41Sopenharmony_ci * and others. All Rights Reserved. 61cb0ef41Sopenharmony_ci ****************************************************************************** 71cb0ef41Sopenharmony_ci * 81cb0ef41Sopenharmony_ci * File INDIANCAL.CPP 91cb0ef41Sopenharmony_ci ***************************************************************************** 101cb0ef41Sopenharmony_ci */ 111cb0ef41Sopenharmony_ci 121cb0ef41Sopenharmony_ci#include "indiancal.h" 131cb0ef41Sopenharmony_ci#include <stdlib.h> 141cb0ef41Sopenharmony_ci#if !UCONFIG_NO_FORMATTING 151cb0ef41Sopenharmony_ci 161cb0ef41Sopenharmony_ci#include "mutex.h" 171cb0ef41Sopenharmony_ci#include <float.h> 181cb0ef41Sopenharmony_ci#include "gregoimp.h" // Math 191cb0ef41Sopenharmony_ci#include "uhash.h" 201cb0ef41Sopenharmony_ci 211cb0ef41Sopenharmony_ci// Debugging 221cb0ef41Sopenharmony_ci#ifdef U_DEBUG_INDIANCAL 231cb0ef41Sopenharmony_ci#include <stdio.h> 241cb0ef41Sopenharmony_ci#include <stdarg.h> 251cb0ef41Sopenharmony_ci 261cb0ef41Sopenharmony_ci#endif 271cb0ef41Sopenharmony_ci 281cb0ef41Sopenharmony_ciU_NAMESPACE_BEGIN 291cb0ef41Sopenharmony_ci 301cb0ef41Sopenharmony_ci// Implementation of the IndianCalendar class 311cb0ef41Sopenharmony_ci 321cb0ef41Sopenharmony_ci//------------------------------------------------------------------------- 331cb0ef41Sopenharmony_ci// Constructors... 341cb0ef41Sopenharmony_ci//------------------------------------------------------------------------- 351cb0ef41Sopenharmony_ci 361cb0ef41Sopenharmony_ci 371cb0ef41Sopenharmony_ciIndianCalendar* IndianCalendar::clone() const { 381cb0ef41Sopenharmony_ci return new IndianCalendar(*this); 391cb0ef41Sopenharmony_ci} 401cb0ef41Sopenharmony_ci 411cb0ef41Sopenharmony_ciIndianCalendar::IndianCalendar(const Locale& aLocale, UErrorCode& success) 421cb0ef41Sopenharmony_ci : Calendar(TimeZone::forLocaleOrDefault(aLocale), aLocale, success) 431cb0ef41Sopenharmony_ci{ 441cb0ef41Sopenharmony_ci setTimeInMillis(getNow(), success); // Call this again now that the vtable is set up properly. 451cb0ef41Sopenharmony_ci} 461cb0ef41Sopenharmony_ci 471cb0ef41Sopenharmony_ciIndianCalendar::IndianCalendar(const IndianCalendar& other) : Calendar(other) { 481cb0ef41Sopenharmony_ci} 491cb0ef41Sopenharmony_ci 501cb0ef41Sopenharmony_ciIndianCalendar::~IndianCalendar() 511cb0ef41Sopenharmony_ci{ 521cb0ef41Sopenharmony_ci} 531cb0ef41Sopenharmony_ciconst char *IndianCalendar::getType() const { 541cb0ef41Sopenharmony_ci return "indian"; 551cb0ef41Sopenharmony_ci} 561cb0ef41Sopenharmony_ci 571cb0ef41Sopenharmony_cistatic const int32_t LIMITS[UCAL_FIELD_COUNT][4] = { 581cb0ef41Sopenharmony_ci // Minimum Greatest Least Maximum 591cb0ef41Sopenharmony_ci // Minimum Maximum 601cb0ef41Sopenharmony_ci { 0, 0, 0, 0}, // ERA 611cb0ef41Sopenharmony_ci { -5000000, -5000000, 5000000, 5000000}, // YEAR 621cb0ef41Sopenharmony_ci { 0, 0, 11, 11}, // MONTH 631cb0ef41Sopenharmony_ci { 1, 1, 52, 53}, // WEEK_OF_YEAR 641cb0ef41Sopenharmony_ci {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // WEEK_OF_MONTH 651cb0ef41Sopenharmony_ci { 1, 1, 30, 31}, // DAY_OF_MONTH 661cb0ef41Sopenharmony_ci { 1, 1, 365, 366}, // DAY_OF_YEAR 671cb0ef41Sopenharmony_ci {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // DAY_OF_WEEK 681cb0ef41Sopenharmony_ci { -1, -1, 5, 5}, // DAY_OF_WEEK_IN_MONTH 691cb0ef41Sopenharmony_ci {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // AM_PM 701cb0ef41Sopenharmony_ci {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // HOUR 711cb0ef41Sopenharmony_ci {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // HOUR_OF_DAY 721cb0ef41Sopenharmony_ci {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // MINUTE 731cb0ef41Sopenharmony_ci {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // SECOND 741cb0ef41Sopenharmony_ci {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // MILLISECOND 751cb0ef41Sopenharmony_ci {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // ZONE_OFFSET 761cb0ef41Sopenharmony_ci {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // DST_OFFSET 771cb0ef41Sopenharmony_ci { -5000000, -5000000, 5000000, 5000000}, // YEAR_WOY 781cb0ef41Sopenharmony_ci {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // DOW_LOCAL 791cb0ef41Sopenharmony_ci { -5000000, -5000000, 5000000, 5000000}, // EXTENDED_YEAR 801cb0ef41Sopenharmony_ci {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // JULIAN_DAY 811cb0ef41Sopenharmony_ci {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // MILLISECONDS_IN_DAY 821cb0ef41Sopenharmony_ci {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // IS_LEAP_MONTH 831cb0ef41Sopenharmony_ci { 0, 0, 11, 11}, // ORDINAL_MONTH 841cb0ef41Sopenharmony_ci}; 851cb0ef41Sopenharmony_ci 861cb0ef41Sopenharmony_cistatic const int32_t INDIAN_ERA_START = 78; 871cb0ef41Sopenharmony_cistatic const int32_t INDIAN_YEAR_START = 80; 881cb0ef41Sopenharmony_ci 891cb0ef41Sopenharmony_ciint32_t IndianCalendar::handleGetLimit(UCalendarDateFields field, ELimitType limitType) const { 901cb0ef41Sopenharmony_ci return LIMITS[field][limitType]; 911cb0ef41Sopenharmony_ci} 921cb0ef41Sopenharmony_ci 931cb0ef41Sopenharmony_ci/* 941cb0ef41Sopenharmony_ci * Determine whether the given gregorian year is a Leap year 951cb0ef41Sopenharmony_ci */ 961cb0ef41Sopenharmony_cistatic UBool isGregorianLeap(int32_t year) 971cb0ef41Sopenharmony_ci{ 981cb0ef41Sopenharmony_ci return Grego::isLeapYear(year); 991cb0ef41Sopenharmony_ci} 1001cb0ef41Sopenharmony_ci 1011cb0ef41Sopenharmony_ci//---------------------------------------------------------------------- 1021cb0ef41Sopenharmony_ci// Calendar framework 1031cb0ef41Sopenharmony_ci//---------------------------------------------------------------------- 1041cb0ef41Sopenharmony_ci 1051cb0ef41Sopenharmony_ci/* 1061cb0ef41Sopenharmony_ci * Return the length (in days) of the given month. 1071cb0ef41Sopenharmony_ci * 1081cb0ef41Sopenharmony_ci * @param eyear The year in Saka Era 1091cb0ef41Sopenharmony_ci * @param month The month(0-based) in Indian calendar 1101cb0ef41Sopenharmony_ci */ 1111cb0ef41Sopenharmony_ciint32_t IndianCalendar::handleGetMonthLength(int32_t eyear, int32_t month) const { 1121cb0ef41Sopenharmony_ci if (month < 0 || month > 11) { 1131cb0ef41Sopenharmony_ci eyear += ClockMath::floorDivide(month, 12, &month); 1141cb0ef41Sopenharmony_ci } 1151cb0ef41Sopenharmony_ci 1161cb0ef41Sopenharmony_ci if (isGregorianLeap(eyear + INDIAN_ERA_START) && month == 0) { 1171cb0ef41Sopenharmony_ci return 31; 1181cb0ef41Sopenharmony_ci } 1191cb0ef41Sopenharmony_ci 1201cb0ef41Sopenharmony_ci if (month >= 1 && month <= 5) { 1211cb0ef41Sopenharmony_ci return 31; 1221cb0ef41Sopenharmony_ci } 1231cb0ef41Sopenharmony_ci 1241cb0ef41Sopenharmony_ci return 30; 1251cb0ef41Sopenharmony_ci} 1261cb0ef41Sopenharmony_ci 1271cb0ef41Sopenharmony_ci/* 1281cb0ef41Sopenharmony_ci * Return the number of days in the given Indian year 1291cb0ef41Sopenharmony_ci * 1301cb0ef41Sopenharmony_ci * @param eyear The year in Saka Era. 1311cb0ef41Sopenharmony_ci */ 1321cb0ef41Sopenharmony_ciint32_t IndianCalendar::handleGetYearLength(int32_t eyear) const { 1331cb0ef41Sopenharmony_ci return isGregorianLeap(eyear + INDIAN_ERA_START) ? 366 : 365; 1341cb0ef41Sopenharmony_ci} 1351cb0ef41Sopenharmony_ci/* 1361cb0ef41Sopenharmony_ci * Returns the Julian Day corresponding to gregorian date 1371cb0ef41Sopenharmony_ci * 1381cb0ef41Sopenharmony_ci * @param year The Gregorian year 1391cb0ef41Sopenharmony_ci * @param month The month in Gregorian Year, 0 based. 1401cb0ef41Sopenharmony_ci * @param date The date in Gregorian day in month 1411cb0ef41Sopenharmony_ci */ 1421cb0ef41Sopenharmony_cistatic double gregorianToJD(int32_t year, int32_t month, int32_t date) { 1431cb0ef41Sopenharmony_ci return Grego::fieldsToDay(year, month, date) + kEpochStartAsJulianDay - 0.5; 1441cb0ef41Sopenharmony_ci} 1451cb0ef41Sopenharmony_ci 1461cb0ef41Sopenharmony_ci/* 1471cb0ef41Sopenharmony_ci * Returns the Gregorian Date corresponding to a given Julian Day 1481cb0ef41Sopenharmony_ci * Month is 0 based. 1491cb0ef41Sopenharmony_ci * @param jd The Julian Day 1501cb0ef41Sopenharmony_ci */ 1511cb0ef41Sopenharmony_cistatic int32_t* jdToGregorian(double jd, int32_t gregorianDate[3]) { 1521cb0ef41Sopenharmony_ci int32_t gdow; 1531cb0ef41Sopenharmony_ci Grego::dayToFields(jd - kEpochStartAsJulianDay, 1541cb0ef41Sopenharmony_ci gregorianDate[0], gregorianDate[1], gregorianDate[2], gdow); 1551cb0ef41Sopenharmony_ci return gregorianDate; 1561cb0ef41Sopenharmony_ci} 1571cb0ef41Sopenharmony_ci 1581cb0ef41Sopenharmony_ci 1591cb0ef41Sopenharmony_ci//------------------------------------------------------------------------- 1601cb0ef41Sopenharmony_ci// Functions for converting from field values to milliseconds.... 1611cb0ef41Sopenharmony_ci//------------------------------------------------------------------------- 1621cb0ef41Sopenharmony_cistatic double IndianToJD(int32_t year, int32_t month, int32_t date) { 1631cb0ef41Sopenharmony_ci int32_t leapMonth, gyear, m; 1641cb0ef41Sopenharmony_ci double start, jd; 1651cb0ef41Sopenharmony_ci 1661cb0ef41Sopenharmony_ci gyear = year + INDIAN_ERA_START; 1671cb0ef41Sopenharmony_ci 1681cb0ef41Sopenharmony_ci 1691cb0ef41Sopenharmony_ci if(isGregorianLeap(gyear)) { 1701cb0ef41Sopenharmony_ci leapMonth = 31; 1711cb0ef41Sopenharmony_ci start = gregorianToJD(gyear, 2 /* The third month in 0 based month */, 21); 1721cb0ef41Sopenharmony_ci } 1731cb0ef41Sopenharmony_ci else { 1741cb0ef41Sopenharmony_ci leapMonth = 30; 1751cb0ef41Sopenharmony_ci start = gregorianToJD(gyear, 2 /* The third month in 0 based month */, 22); 1761cb0ef41Sopenharmony_ci } 1771cb0ef41Sopenharmony_ci 1781cb0ef41Sopenharmony_ci if (month == 1) { 1791cb0ef41Sopenharmony_ci jd = start + (date - 1); 1801cb0ef41Sopenharmony_ci } else { 1811cb0ef41Sopenharmony_ci jd = start + leapMonth; 1821cb0ef41Sopenharmony_ci m = month - 2; 1831cb0ef41Sopenharmony_ci 1841cb0ef41Sopenharmony_ci //m = Math.min(m, 5); 1851cb0ef41Sopenharmony_ci if (m > 5) { 1861cb0ef41Sopenharmony_ci m = 5; 1871cb0ef41Sopenharmony_ci } 1881cb0ef41Sopenharmony_ci 1891cb0ef41Sopenharmony_ci jd += m * 31; 1901cb0ef41Sopenharmony_ci 1911cb0ef41Sopenharmony_ci if (month >= 8) { 1921cb0ef41Sopenharmony_ci m = month - 7; 1931cb0ef41Sopenharmony_ci jd += m * 30; 1941cb0ef41Sopenharmony_ci } 1951cb0ef41Sopenharmony_ci jd += date - 1; 1961cb0ef41Sopenharmony_ci } 1971cb0ef41Sopenharmony_ci 1981cb0ef41Sopenharmony_ci return jd; 1991cb0ef41Sopenharmony_ci} 2001cb0ef41Sopenharmony_ci 2011cb0ef41Sopenharmony_ci/* 2021cb0ef41Sopenharmony_ci * Return JD of start of given month/year of Indian Calendar 2031cb0ef41Sopenharmony_ci * @param eyear The year in Indian Calendar measured from Saka Era (78 AD). 2041cb0ef41Sopenharmony_ci * @param month The month in Indian calendar 2051cb0ef41Sopenharmony_ci */ 2061cb0ef41Sopenharmony_ciint32_t IndianCalendar::handleComputeMonthStart(int32_t eyear, int32_t month, UBool /* useMonth */ ) const { 2071cb0ef41Sopenharmony_ci 2081cb0ef41Sopenharmony_ci //month is 0 based; converting it to 1-based 2091cb0ef41Sopenharmony_ci int32_t imonth; 2101cb0ef41Sopenharmony_ci 2111cb0ef41Sopenharmony_ci // If the month is out of range, adjust it into range, and adjust the extended year accordingly 2121cb0ef41Sopenharmony_ci if (month < 0 || month > 11) { 2131cb0ef41Sopenharmony_ci eyear += (int32_t)ClockMath::floorDivide(month, 12, &month); 2141cb0ef41Sopenharmony_ci } 2151cb0ef41Sopenharmony_ci 2161cb0ef41Sopenharmony_ci if(month == 12){ 2171cb0ef41Sopenharmony_ci imonth = 1; 2181cb0ef41Sopenharmony_ci } else { 2191cb0ef41Sopenharmony_ci imonth = month + 1; 2201cb0ef41Sopenharmony_ci } 2211cb0ef41Sopenharmony_ci 2221cb0ef41Sopenharmony_ci double jd = IndianToJD(eyear ,imonth, 1); 2231cb0ef41Sopenharmony_ci 2241cb0ef41Sopenharmony_ci return (int32_t)jd; 2251cb0ef41Sopenharmony_ci} 2261cb0ef41Sopenharmony_ci 2271cb0ef41Sopenharmony_ci//------------------------------------------------------------------------- 2281cb0ef41Sopenharmony_ci// Functions for converting from milliseconds to field values 2291cb0ef41Sopenharmony_ci//------------------------------------------------------------------------- 2301cb0ef41Sopenharmony_ci 2311cb0ef41Sopenharmony_ciint32_t IndianCalendar::handleGetExtendedYear() { 2321cb0ef41Sopenharmony_ci int32_t year; 2331cb0ef41Sopenharmony_ci 2341cb0ef41Sopenharmony_ci if (newerField(UCAL_EXTENDED_YEAR, UCAL_YEAR) == UCAL_EXTENDED_YEAR) { 2351cb0ef41Sopenharmony_ci year = internalGet(UCAL_EXTENDED_YEAR, 1); // Default to year 1 2361cb0ef41Sopenharmony_ci } else { 2371cb0ef41Sopenharmony_ci year = internalGet(UCAL_YEAR, 1); // Default to year 1 2381cb0ef41Sopenharmony_ci } 2391cb0ef41Sopenharmony_ci 2401cb0ef41Sopenharmony_ci return year; 2411cb0ef41Sopenharmony_ci} 2421cb0ef41Sopenharmony_ci 2431cb0ef41Sopenharmony_ci/* 2441cb0ef41Sopenharmony_ci * Override Calendar to compute several fields specific to the Indian 2451cb0ef41Sopenharmony_ci * calendar system. These are: 2461cb0ef41Sopenharmony_ci * 2471cb0ef41Sopenharmony_ci * <ul><li>ERA 2481cb0ef41Sopenharmony_ci * <li>YEAR 2491cb0ef41Sopenharmony_ci * <li>MONTH 2501cb0ef41Sopenharmony_ci * <li>DAY_OF_MONTH 2511cb0ef41Sopenharmony_ci * <li>EXTENDED_YEAR</ul> 2521cb0ef41Sopenharmony_ci * 2531cb0ef41Sopenharmony_ci * The DAY_OF_WEEK and DOW_LOCAL fields are already set when this 2541cb0ef41Sopenharmony_ci * method is called. The getGregorianXxx() methods return Gregorian 2551cb0ef41Sopenharmony_ci * calendar equivalents for the given Julian day. 2561cb0ef41Sopenharmony_ci */ 2571cb0ef41Sopenharmony_civoid IndianCalendar::handleComputeFields(int32_t julianDay, UErrorCode& /* status */) { 2581cb0ef41Sopenharmony_ci double jdAtStartOfGregYear; 2591cb0ef41Sopenharmony_ci int32_t leapMonth, IndianYear, yday, IndianMonth, IndianDayOfMonth, mday; 2601cb0ef41Sopenharmony_ci int32_t gregorianYear; // Stores gregorian date corresponding to Julian day; 2611cb0ef41Sopenharmony_ci int32_t gd[3]; 2621cb0ef41Sopenharmony_ci 2631cb0ef41Sopenharmony_ci gregorianYear = jdToGregorian(julianDay, gd)[0]; // Gregorian date for Julian day 2641cb0ef41Sopenharmony_ci IndianYear = gregorianYear - INDIAN_ERA_START; // Year in Saka era 2651cb0ef41Sopenharmony_ci jdAtStartOfGregYear = gregorianToJD(gregorianYear, 0, 1); // JD at start of Gregorian year 2661cb0ef41Sopenharmony_ci yday = (int32_t)(julianDay - jdAtStartOfGregYear); // Day number in Gregorian year (starting from 0) 2671cb0ef41Sopenharmony_ci 2681cb0ef41Sopenharmony_ci if (yday < INDIAN_YEAR_START) { 2691cb0ef41Sopenharmony_ci // Day is at the end of the preceding Saka year 2701cb0ef41Sopenharmony_ci IndianYear -= 1; 2711cb0ef41Sopenharmony_ci leapMonth = isGregorianLeap(gregorianYear - 1) ? 31 : 30; // Days in leapMonth this year, previous Gregorian year 2721cb0ef41Sopenharmony_ci yday += leapMonth + (31 * 5) + (30 * 3) + 10; 2731cb0ef41Sopenharmony_ci } else { 2741cb0ef41Sopenharmony_ci leapMonth = isGregorianLeap(gregorianYear) ? 31 : 30; // Days in leapMonth this year 2751cb0ef41Sopenharmony_ci yday -= INDIAN_YEAR_START; 2761cb0ef41Sopenharmony_ci } 2771cb0ef41Sopenharmony_ci 2781cb0ef41Sopenharmony_ci if (yday < leapMonth) { 2791cb0ef41Sopenharmony_ci IndianMonth = 0; 2801cb0ef41Sopenharmony_ci IndianDayOfMonth = yday + 1; 2811cb0ef41Sopenharmony_ci } else { 2821cb0ef41Sopenharmony_ci mday = yday - leapMonth; 2831cb0ef41Sopenharmony_ci if (mday < (31 * 5)) { 2841cb0ef41Sopenharmony_ci IndianMonth = (int32_t)uprv_floor(mday / 31) + 1; 2851cb0ef41Sopenharmony_ci IndianDayOfMonth = (mday % 31) + 1; 2861cb0ef41Sopenharmony_ci } else { 2871cb0ef41Sopenharmony_ci mday -= 31 * 5; 2881cb0ef41Sopenharmony_ci IndianMonth = (int32_t)uprv_floor(mday / 30) + 6; 2891cb0ef41Sopenharmony_ci IndianDayOfMonth = (mday % 30) + 1; 2901cb0ef41Sopenharmony_ci } 2911cb0ef41Sopenharmony_ci } 2921cb0ef41Sopenharmony_ci 2931cb0ef41Sopenharmony_ci internalSet(UCAL_ERA, 0); 2941cb0ef41Sopenharmony_ci internalSet(UCAL_EXTENDED_YEAR, IndianYear); 2951cb0ef41Sopenharmony_ci internalSet(UCAL_YEAR, IndianYear); 2961cb0ef41Sopenharmony_ci internalSet(UCAL_MONTH, IndianMonth); 2971cb0ef41Sopenharmony_ci internalSet(UCAL_ORDINAL_MONTH, IndianMonth); 2981cb0ef41Sopenharmony_ci internalSet(UCAL_DAY_OF_MONTH, IndianDayOfMonth); 2991cb0ef41Sopenharmony_ci internalSet(UCAL_DAY_OF_YEAR, yday + 1); // yday is 0-based 3001cb0ef41Sopenharmony_ci} 3011cb0ef41Sopenharmony_ci 3021cb0ef41Sopenharmony_ciconstexpr uint32_t kIndianRelatedYearDiff = 79; 3031cb0ef41Sopenharmony_ci 3041cb0ef41Sopenharmony_ciint32_t IndianCalendar::getRelatedYear(UErrorCode &status) const 3051cb0ef41Sopenharmony_ci{ 3061cb0ef41Sopenharmony_ci int32_t year = get(UCAL_EXTENDED_YEAR, status); 3071cb0ef41Sopenharmony_ci if (U_FAILURE(status)) { 3081cb0ef41Sopenharmony_ci return 0; 3091cb0ef41Sopenharmony_ci } 3101cb0ef41Sopenharmony_ci return year + kIndianRelatedYearDiff; 3111cb0ef41Sopenharmony_ci} 3121cb0ef41Sopenharmony_ci 3131cb0ef41Sopenharmony_civoid IndianCalendar::setRelatedYear(int32_t year) 3141cb0ef41Sopenharmony_ci{ 3151cb0ef41Sopenharmony_ci // set extended year 3161cb0ef41Sopenharmony_ci set(UCAL_EXTENDED_YEAR, year - kIndianRelatedYearDiff); 3171cb0ef41Sopenharmony_ci} 3181cb0ef41Sopenharmony_ci 3191cb0ef41Sopenharmony_ci/** 3201cb0ef41Sopenharmony_ci * The system maintains a static default century start date and Year. They are 3211cb0ef41Sopenharmony_ci * initialized the first time they are used. Once the system default century date 3221cb0ef41Sopenharmony_ci * and year are set, they do not change. 3231cb0ef41Sopenharmony_ci */ 3241cb0ef41Sopenharmony_cistatic UDate gSystemDefaultCenturyStart = DBL_MIN; 3251cb0ef41Sopenharmony_cistatic int32_t gSystemDefaultCenturyStartYear = -1; 3261cb0ef41Sopenharmony_cistatic icu::UInitOnce gSystemDefaultCenturyInit {}; 3271cb0ef41Sopenharmony_ci 3281cb0ef41Sopenharmony_ci 3291cb0ef41Sopenharmony_ciUBool IndianCalendar::haveDefaultCentury() const 3301cb0ef41Sopenharmony_ci{ 3311cb0ef41Sopenharmony_ci return true; 3321cb0ef41Sopenharmony_ci} 3331cb0ef41Sopenharmony_ci 3341cb0ef41Sopenharmony_cistatic void U_CALLCONV 3351cb0ef41Sopenharmony_ciinitializeSystemDefaultCentury() 3361cb0ef41Sopenharmony_ci{ 3371cb0ef41Sopenharmony_ci // initialize systemDefaultCentury and systemDefaultCenturyYear based 3381cb0ef41Sopenharmony_ci // on the current time. They'll be set to 80 years before 3391cb0ef41Sopenharmony_ci // the current time. 3401cb0ef41Sopenharmony_ci UErrorCode status = U_ZERO_ERROR; 3411cb0ef41Sopenharmony_ci 3421cb0ef41Sopenharmony_ci IndianCalendar calendar ( Locale ( "@calendar=Indian" ), status); 3431cb0ef41Sopenharmony_ci if ( U_SUCCESS ( status ) ) { 3441cb0ef41Sopenharmony_ci calendar.setTime ( Calendar::getNow(), status ); 3451cb0ef41Sopenharmony_ci calendar.add ( UCAL_YEAR, -80, status ); 3461cb0ef41Sopenharmony_ci 3471cb0ef41Sopenharmony_ci UDate newStart = calendar.getTime ( status ); 3481cb0ef41Sopenharmony_ci int32_t newYear = calendar.get ( UCAL_YEAR, status ); 3491cb0ef41Sopenharmony_ci 3501cb0ef41Sopenharmony_ci gSystemDefaultCenturyStart = newStart; 3511cb0ef41Sopenharmony_ci gSystemDefaultCenturyStartYear = newYear; 3521cb0ef41Sopenharmony_ci } 3531cb0ef41Sopenharmony_ci // We have no recourse upon failure. 3541cb0ef41Sopenharmony_ci} 3551cb0ef41Sopenharmony_ci 3561cb0ef41Sopenharmony_ci 3571cb0ef41Sopenharmony_ciUDate 3581cb0ef41Sopenharmony_ciIndianCalendar::defaultCenturyStart() const 3591cb0ef41Sopenharmony_ci{ 3601cb0ef41Sopenharmony_ci // lazy-evaluate systemDefaultCenturyStart 3611cb0ef41Sopenharmony_ci umtx_initOnce(gSystemDefaultCenturyInit, &initializeSystemDefaultCentury); 3621cb0ef41Sopenharmony_ci return gSystemDefaultCenturyStart; 3631cb0ef41Sopenharmony_ci} 3641cb0ef41Sopenharmony_ci 3651cb0ef41Sopenharmony_ciint32_t 3661cb0ef41Sopenharmony_ciIndianCalendar::defaultCenturyStartYear() const 3671cb0ef41Sopenharmony_ci{ 3681cb0ef41Sopenharmony_ci // lazy-evaluate systemDefaultCenturyStartYear 3691cb0ef41Sopenharmony_ci umtx_initOnce(gSystemDefaultCenturyInit, &initializeSystemDefaultCentury); 3701cb0ef41Sopenharmony_ci return gSystemDefaultCenturyStartYear; 3711cb0ef41Sopenharmony_ci} 3721cb0ef41Sopenharmony_ci 3731cb0ef41Sopenharmony_ci 3741cb0ef41Sopenharmony_ciUOBJECT_DEFINE_RTTI_IMPLEMENTATION(IndianCalendar) 3751cb0ef41Sopenharmony_ci 3761cb0ef41Sopenharmony_ciU_NAMESPACE_END 3771cb0ef41Sopenharmony_ci 3781cb0ef41Sopenharmony_ci#endif 3791cb0ef41Sopenharmony_ci 380