Signed-off-by: maojunwei <maojunwei1@huawei.com>

==-------------------------------------------==
    优化GetYearFromDays(int64_t *days)函数
    issue:https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/I5K5MB?from=project-issue
   ==-------------------------------------------==
This commit is contained in:
maojunwei 2022-08-02 16:29:01 +08:00
parent a483ffdb2b
commit 6f93e31411
2 changed files with 33 additions and 17 deletions

View File

@ -78,28 +78,35 @@ int64_t DateUtils::FloorDiv(int64_t a, int64_t b)
// static
int64_t DateUtils::GetYearFromDays(int64_t *days)
{
if (isCached_ && preSumDays_ == *days) {
*days = preDays_;
return preYear_;
if (isCached_) {
int64_t t = *days;
int64_t newDays = preDays_ + (t - preSumDays_);
if (newDays >= 1 && newDays < DAYS_IN_YEAR) {
preSumDays_ = t;
*days = newDays;
preDays_ = newDays;
return preYear_;
}
}
int64_t realDay;
int64_t dayTemp = 0;
int64_t d = *days;
preSumDays_ = d;
int64_t year = FloorDiv(d * APPROXIMATION_NUMBER[0], APPROXIMATION_NUMBER[1]) + YEAR_NUMBER[0];
realDay = d - GetDaysFromYear(year);
while (realDay != 0) {
if (realDay < 0) {
year--;
} else {
dayTemp = GetDaysInYear(year);
if (realDay < dayTemp) {
break;
}
year++;
}
realDay = d - GetDaysFromYear(year);
}
d += DAYS_1970_TO_0000; // shift from 1970-01-01 to 0000-03-01
int64_t era = (d >= 0 ? d : d - DAYS_IN_400_YEARS + 1) / DAYS_IN_400_YEARS; // an era is a 400 year period
int64_t doe = static_cast<int64_t>(d - era * DAYS_IN_400_YEARS); // days of era
int64_t yoe = (doe - doe / DAYS_IN_4_YEARS + doe / DAYS_IN_100_YEARS -
doe / DAYS_IN_400_YEARS) / DAYS_IN_YEAR; // year of era
int64_t y = static_cast<int64_t>(yoe) + era * LEAP_NUMBER[2];
int64_t doy = doe - (DAYS_IN_YEAR * yoe + yoe / LEAP_NUMBER[0] -
yoe / LEAP_NUMBER[1]); // days of year
int64_t mp = (COEFFICIENT_TO_CIVIL[0] * doy + MONTH_COEFFICIENT) /
COEFFICIENT_TO_CIVIL[1]; // [0, 11] / [Mar,Feb] system
int64_t m = mp + (mp < MONTH_TRANSFORM[1] ?
MONTH_TRANSFORM[0] : MONTH_TRANSFORM[2]); // transform the month to civil system
int64_t year = y + (m <= MONTH_COEFFICIENT);
dayTemp = doy + DAYS_JAN_AND_FEB + IsLeap(year); // 03-01 is the first day of year
realDay = m > MONTH_COEFFICIENT ? dayTemp : (doy - DAYS_MAR_TO_DEC); // shift from 03-01 to 01-01
*days = realDay;
preDays_ = realDay;
preYear_ = year;

View File

@ -49,6 +49,15 @@ static constexpr int CHINA_AFTER_1901_MIN = 480;
static constexpr int CHINA_BEFORE_1901_MS = 343000;
static constexpr std::array<int, 3> LEAP_NUMBER = {4, 100, 400};
static constexpr std::array<int, 4> YEAR_NUMBER = {1970, 1969, 1901, 1601};
static constexpr int DAYS_1970_TO_0000 = 719468;
static constexpr int DAYS_IN_4_YEARS = 1460;
static constexpr int DAYS_IN_100_YEARS = 35624;
static constexpr int DAYS_IN_400_YEARS = 146097;
static constexpr int DAYS_MAR_TO_DEC = 306;
static constexpr int DAYS_JAN_AND_FEB = 59;
static constexpr int MONTH_COEFFICIENT = 2;
static constexpr std::array<int, 2> COEFFICIENT_TO_CIVIL = {5, 153};
static constexpr std::array<int, 3> MONTH_TRANSFORM = {3, 10, -9};
class DateUtils {
public: