14514f5e3Sopenharmony_ci/* 24514f5e3Sopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd. 34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License. 54514f5e3Sopenharmony_ci * You may obtain a copy of the License at 64514f5e3Sopenharmony_ci * 74514f5e3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 84514f5e3Sopenharmony_ci * 94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and 134514f5e3Sopenharmony_ci * limitations under the License. 144514f5e3Sopenharmony_ci */ 154514f5e3Sopenharmony_ci 164514f5e3Sopenharmony_ci#include "ecmascript/js_date.h" 174514f5e3Sopenharmony_ci 184514f5e3Sopenharmony_ci#include <ctime> 194514f5e3Sopenharmony_ci#include <regex> 204514f5e3Sopenharmony_ci#include <sys/time.h> 214514f5e3Sopenharmony_ci 224514f5e3Sopenharmony_ci#include "ecmascript/date_parse.h" 234514f5e3Sopenharmony_ci#include "ecmascript/object_fast_operator-inl.h" 244514f5e3Sopenharmony_ci#include "ecmascript/platform/time.h" 254514f5e3Sopenharmony_ci 264514f5e3Sopenharmony_cinamespace panda::ecmascript { 274514f5e3Sopenharmony_ciusing NumberHelper = base::NumberHelper; 284514f5e3Sopenharmony_cibool DateUtils::isCached_ = false; 294514f5e3Sopenharmony_ciint DateUtils::preSumDays_ = 0; 304514f5e3Sopenharmony_ciint DateUtils::preDays_ = 0; 314514f5e3Sopenharmony_ciint DateUtils::preMonth_ = 0; 324514f5e3Sopenharmony_ciint DateUtils::preYear_ = 0; 334514f5e3Sopenharmony_cistatic const std::array<CString, WEEKDAY> WEEK_DAY_NAME = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; 344514f5e3Sopenharmony_cistatic const std::array<CString, MOUTH_PER_YEAR> MONTH_NAME = { 354514f5e3Sopenharmony_ci "Jan", "Feb", "Mar", "Apr", "May", "Jun", 364514f5e3Sopenharmony_ci "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" 374514f5e3Sopenharmony_ci}; 384514f5e3Sopenharmony_civoid DateUtils::TransferTimeToDate(int64_t timeMs, std::array<int64_t, DATE_LENGTH> *date) 394514f5e3Sopenharmony_ci{ 404514f5e3Sopenharmony_ci (*date)[HOUR] = Mod(timeMs, MS_PER_DAY); // ms from hour, minutes, second, ms 414514f5e3Sopenharmony_ci (*date)[DAYS] = (timeMs - (*date)[HOUR]) / MS_PER_DAY; // days from year, month, day 424514f5e3Sopenharmony_ci (*date)[MS] = (*date)[HOUR] % MS_PER_SECOND; // ms 434514f5e3Sopenharmony_ci (*date)[HOUR] = ((*date)[HOUR] - (*date)[MS]) / MS_PER_SECOND; // s from hour, minutes, second 444514f5e3Sopenharmony_ci (*date)[SEC] = (*date)[HOUR] % SEC_PER_MINUTE; // second 454514f5e3Sopenharmony_ci (*date)[HOUR] = ((*date)[HOUR] - (*date)[SEC]) / SEC_PER_MINUTE; // min from hour, minutes 464514f5e3Sopenharmony_ci (*date)[MIN] = (*date)[HOUR] % SEC_PER_MINUTE; // min 474514f5e3Sopenharmony_ci (*date)[HOUR] = ((*date)[HOUR] - (*date)[MIN]) / SEC_PER_MINUTE; // hour 484514f5e3Sopenharmony_ci (*date)[WEEKDAY] = Mod(((*date)[DAYS] + LEAP_NUMBER[0]), DAY_PER_WEEK); // weekday 494514f5e3Sopenharmony_ci GetYearFromDays(date); 504514f5e3Sopenharmony_ci} 514514f5e3Sopenharmony_ci// static 524514f5e3Sopenharmony_cibool DateUtils::IsLeap(int64_t year) 534514f5e3Sopenharmony_ci{ 544514f5e3Sopenharmony_ci return year % LEAP_NUMBER[0] == 0 && (year % LEAP_NUMBER[1] != 0 || year % LEAP_NUMBER[2] == 0); // 2: means index 554514f5e3Sopenharmony_ci} 564514f5e3Sopenharmony_ci 574514f5e3Sopenharmony_ci// static 584514f5e3Sopenharmony_ciint64_t DateUtils::GetDaysInYear(int64_t year) 594514f5e3Sopenharmony_ci{ 604514f5e3Sopenharmony_ci int64_t number; 614514f5e3Sopenharmony_ci number = IsLeap(year) ? (DAYS_IN_YEAR + 1) : DAYS_IN_YEAR; 624514f5e3Sopenharmony_ci return number; 634514f5e3Sopenharmony_ci} 644514f5e3Sopenharmony_ci 654514f5e3Sopenharmony_ci// static 664514f5e3Sopenharmony_ciint64_t DateUtils::GetDaysFromYear(int64_t year) 674514f5e3Sopenharmony_ci{ 684514f5e3Sopenharmony_ci return DAYS_IN_YEAR * (year - YEAR_NUMBER[0]) + FloorDiv(year - YEAR_NUMBER[1], LEAP_NUMBER[0]) - 694514f5e3Sopenharmony_ci FloorDiv(year - YEAR_NUMBER[2], LEAP_NUMBER[1]) + // 2: year index 704514f5e3Sopenharmony_ci FloorDiv(year - YEAR_NUMBER[3], LEAP_NUMBER[2]); // 3, 2: year index 714514f5e3Sopenharmony_ci} 724514f5e3Sopenharmony_ci 734514f5e3Sopenharmony_ci// static 744514f5e3Sopenharmony_ciint64_t DateUtils::FloorDiv(int64_t a, int64_t b) 754514f5e3Sopenharmony_ci{ 764514f5e3Sopenharmony_ci ASSERT(b != 0); 774514f5e3Sopenharmony_ci int64_t m = a % b; 784514f5e3Sopenharmony_ci int64_t res = m < 0 ? ((a - m - b) / b) : ((a - m) / b); 794514f5e3Sopenharmony_ci return res; 804514f5e3Sopenharmony_ci} 814514f5e3Sopenharmony_ci 824514f5e3Sopenharmony_ci// static 834514f5e3Sopenharmony_civoid DateUtils::GetYearFromDays(std::array<int64_t, DATE_LENGTH> *date) 844514f5e3Sopenharmony_ci{ 854514f5e3Sopenharmony_ci if (date == nullptr) { 864514f5e3Sopenharmony_ci return; 874514f5e3Sopenharmony_ci } 884514f5e3Sopenharmony_ci if (isCached_) { 894514f5e3Sopenharmony_ci int64_t t = (*date)[DAYS]; 904514f5e3Sopenharmony_ci int64_t newDays = preDays_ + (t - preSumDays_); 914514f5e3Sopenharmony_ci if (newDays >= 1 && newDays < DAYS_FEBRUARY) { 924514f5e3Sopenharmony_ci preSumDays_ = t; 934514f5e3Sopenharmony_ci preDays_ = newDays; 944514f5e3Sopenharmony_ci (*date)[DAYS] = newDays; 954514f5e3Sopenharmony_ci (*date)[MONTH] = preMonth_; 964514f5e3Sopenharmony_ci (*date)[YEAR] = preYear_; 974514f5e3Sopenharmony_ci return; 984514f5e3Sopenharmony_ci } 994514f5e3Sopenharmony_ci } 1004514f5e3Sopenharmony_ci int64_t realDay; 1014514f5e3Sopenharmony_ci int64_t d = (*date)[DAYS]; 1024514f5e3Sopenharmony_ci preSumDays_ = d; 1034514f5e3Sopenharmony_ci d += DAYS_1970_TO_0000; // shift from 1970-01-01 to 0000-03-01 1044514f5e3Sopenharmony_ci int64_t era = (d >= 0 ? d : d - DAYS_IN_400_YEARS + 1) / DAYS_IN_400_YEARS; // an era is a 400 year period 1054514f5e3Sopenharmony_ci int64_t doe = static_cast<int64_t>(d - era * DAYS_IN_400_YEARS); // days of era 1064514f5e3Sopenharmony_ci int64_t yoe = (doe - doe / DAYS_IN_4_YEARS + doe / DAYS_IN_100_YEARS - 1074514f5e3Sopenharmony_ci doe / (DAYS_IN_400_YEARS - 1)) / DAYS_IN_YEAR; // year of era 1084514f5e3Sopenharmony_ci int64_t y = static_cast<int64_t>(yoe) + era * LEAP_NUMBER[2]; 1094514f5e3Sopenharmony_ci int64_t doy = doe - (DAYS_IN_YEAR * yoe + yoe / LEAP_NUMBER[0] - 1104514f5e3Sopenharmony_ci yoe / LEAP_NUMBER[1]); // days of year 1114514f5e3Sopenharmony_ci int64_t mp = (COEFFICIENT_TO_CIVIL[0] * doy + MONTH_COEFFICIENT) / 1124514f5e3Sopenharmony_ci COEFFICIENT_TO_CIVIL[1]; // [0, 11] / [Mar,Feb] system 1134514f5e3Sopenharmony_ci int64_t month = mp + (mp < MONTH_TRANSFORM[1] ? 1144514f5e3Sopenharmony_ci MONTH_TRANSFORM[0] : MONTH_TRANSFORM[2]); // transform month to civil system 1154514f5e3Sopenharmony_ci int64_t year = y + (month <= MONTH_COEFFICIENT); 1164514f5e3Sopenharmony_ci month -= 1; 1174514f5e3Sopenharmony_ci realDay = doy - (COEFFICIENT_TO_CIVIL[1] * mp + 2) / COEFFICIENT_TO_CIVIL[0] + 1; // 2: shift from 03-01 to 01-01 1184514f5e3Sopenharmony_ci (*date)[YEAR] = year; 1194514f5e3Sopenharmony_ci (*date)[MONTH] = month; 1204514f5e3Sopenharmony_ci (*date)[DAYS] = realDay; 1214514f5e3Sopenharmony_ci preDays_ = realDay; 1224514f5e3Sopenharmony_ci preMonth_ = month; 1234514f5e3Sopenharmony_ci preYear_ = year; 1244514f5e3Sopenharmony_ci isCached_ = true; 1254514f5e3Sopenharmony_ci} 1264514f5e3Sopenharmony_ci 1274514f5e3Sopenharmony_ci// static 1284514f5e3Sopenharmony_ciint64_t DateUtils::Mod(int64_t a, int b) 1294514f5e3Sopenharmony_ci{ 1304514f5e3Sopenharmony_ci ASSERT(b != 0); 1314514f5e3Sopenharmony_ci int64_t m = a % b; 1324514f5e3Sopenharmony_ci int64_t res = m < 0 ? (m + b) : m; 1334514f5e3Sopenharmony_ci return res; 1344514f5e3Sopenharmony_ci} 1354514f5e3Sopenharmony_ci 1364514f5e3Sopenharmony_ci// static 1374514f5e3Sopenharmony_ci// 20.4.1.11 1384514f5e3Sopenharmony_cidouble JSDate::MakeTime(double hour, double min, double sec, double ms) 1394514f5e3Sopenharmony_ci{ 1404514f5e3Sopenharmony_ci if (std::isfinite(hour) && std::isfinite(min) && std::isfinite(sec) && std::isfinite(ms)) { 1414514f5e3Sopenharmony_ci double hourInteger = NumberHelper::TruncateDouble(hour); 1424514f5e3Sopenharmony_ci double minInteger = NumberHelper::TruncateDouble(min); 1434514f5e3Sopenharmony_ci double secInteger = NumberHelper::TruncateDouble(sec); 1444514f5e3Sopenharmony_ci double msInteger = NumberHelper::TruncateDouble(ms); 1454514f5e3Sopenharmony_ci return hourInteger * MS_PER_HOUR + minInteger * MS_PER_MINUTE + secInteger * MS_PER_SECOND + msInteger; 1464514f5e3Sopenharmony_ci } 1474514f5e3Sopenharmony_ci return base::NAN_VALUE; 1484514f5e3Sopenharmony_ci} 1494514f5e3Sopenharmony_ci 1504514f5e3Sopenharmony_ci// static 1514514f5e3Sopenharmony_ci// 20.4.1.12 1524514f5e3Sopenharmony_cidouble JSDate::MakeDay(double year, double month, double date) 1534514f5e3Sopenharmony_ci{ 1544514f5e3Sopenharmony_ci if (std::isfinite(year) && std::isfinite(month) && std::isfinite(date)) { 1554514f5e3Sopenharmony_ci double yearInteger = NumberHelper::TruncateDouble(year); 1564514f5e3Sopenharmony_ci double monthInteger = NumberHelper::TruncateDouble(month); 1574514f5e3Sopenharmony_ci int64_t y = static_cast<int64_t>(yearInteger) + static_cast<int64_t>(monthInteger / MOUTH_PER_YEAR); 1584514f5e3Sopenharmony_ci int64_t m = static_cast<int64_t>(monthInteger) % MOUTH_PER_YEAR; 1594514f5e3Sopenharmony_ci if (m < 0) { 1604514f5e3Sopenharmony_ci m += MOUTH_PER_YEAR; 1614514f5e3Sopenharmony_ci y -= 1; 1624514f5e3Sopenharmony_ci } 1634514f5e3Sopenharmony_ci 1644514f5e3Sopenharmony_ci int64_t days = DateUtils::GetDaysFromYear(y); 1654514f5e3Sopenharmony_ci int index = DateUtils::IsLeap(year) ? 1 : 0; 1664514f5e3Sopenharmony_ci days += DAYS_FROM_MONTH[index][m]; 1674514f5e3Sopenharmony_ci return static_cast<double>(days - 1) + NumberHelper::TruncateDouble(date); 1684514f5e3Sopenharmony_ci } 1694514f5e3Sopenharmony_ci return base::NAN_VALUE; 1704514f5e3Sopenharmony_ci} 1714514f5e3Sopenharmony_ci 1724514f5e3Sopenharmony_ci// static 1734514f5e3Sopenharmony_ci// 20.4.1.13 1744514f5e3Sopenharmony_cidouble JSDate::MakeDate(double day, double time) 1754514f5e3Sopenharmony_ci{ 1764514f5e3Sopenharmony_ci if (std::isfinite(day) && std::isfinite(time)) { 1774514f5e3Sopenharmony_ci return time + day * MS_PER_DAY; 1784514f5e3Sopenharmony_ci } 1794514f5e3Sopenharmony_ci return base::NAN_VALUE; 1804514f5e3Sopenharmony_ci} 1814514f5e3Sopenharmony_ci 1824514f5e3Sopenharmony_ci// static 1834514f5e3Sopenharmony_ci// 20.4.1.14 1844514f5e3Sopenharmony_cidouble JSDate::TimeClip(double time) 1854514f5e3Sopenharmony_ci{ 1864514f5e3Sopenharmony_ci if (-MAX_TIME_IN_MS <= time && time <= MAX_TIME_IN_MS) { 1874514f5e3Sopenharmony_ci return NumberHelper::TruncateDouble(time); 1884514f5e3Sopenharmony_ci } 1894514f5e3Sopenharmony_ci return base::NAN_VALUE; 1904514f5e3Sopenharmony_ci} 1914514f5e3Sopenharmony_ci 1924514f5e3Sopenharmony_ci// 20.4.1.8 1934514f5e3Sopenharmony_cidouble JSDate::LocalTime(double timeMs) const 1944514f5e3Sopenharmony_ci{ 1954514f5e3Sopenharmony_ci return timeMs + GetLocalOffsetFromOS(timeMs, true); 1964514f5e3Sopenharmony_ci} 1974514f5e3Sopenharmony_ci 1984514f5e3Sopenharmony_ci// 20.4.1.9 1994514f5e3Sopenharmony_cidouble JSDate::UTCTime(double timeMs) const 2004514f5e3Sopenharmony_ci{ 2014514f5e3Sopenharmony_ci return timeMs - GetLocalOffsetFromOS(timeMs, false); 2024514f5e3Sopenharmony_ci} 2034514f5e3Sopenharmony_ci 2044514f5e3Sopenharmony_ci// static 2054514f5e3Sopenharmony_ciint JSDate::GetSignedNumFromString(const CString &str, int len, int *index) 2064514f5e3Sopenharmony_ci{ 2074514f5e3Sopenharmony_ci int res = 0; 2084514f5e3Sopenharmony_ci GetNumFromString(str, len, index, &res); 2094514f5e3Sopenharmony_ci if (str.at(0) == NEG) { 2104514f5e3Sopenharmony_ci return -res; 2114514f5e3Sopenharmony_ci } 2124514f5e3Sopenharmony_ci return res; 2134514f5e3Sopenharmony_ci} 2144514f5e3Sopenharmony_ci 2154514f5e3Sopenharmony_ci// static 2164514f5e3Sopenharmony_cibool JSDate::GetNumFromString(const CString &str, int len, int *index, int *num) 2174514f5e3Sopenharmony_ci{ 2184514f5e3Sopenharmony_ci int indexStr = *index; 2194514f5e3Sopenharmony_ci char oneByte = 0; 2204514f5e3Sopenharmony_ci while (indexStr < len) { 2214514f5e3Sopenharmony_ci oneByte = str.at(indexStr); 2224514f5e3Sopenharmony_ci if (oneByte >= '0' && oneByte <= '9') { 2234514f5e3Sopenharmony_ci break; 2244514f5e3Sopenharmony_ci } 2254514f5e3Sopenharmony_ci indexStr++; 2264514f5e3Sopenharmony_ci } 2274514f5e3Sopenharmony_ci if (indexStr >= len) { 2284514f5e3Sopenharmony_ci return false; 2294514f5e3Sopenharmony_ci } 2304514f5e3Sopenharmony_ci int value = 0; 2314514f5e3Sopenharmony_ci while (indexStr < len) { 2324514f5e3Sopenharmony_ci oneByte = str.at(indexStr); 2334514f5e3Sopenharmony_ci int val = static_cast<int>(oneByte - '0'); 2344514f5e3Sopenharmony_ci if (val >= 0 && val <= NUM_NINE) { 2354514f5e3Sopenharmony_ci value = value * TEN + val; 2364514f5e3Sopenharmony_ci indexStr++; 2374514f5e3Sopenharmony_ci } else { 2384514f5e3Sopenharmony_ci break; 2394514f5e3Sopenharmony_ci } 2404514f5e3Sopenharmony_ci } 2414514f5e3Sopenharmony_ci *num = value; 2424514f5e3Sopenharmony_ci *index = indexStr; 2434514f5e3Sopenharmony_ci return true; 2444514f5e3Sopenharmony_ci} 2454514f5e3Sopenharmony_ci 2464514f5e3Sopenharmony_ci// 20.4.1.7 2474514f5e3Sopenharmony_ciint64_t JSDate::GetLocalOffsetInMin(const JSThread *thread, int64_t timeMs, bool isLocal) 2484514f5e3Sopenharmony_ci{ 2494514f5e3Sopenharmony_ci if (!isLocal) { 2504514f5e3Sopenharmony_ci return 0; 2514514f5e3Sopenharmony_ci } 2524514f5e3Sopenharmony_ci double localOffset = this->GetLocalOffset().GetDouble(); 2534514f5e3Sopenharmony_ci if (localOffset == MAX_DOUBLE) { 2544514f5e3Sopenharmony_ci localOffset = static_cast<double>(GetLocalOffsetFromOS(timeMs, isLocal)); 2554514f5e3Sopenharmony_ci SetLocalOffset(thread, JSTaggedValue(localOffset)); 2564514f5e3Sopenharmony_ci } 2574514f5e3Sopenharmony_ci return localOffset; 2584514f5e3Sopenharmony_ci} 2594514f5e3Sopenharmony_ci 2604514f5e3Sopenharmony_ci// static 2614514f5e3Sopenharmony_ciJSTaggedValue JSDate::LocalParseStringToMs(const CString &str) 2624514f5e3Sopenharmony_ci{ 2634514f5e3Sopenharmony_ci int year = 0; 2644514f5e3Sopenharmony_ci int month = 0; 2654514f5e3Sopenharmony_ci int date = 1; 2664514f5e3Sopenharmony_ci int hours = 0; 2674514f5e3Sopenharmony_ci int minutes = 0; 2684514f5e3Sopenharmony_ci int seconds = 0; 2694514f5e3Sopenharmony_ci int ms = 0; 2704514f5e3Sopenharmony_ci int index = 0; 2714514f5e3Sopenharmony_ci int len = static_cast<int>(str.length()); 2724514f5e3Sopenharmony_ci bool isLocal = false; 2734514f5e3Sopenharmony_ci CString::size_type indexGmt; 2744514f5e3Sopenharmony_ci CString::size_type indexPlus = CString::npos; 2754514f5e3Sopenharmony_ci int localTime = 0; 2764514f5e3Sopenharmony_ci int localHours = 0; 2774514f5e3Sopenharmony_ci int localMinutes = 0; 2784514f5e3Sopenharmony_ci int64_t localMs = 0; 2794514f5e3Sopenharmony_ci CString::size_type localSpace; 2804514f5e3Sopenharmony_ci localSpace = str.find(' ', index); 2814514f5e3Sopenharmony_ci CString strMonth = str.substr(localSpace + 1, LENGTH_MONTH_NAME); 2824514f5e3Sopenharmony_ci for (int i = 0; i < MOUTH_PER_YEAR; i++) { 2834514f5e3Sopenharmony_ci if (strMonth == MONTH_NAME[i]) { 2844514f5e3Sopenharmony_ci month = i; 2854514f5e3Sopenharmony_ci break; 2864514f5e3Sopenharmony_ci } 2874514f5e3Sopenharmony_ci } 2884514f5e3Sopenharmony_ci index += (LENGTH_MONTH_NAME + 1); 2894514f5e3Sopenharmony_ci GetNumFromString(str, len, &index, &date); 2904514f5e3Sopenharmony_ci GetNumFromString(str, len, &index, &year); 2914514f5e3Sopenharmony_ci indexGmt = str.find("GMT", index); 2924514f5e3Sopenharmony_ci if (indexGmt == CString::npos) { 2934514f5e3Sopenharmony_ci GetNumFromString(str, len, &index, &hours); 2944514f5e3Sopenharmony_ci GetNumFromString(str, len, &index, &minutes); 2954514f5e3Sopenharmony_ci GetNumFromString(str, len, &index, &seconds); 2964514f5e3Sopenharmony_ci isLocal = true; 2974514f5e3Sopenharmony_ci localMs -= (GetLocalOffsetFromOS(localMs, true) * MS_PER_MINUTE); 2984514f5e3Sopenharmony_ci } else { 2994514f5e3Sopenharmony_ci indexPlus = str.find(PLUS, indexGmt); 3004514f5e3Sopenharmony_ci int indexLocal = static_cast<int>(indexGmt); 3014514f5e3Sopenharmony_ci GetNumFromString(str, indexGmt, &index, &hours); 3024514f5e3Sopenharmony_ci GetNumFromString(str, indexGmt, &index, &minutes); 3034514f5e3Sopenharmony_ci GetNumFromString(str, indexGmt, &index, &seconds); 3044514f5e3Sopenharmony_ci GetNumFromString(str, len, &indexLocal, &localTime); 3054514f5e3Sopenharmony_ci localHours = localTime / HUNDRED; 3064514f5e3Sopenharmony_ci localMinutes = localTime % HUNDRED; 3074514f5e3Sopenharmony_ci localMs = static_cast<int64_t>(MakeTime(localHours, localMinutes, 0, 0)); 3084514f5e3Sopenharmony_ci if (indexPlus != CString::npos) { 3094514f5e3Sopenharmony_ci localMs = -localMs; 3104514f5e3Sopenharmony_ci } 3114514f5e3Sopenharmony_ci } 3124514f5e3Sopenharmony_ci double day = MakeDay(year, month, date); 3134514f5e3Sopenharmony_ci double time = MakeTime(hours, minutes, seconds, ms); 3144514f5e3Sopenharmony_ci double timeValue = TimeClip(MakeDate(day, time)); 3154514f5e3Sopenharmony_ci if (std::isnan(timeValue)) { 3164514f5e3Sopenharmony_ci return JSTaggedValue(timeValue); 3174514f5e3Sopenharmony_ci } 3184514f5e3Sopenharmony_ci if (isLocal && timeValue < CHINA_1901_MS && (-localMs / MS_PER_MINUTE) == CHINA_AFTER_1901_MIN) { 3194514f5e3Sopenharmony_ci timeValue += static_cast<double>(localMs - CHINA_BEFORE_1901_MS); 3204514f5e3Sopenharmony_ci } else { 3214514f5e3Sopenharmony_ci timeValue += localMs; 3224514f5e3Sopenharmony_ci } 3234514f5e3Sopenharmony_ci return JSTaggedValue(timeValue); 3244514f5e3Sopenharmony_ci} 3254514f5e3Sopenharmony_ci 3264514f5e3Sopenharmony_ci// static 3274514f5e3Sopenharmony_ciJSTaggedValue JSDate::UtcParseStringToMs(const CString &str) 3284514f5e3Sopenharmony_ci{ 3294514f5e3Sopenharmony_ci int year = 0; 3304514f5e3Sopenharmony_ci int month = 0; 3314514f5e3Sopenharmony_ci int date = 1; 3324514f5e3Sopenharmony_ci int hours = 0; 3334514f5e3Sopenharmony_ci int minutes = 0; 3344514f5e3Sopenharmony_ci int seconds = 0; 3354514f5e3Sopenharmony_ci int ms = 0; 3364514f5e3Sopenharmony_ci int index = 0; 3374514f5e3Sopenharmony_ci int len = static_cast<int>(str.length()); 3384514f5e3Sopenharmony_ci CString::size_type indexGmt; 3394514f5e3Sopenharmony_ci CString::size_type indexPlus = CString::npos; 3404514f5e3Sopenharmony_ci int localTime = 0; 3414514f5e3Sopenharmony_ci int localHours = 0; 3424514f5e3Sopenharmony_ci int localMinutes = 0; 3434514f5e3Sopenharmony_ci int64_t localMs = 0; 3444514f5e3Sopenharmony_ci bool isLocal = false; 3454514f5e3Sopenharmony_ci GetNumFromString(str, len, &index, &date); 3464514f5e3Sopenharmony_ci CString strMonth = str.substr(index + 1, LENGTH_MONTH_NAME); 3474514f5e3Sopenharmony_ci for (int i = 0; i < MOUTH_PER_YEAR; i++) { 3484514f5e3Sopenharmony_ci if (strMonth == MONTH_NAME[i]) { 3494514f5e3Sopenharmony_ci month = i; 3504514f5e3Sopenharmony_ci break; 3514514f5e3Sopenharmony_ci } 3524514f5e3Sopenharmony_ci } 3534514f5e3Sopenharmony_ci index += (LENGTH_MONTH_NAME + 1); 3544514f5e3Sopenharmony_ci GetNumFromString(str, len, &index, &year); 3554514f5e3Sopenharmony_ci indexGmt = str.find("GMT", index); 3564514f5e3Sopenharmony_ci if (indexGmt == CString::npos) { 3574514f5e3Sopenharmony_ci GetNumFromString(str, len, &index, &hours); 3584514f5e3Sopenharmony_ci GetNumFromString(str, len, &index, &minutes); 3594514f5e3Sopenharmony_ci GetNumFromString(str, len, &index, &seconds); 3604514f5e3Sopenharmony_ci isLocal = true; 3614514f5e3Sopenharmony_ci localMs -= (GetLocalOffsetFromOS(localMs, true) * MS_PER_MINUTE); 3624514f5e3Sopenharmony_ci } else { 3634514f5e3Sopenharmony_ci indexPlus = str.find(PLUS, indexGmt); 3644514f5e3Sopenharmony_ci int indexLocal = static_cast<int>(indexGmt); 3654514f5e3Sopenharmony_ci GetNumFromString(str, indexGmt, &index, &hours); 3664514f5e3Sopenharmony_ci GetNumFromString(str, indexGmt, &index, &minutes); 3674514f5e3Sopenharmony_ci GetNumFromString(str, indexGmt, &index, &seconds); 3684514f5e3Sopenharmony_ci GetNumFromString(str, len, &indexLocal, &localTime); 3694514f5e3Sopenharmony_ci localHours = localTime / HUNDRED; 3704514f5e3Sopenharmony_ci localMinutes = localTime % HUNDRED; 3714514f5e3Sopenharmony_ci localMs = static_cast<int64_t>(MakeTime(localHours, localMinutes, 0, 0)); 3724514f5e3Sopenharmony_ci if (indexPlus != CString::npos) { 3734514f5e3Sopenharmony_ci localMs = -localMs; 3744514f5e3Sopenharmony_ci } 3754514f5e3Sopenharmony_ci } 3764514f5e3Sopenharmony_ci double day = MakeDay(year, month, date); 3774514f5e3Sopenharmony_ci double time = MakeTime(hours, minutes, seconds, ms); 3784514f5e3Sopenharmony_ci double timeValue = TimeClip(MakeDate(day, time)); 3794514f5e3Sopenharmony_ci if (std::isnan(timeValue)) { 3804514f5e3Sopenharmony_ci return JSTaggedValue(timeValue); 3814514f5e3Sopenharmony_ci } 3824514f5e3Sopenharmony_ci if (isLocal && timeValue < CHINA_1901_MS && (-localMs / MS_PER_MINUTE) == CHINA_AFTER_1901_MIN) { 3834514f5e3Sopenharmony_ci timeValue += static_cast<double>(localMs - CHINA_BEFORE_1901_MS); 3844514f5e3Sopenharmony_ci } else { 3854514f5e3Sopenharmony_ci timeValue += localMs; 3864514f5e3Sopenharmony_ci } 3874514f5e3Sopenharmony_ci return JSTaggedValue(timeValue); 3884514f5e3Sopenharmony_ci} 3894514f5e3Sopenharmony_ci// static 3904514f5e3Sopenharmony_ciJSTaggedValue JSDate::IsoParseStringToMs(const CString &str) 3914514f5e3Sopenharmony_ci{ 3924514f5e3Sopenharmony_ci char flag = 0; 3934514f5e3Sopenharmony_ci int year; 3944514f5e3Sopenharmony_ci int month = 1; 3954514f5e3Sopenharmony_ci int date = 1; 3964514f5e3Sopenharmony_ci int hours = 0; 3974514f5e3Sopenharmony_ci int minutes = 0; 3984514f5e3Sopenharmony_ci int seconds = 0; 3994514f5e3Sopenharmony_ci int ms = 0; 4004514f5e3Sopenharmony_ci int index = 0; 4014514f5e3Sopenharmony_ci int len = static_cast<int>(str.length()); 4024514f5e3Sopenharmony_ci year = GetSignedNumFromString(str, len, &index); 4034514f5e3Sopenharmony_ci CString::size_type indexT = str.find(FLAG_TIME, index); 4044514f5e3Sopenharmony_ci CString::size_type indexZ = str.find(FLAG_UTC, index); 4054514f5e3Sopenharmony_ci CString::size_type indexEndFlag = 0; 4064514f5e3Sopenharmony_ci int64_t localMs = 0; 4074514f5e3Sopenharmony_ci if (indexZ != CString::npos) { 4084514f5e3Sopenharmony_ci indexEndFlag = indexZ; 4094514f5e3Sopenharmony_ci } else if (len >= MIN_LENGTH && str.at(len - INDEX_PLUS_NEG) == NEG) { 4104514f5e3Sopenharmony_ci indexEndFlag = static_cast<CString::size_type>(len - INDEX_PLUS_NEG); 4114514f5e3Sopenharmony_ci flag = NEG; 4124514f5e3Sopenharmony_ci } else if (len >= MIN_LENGTH && str.at(len - INDEX_PLUS_NEG) == PLUS) { 4134514f5e3Sopenharmony_ci indexEndFlag = static_cast<CString::size_type>(len - INDEX_PLUS_NEG); 4144514f5e3Sopenharmony_ci flag = PLUS; 4154514f5e3Sopenharmony_ci } 4164514f5e3Sopenharmony_ci if (indexT != CString::npos) { 4174514f5e3Sopenharmony_ci if (static_cast<int>(indexT) - index == LENGTH_PER_TIME) { 4184514f5e3Sopenharmony_ci GetNumFromString(str, len, &index, &month); 4194514f5e3Sopenharmony_ci } else if (static_cast<int>(indexT) - index == (LENGTH_PER_TIME + LENGTH_PER_TIME)) { 4204514f5e3Sopenharmony_ci GetNumFromString(str, len, &index, &month); 4214514f5e3Sopenharmony_ci GetNumFromString(str, len, &index, &date); 4224514f5e3Sopenharmony_ci } 4234514f5e3Sopenharmony_ci GetNumFromString(str, len, &index, &hours); 4244514f5e3Sopenharmony_ci GetNumFromString(str, len, &index, &minutes); 4254514f5e3Sopenharmony_ci if (indexEndFlag > 0) { 4264514f5e3Sopenharmony_ci if (static_cast<int>(indexEndFlag) - index == LENGTH_PER_TIME) { 4274514f5e3Sopenharmony_ci GetNumFromString(str, len, &index, &seconds); 4284514f5e3Sopenharmony_ci } else if (static_cast<int>(indexEndFlag) - index == (LENGTH_PER_TIME + LENGTH_PER_TIME + 1)) { 4294514f5e3Sopenharmony_ci GetNumFromString(str, len, &index, &seconds); 4304514f5e3Sopenharmony_ci GetNumFromString(str, len, &index, &ms); 4314514f5e3Sopenharmony_ci } 4324514f5e3Sopenharmony_ci } else { 4334514f5e3Sopenharmony_ci if (len - index == LENGTH_PER_TIME) { 4344514f5e3Sopenharmony_ci GetNumFromString(str, len, &index, &seconds); 4354514f5e3Sopenharmony_ci } else if (len - index == (LENGTH_PER_TIME + LENGTH_PER_TIME + 1)) { 4364514f5e3Sopenharmony_ci GetNumFromString(str, len, &index, &seconds); 4374514f5e3Sopenharmony_ci GetNumFromString(str, len, &index, &ms); 4384514f5e3Sopenharmony_ci } 4394514f5e3Sopenharmony_ci } 4404514f5e3Sopenharmony_ci } else { 4414514f5e3Sopenharmony_ci GetNumFromString(str, len, &index, &month); 4424514f5e3Sopenharmony_ci GetNumFromString(str, len, &index, &date); 4434514f5e3Sopenharmony_ci } 4444514f5e3Sopenharmony_ci if (indexEndFlag > 0) { 4454514f5e3Sopenharmony_ci int localHours = 0; 4464514f5e3Sopenharmony_ci int localMinutes = 0; 4474514f5e3Sopenharmony_ci if (indexZ == CString::npos) { 4484514f5e3Sopenharmony_ci GetNumFromString(str, len, &index, &localHours); 4494514f5e3Sopenharmony_ci GetNumFromString(str, len, &index, &localMinutes); 4504514f5e3Sopenharmony_ci if (flag == PLUS) { 4514514f5e3Sopenharmony_ci localMs = static_cast<int64_t>(-MakeTime(localHours, localMinutes, 0, 0)); 4524514f5e3Sopenharmony_ci } else { 4534514f5e3Sopenharmony_ci localMs = static_cast<int64_t>(MakeTime(localHours, localMinutes, 0, 0)); 4544514f5e3Sopenharmony_ci } 4554514f5e3Sopenharmony_ci } 4564514f5e3Sopenharmony_ci } 4574514f5e3Sopenharmony_ci if (indexEndFlag == 0 && indexT != CString::npos) { 4584514f5e3Sopenharmony_ci localMs -= (GetLocalOffsetFromOS(localMs, true) * MS_PER_MINUTE); 4594514f5e3Sopenharmony_ci } 4604514f5e3Sopenharmony_ci 4614514f5e3Sopenharmony_ci double day = MakeDay(year, month - 1, date); 4624514f5e3Sopenharmony_ci double time = MakeTime(hours, minutes, seconds, ms); 4634514f5e3Sopenharmony_ci double timeValue = TimeClip(MakeDate(day, time)); 4644514f5e3Sopenharmony_ci if (std::isnan(timeValue)) { 4654514f5e3Sopenharmony_ci return JSTaggedValue(timeValue); 4664514f5e3Sopenharmony_ci } 4674514f5e3Sopenharmony_ci if (flag == 0 && timeValue < CHINA_1901_MS && (-localMs / MS_PER_MINUTE) == CHINA_AFTER_1901_MIN) { 4684514f5e3Sopenharmony_ci timeValue += static_cast<double>(localMs - CHINA_BEFORE_1901_MS); 4694514f5e3Sopenharmony_ci } else { 4704514f5e3Sopenharmony_ci timeValue += localMs; 4714514f5e3Sopenharmony_ci } 4724514f5e3Sopenharmony_ci return JSTaggedValue(timeValue); 4734514f5e3Sopenharmony_ci} 4744514f5e3Sopenharmony_ci 4754514f5e3Sopenharmony_ciJSTaggedValue JSDate::GetTimeFromString(const char *str, int len) 4764514f5e3Sopenharmony_ci{ 4774514f5e3Sopenharmony_ci int time[TIMEZONE + 1]; 4784514f5e3Sopenharmony_ci bool res = DateParse::ParseDateString(str, len, time); 4794514f5e3Sopenharmony_ci if (res) { 4804514f5e3Sopenharmony_ci double day = MakeDay(time[YEAR], time[MONTH], time[DAYS]); 4814514f5e3Sopenharmony_ci double dateTime = MakeTime(time[HOUR], time[MIN], time[SEC], time[MS]); 4824514f5e3Sopenharmony_ci double timeValue = TimeClip(MakeDate(day, dateTime)); 4834514f5e3Sopenharmony_ci if (std::isnan(timeValue)) { 4844514f5e3Sopenharmony_ci return JSTaggedValue(timeValue); 4854514f5e3Sopenharmony_ci } 4864514f5e3Sopenharmony_ci int64_t localMs; 4874514f5e3Sopenharmony_ci if (time[TIMEZONE] == INT_MAX) { 4884514f5e3Sopenharmony_ci localMs = GetLocalOffsetFromOS(static_cast<int64_t>(timeValue), true) * MS_PER_MINUTE; 4894514f5e3Sopenharmony_ci } else { 4904514f5e3Sopenharmony_ci localMs = time[TIMEZONE] * MS_PER_SECOND; 4914514f5e3Sopenharmony_ci } 4924514f5e3Sopenharmony_ci timeValue -= localMs; 4934514f5e3Sopenharmony_ci return JSTaggedValue(timeValue); 4944514f5e3Sopenharmony_ci } 4954514f5e3Sopenharmony_ci return JSTaggedValue(base::NAN_VALUE); 4964514f5e3Sopenharmony_ci} 4974514f5e3Sopenharmony_ci 4984514f5e3Sopenharmony_ci// 20.4.3.2 static 4994514f5e3Sopenharmony_ciJSTaggedValue JSDate::Parse(EcmaRuntimeCallInfo *argv) 5004514f5e3Sopenharmony_ci{ 5014514f5e3Sopenharmony_ci ASSERT(argv); 5024514f5e3Sopenharmony_ci JSThread *thread = argv->GetThread(); 5034514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> msg = base::BuiltinsBase::GetCallArg(argv, 0); 5044514f5e3Sopenharmony_ci JSHandle<EcmaString> ecmaStr = JSTaggedValue::ToString(thread, msg); 5054514f5e3Sopenharmony_ci RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::Exception()); 5064514f5e3Sopenharmony_ci CVector<uint8_t> tmpBuf; 5074514f5e3Sopenharmony_ci EcmaStringAccessor strAccessor(const_cast<EcmaString *>(*ecmaStr)); 5084514f5e3Sopenharmony_ci if (strAccessor.IsUtf16()) { 5094514f5e3Sopenharmony_ci return JSTaggedValue(base::NAN_VALUE); 5104514f5e3Sopenharmony_ci } 5114514f5e3Sopenharmony_ci int len = static_cast<int>(strAccessor.GetLength()); 5124514f5e3Sopenharmony_ci auto data = reinterpret_cast<const char *>(strAccessor.GetUtf8DataFlat(*ecmaStr, tmpBuf)); 5134514f5e3Sopenharmony_ci return GetTimeFromString(data, len); 5144514f5e3Sopenharmony_ci} 5154514f5e3Sopenharmony_ci 5164514f5e3Sopenharmony_ci// 20.4.3.1 5174514f5e3Sopenharmony_ciJSTaggedValue JSDate::Now() 5184514f5e3Sopenharmony_ci{ 5194514f5e3Sopenharmony_ci // time from now is in ms. 5204514f5e3Sopenharmony_ci int64_t ans; 5214514f5e3Sopenharmony_ci struct timeval tv { 5224514f5e3Sopenharmony_ci }; 5234514f5e3Sopenharmony_ci gettimeofday(&tv, nullptr); 5244514f5e3Sopenharmony_ci ans = static_cast<int64_t>(tv.tv_sec) * MS_PER_SECOND + (tv.tv_usec / MS_PER_SECOND); 5254514f5e3Sopenharmony_ci return JSTaggedValue(static_cast<double>(ans)); 5264514f5e3Sopenharmony_ci} 5274514f5e3Sopenharmony_ci 5284514f5e3Sopenharmony_ci// 20.4.4.2 static 5294514f5e3Sopenharmony_ciJSTaggedValue JSDate::UTC(EcmaRuntimeCallInfo *argv) 5304514f5e3Sopenharmony_ci{ 5314514f5e3Sopenharmony_ci double year = 0.0; 5324514f5e3Sopenharmony_ci double month = 0.0; 5334514f5e3Sopenharmony_ci double date = 1.0; 5344514f5e3Sopenharmony_ci double hours = 0.0; 5354514f5e3Sopenharmony_ci double minutes = 0.0; 5364514f5e3Sopenharmony_ci double seconds = 0.0; 5374514f5e3Sopenharmony_ci double ms = 0.0; 5384514f5e3Sopenharmony_ci JSThread *thread = argv->GetThread(); 5394514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> yearArg = base::BuiltinsBase::GetCallArg(argv, 0); 5404514f5e3Sopenharmony_ci JSTaggedNumber yearValue = JSTaggedValue::ToNumber(thread, yearArg); 5414514f5e3Sopenharmony_ci RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::Exception()); 5424514f5e3Sopenharmony_ci if (yearValue.IsNumber()) { 5434514f5e3Sopenharmony_ci year = yearValue.GetNumber(); 5444514f5e3Sopenharmony_ci if (std::isfinite(year) && !yearValue.IsInt()) { 5454514f5e3Sopenharmony_ci year = NumberHelper::TruncateDouble(year); 5464514f5e3Sopenharmony_ci } 5474514f5e3Sopenharmony_ci if (year >= 0 && year <= (HUNDRED - 1)) { 5484514f5e3Sopenharmony_ci year = year + NINETEEN_HUNDRED_YEAR; 5494514f5e3Sopenharmony_ci } 5504514f5e3Sopenharmony_ci } else { 5514514f5e3Sopenharmony_ci year = base::NAN_VALUE; 5524514f5e3Sopenharmony_ci } 5534514f5e3Sopenharmony_ci uint32_t index = 1; 5544514f5e3Sopenharmony_ci uint32_t numArgs = argv->GetArgsNumber(); 5554514f5e3Sopenharmony_ci JSTaggedValue res; 5564514f5e3Sopenharmony_ci if (numArgs > index) { 5574514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> value = base::BuiltinsBase::GetCallArg(argv, index); 5584514f5e3Sopenharmony_ci res = JSTaggedValue::ToNumber(thread, value); 5594514f5e3Sopenharmony_ci RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::Exception()); 5604514f5e3Sopenharmony_ci month = res.GetNumber(); 5614514f5e3Sopenharmony_ci index++; 5624514f5e3Sopenharmony_ci } 5634514f5e3Sopenharmony_ci if (numArgs > index) { 5644514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> value = base::BuiltinsBase::GetCallArg(argv, index); 5654514f5e3Sopenharmony_ci res = JSTaggedValue::ToNumber(thread, value); 5664514f5e3Sopenharmony_ci RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::Exception()); 5674514f5e3Sopenharmony_ci date = res.GetNumber(); 5684514f5e3Sopenharmony_ci index++; 5694514f5e3Sopenharmony_ci } 5704514f5e3Sopenharmony_ci if (numArgs > index) { 5714514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> value = base::BuiltinsBase::GetCallArg(argv, index); 5724514f5e3Sopenharmony_ci res = JSTaggedValue::ToNumber(thread, value); 5734514f5e3Sopenharmony_ci RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::Exception()); 5744514f5e3Sopenharmony_ci hours = res.GetNumber(); 5754514f5e3Sopenharmony_ci index++; 5764514f5e3Sopenharmony_ci } 5774514f5e3Sopenharmony_ci if (numArgs > index) { 5784514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> value = base::BuiltinsBase::GetCallArg(argv, index); 5794514f5e3Sopenharmony_ci res = JSTaggedValue::ToNumber(thread, value); 5804514f5e3Sopenharmony_ci RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::Exception()); 5814514f5e3Sopenharmony_ci minutes = res.GetNumber(); 5824514f5e3Sopenharmony_ci index++; 5834514f5e3Sopenharmony_ci } 5844514f5e3Sopenharmony_ci if (numArgs > index) { 5854514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> value = base::BuiltinsBase::GetCallArg(argv, index); 5864514f5e3Sopenharmony_ci res = JSTaggedValue::ToNumber(thread, value); 5874514f5e3Sopenharmony_ci RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::Exception()); 5884514f5e3Sopenharmony_ci seconds = res.GetNumber(); 5894514f5e3Sopenharmony_ci index++; 5904514f5e3Sopenharmony_ci } 5914514f5e3Sopenharmony_ci if (numArgs > index) { 5924514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> value = base::BuiltinsBase::GetCallArg(argv, index); 5934514f5e3Sopenharmony_ci res = JSTaggedValue::ToNumber(thread, value); 5944514f5e3Sopenharmony_ci RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::Exception()); 5954514f5e3Sopenharmony_ci ms = res.GetNumber(); 5964514f5e3Sopenharmony_ci } 5974514f5e3Sopenharmony_ci double day = MakeDay(year, month, date); 5984514f5e3Sopenharmony_ci double time = MakeTime(hours, minutes, seconds, ms); 5994514f5e3Sopenharmony_ci return JSTaggedValue(TimeClip(MakeDate(day, time))); 6004514f5e3Sopenharmony_ci} 6014514f5e3Sopenharmony_ci 6024514f5e3Sopenharmony_ci// 20.4.4.10 6034514f5e3Sopenharmony_ciJSTaggedValue JSDate::GetTime() const 6044514f5e3Sopenharmony_ci{ 6054514f5e3Sopenharmony_ci return GetTimeValue(); 6064514f5e3Sopenharmony_ci} 6074514f5e3Sopenharmony_ci 6084514f5e3Sopenharmony_ci// static 6094514f5e3Sopenharmony_ciCString JSDate::StrToTargetLength(const CString &str, int length) 6104514f5e3Sopenharmony_ci{ 6114514f5e3Sopenharmony_ci int len = 0; 6124514f5e3Sopenharmony_ci CString sub; 6134514f5e3Sopenharmony_ci if (str[0] == NEG) { 6144514f5e3Sopenharmony_ci sub.reserve(length + 1); 6154514f5e3Sopenharmony_ci ASSERT(str.length() > 0); 6164514f5e3Sopenharmony_ci len = static_cast<int>(str.length() - 1); 6174514f5e3Sopenharmony_ci sub += NEG; 6184514f5e3Sopenharmony_ci } else { 6194514f5e3Sopenharmony_ci sub.reserve(length); 6204514f5e3Sopenharmony_ci len = static_cast<int>(str.length()); 6214514f5e3Sopenharmony_ci } 6224514f5e3Sopenharmony_ci int dif = length - len; 6234514f5e3Sopenharmony_ci for (int i = 0; i < dif; i++) { 6244514f5e3Sopenharmony_ci sub += '0'; 6254514f5e3Sopenharmony_ci } 6264514f5e3Sopenharmony_ci if (str[0] == NEG) { 6274514f5e3Sopenharmony_ci sub += str.substr(1, len); 6284514f5e3Sopenharmony_ci } else { 6294514f5e3Sopenharmony_ci sub += str; 6304514f5e3Sopenharmony_ci } 6314514f5e3Sopenharmony_ci return sub; 6324514f5e3Sopenharmony_ci} 6334514f5e3Sopenharmony_ci 6344514f5e3Sopenharmony_ci// static 6354514f5e3Sopenharmony_civoid JSDate::AppendStrToTargetLength(const CString &str, int length, CString &target) 6364514f5e3Sopenharmony_ci{ 6374514f5e3Sopenharmony_ci int len = 0; 6384514f5e3Sopenharmony_ci if (str[0] == NEG) { 6394514f5e3Sopenharmony_ci len = static_cast<int>(str.length() - 1); 6404514f5e3Sopenharmony_ci target += NEG; 6414514f5e3Sopenharmony_ci } else { 6424514f5e3Sopenharmony_ci len = static_cast<int>(str.length()); 6434514f5e3Sopenharmony_ci } 6444514f5e3Sopenharmony_ci int dif = length - len; 6454514f5e3Sopenharmony_ci for (int i = 0; i < dif; i++) { 6464514f5e3Sopenharmony_ci target += '0'; 6474514f5e3Sopenharmony_ci } 6484514f5e3Sopenharmony_ci if (str[0] == NEG) { 6494514f5e3Sopenharmony_ci target += str.substr(1, len); 6504514f5e3Sopenharmony_ci } else { 6514514f5e3Sopenharmony_ci target += str; 6524514f5e3Sopenharmony_ci } 6534514f5e3Sopenharmony_ci} 6544514f5e3Sopenharmony_ci 6554514f5e3Sopenharmony_cibool JSDate::GetThisDateValues(std::array<int64_t, DATE_LENGTH> *date, bool isLocal) const 6564514f5e3Sopenharmony_ci{ 6574514f5e3Sopenharmony_ci double timeMs = this->GetTimeValue().GetDouble(); 6584514f5e3Sopenharmony_ci if (std::isnan(timeMs)) { 6594514f5e3Sopenharmony_ci return false; 6604514f5e3Sopenharmony_ci } 6614514f5e3Sopenharmony_ci GetDateValues(timeMs, date, isLocal); 6624514f5e3Sopenharmony_ci return true; 6634514f5e3Sopenharmony_ci} 6644514f5e3Sopenharmony_ci 6654514f5e3Sopenharmony_ci// 20.4.4.35 6664514f5e3Sopenharmony_ciJSTaggedValue JSDate::ToDateString(JSThread *thread) const 6674514f5e3Sopenharmony_ci{ 6684514f5e3Sopenharmony_ci std::array<int64_t, DATE_LENGTH> fields = {0}; 6694514f5e3Sopenharmony_ci if (!GetThisDateValues(&fields, true)) { 6704514f5e3Sopenharmony_ci return JSTaggedValue(base::NAN_VALUE); 6714514f5e3Sopenharmony_ci } 6724514f5e3Sopenharmony_ci CString str; 6734514f5e3Sopenharmony_ci str.reserve(DATE_STRING_LENGTH); 6744514f5e3Sopenharmony_ci str.append(WEEK_DAY_NAME[fields[WEEKDAY]]) // Append weekdy name 6754514f5e3Sopenharmony_ci .append(SPACE_STR) // Append SPACE 6764514f5e3Sopenharmony_ci .append(MONTH_NAME[fields[MONTH]]) // Append mouth name 6774514f5e3Sopenharmony_ci .append(SPACE_STR); // Append SPACE 6784514f5e3Sopenharmony_ci ConvertAndAppend(fields[DAYS], STR_LENGTH_OTHERS, str); 6794514f5e3Sopenharmony_ci str += SPACE; 6804514f5e3Sopenharmony_ci ConvertAndAppend(fields[YEAR], STR_LENGTH_YEAR, str); 6814514f5e3Sopenharmony_ci JSHandle<EcmaString> result = thread->GetEcmaVM()->GetFactory()->NewFromASCII(str); 6824514f5e3Sopenharmony_ci return result.GetTaggedValue(); 6834514f5e3Sopenharmony_ci} 6844514f5e3Sopenharmony_ci 6854514f5e3Sopenharmony_ci// static 6864514f5e3Sopenharmony_ciCString JSDate::ToDateString(double timeMs) 6874514f5e3Sopenharmony_ci{ 6884514f5e3Sopenharmony_ci if (std::isnan(timeMs)) { 6894514f5e3Sopenharmony_ci return "Invalid Date"; 6904514f5e3Sopenharmony_ci } 6914514f5e3Sopenharmony_ci std::array<int64_t, DATE_LENGTH> fields = {0}; 6924514f5e3Sopenharmony_ci GetDateValues(timeMs, &fields, true); 6934514f5e3Sopenharmony_ci CString localTime; 6944514f5e3Sopenharmony_ci int localMin = 0; 6954514f5e3Sopenharmony_ci localMin = GetLocalOffsetFromOS(timeMs, true); 6964514f5e3Sopenharmony_ci if (localMin >= 0) { 6974514f5e3Sopenharmony_ci localTime += PLUS; 6984514f5e3Sopenharmony_ci } else { 6994514f5e3Sopenharmony_ci localTime += NEG; 7004514f5e3Sopenharmony_ci localMin = -localMin; 7014514f5e3Sopenharmony_ci } 7024514f5e3Sopenharmony_ci localTime = localTime + StrToTargetLength(ToCString(localMin / MINUTE_PER_HOUR), STR_LENGTH_OTHERS); 7034514f5e3Sopenharmony_ci localTime = localTime + StrToTargetLength(ToCString(localMin % MINUTE_PER_HOUR), STR_LENGTH_OTHERS); 7044514f5e3Sopenharmony_ci CString str; 7054514f5e3Sopenharmony_ci str.reserve(DATE_CSTRING_LENGTH); 7064514f5e3Sopenharmony_ci str.append(WEEK_DAY_NAME[fields[WEEKDAY]]) // Append weekday name 7074514f5e3Sopenharmony_ci .append(SPACE_STR) // Append SPACE 7084514f5e3Sopenharmony_ci .append(MONTH_NAME[fields[MONTH]]) // Append mouth name 7094514f5e3Sopenharmony_ci .append(SPACE_STR); // Append SPACE 7104514f5e3Sopenharmony_ci ConvertAndAppend(fields[DAYS], STR_LENGTH_OTHERS, str); 7114514f5e3Sopenharmony_ci str += SPACE; 7124514f5e3Sopenharmony_ci ConvertAndAppend(fields[YEAR], STR_LENGTH_YEAR, str); 7134514f5e3Sopenharmony_ci str += SPACE; 7144514f5e3Sopenharmony_ci ConvertAndAppend(fields[HOUR], STR_LENGTH_OTHERS, str); 7154514f5e3Sopenharmony_ci str += COLON; 7164514f5e3Sopenharmony_ci ConvertAndAppend(fields[MIN], STR_LENGTH_OTHERS, str); 7174514f5e3Sopenharmony_ci str += COLON; 7184514f5e3Sopenharmony_ci ConvertAndAppend(fields[SEC], STR_LENGTH_OTHERS, str); 7194514f5e3Sopenharmony_ci str.append(SPACE_STR) // Append SPACE 7204514f5e3Sopenharmony_ci .append("GMT") // Append GMT 7214514f5e3Sopenharmony_ci .append(localTime); // Append localTime 7224514f5e3Sopenharmony_ci return str; 7234514f5e3Sopenharmony_ci} 7244514f5e3Sopenharmony_ci// 20.4.4.36 7254514f5e3Sopenharmony_ciJSTaggedValue JSDate::ToISOString(JSThread *thread) const 7264514f5e3Sopenharmony_ci{ 7274514f5e3Sopenharmony_ci std::array<int64_t, DATE_LENGTH> fields = {0}; 7284514f5e3Sopenharmony_ci if (!GetThisDateValues(&fields, false)) { 7294514f5e3Sopenharmony_ci return JSTaggedValue(base::NAN_VALUE); 7304514f5e3Sopenharmony_ci } 7314514f5e3Sopenharmony_ci CString year = ToCString(fields[YEAR]); 7324514f5e3Sopenharmony_ci if (year[0] == NEG) { 7334514f5e3Sopenharmony_ci year = StrToTargetLength(year, STR_LENGTH_YEAR + STR_LENGTH_OTHERS); 7344514f5e3Sopenharmony_ci } else if (year.length() > STR_LENGTH_YEAR) { 7354514f5e3Sopenharmony_ci year = PLUS + StrToTargetLength(year, STR_LENGTH_YEAR + STR_LENGTH_OTHERS); 7364514f5e3Sopenharmony_ci } else { 7374514f5e3Sopenharmony_ci year = StrToTargetLength(year, STR_LENGTH_YEAR); 7384514f5e3Sopenharmony_ci } 7394514f5e3Sopenharmony_ci CString str; 7404514f5e3Sopenharmony_ci str.reserve(ISO_STRING_LENGTH); 7414514f5e3Sopenharmony_ci str.append(year) // Append year 7424514f5e3Sopenharmony_ci .append(NEG_STR); // Append NEG 7434514f5e3Sopenharmony_ci ConvertAndAppend(fields[MONTH] + 1, STR_LENGTH_OTHERS, str); 7444514f5e3Sopenharmony_ci str += NEG; 7454514f5e3Sopenharmony_ci ConvertAndAppend(fields[DAYS], STR_LENGTH_OTHERS, str); 7464514f5e3Sopenharmony_ci str += FLAG_TIME; 7474514f5e3Sopenharmony_ci ConvertAndAppend(fields[HOUR], STR_LENGTH_OTHERS, str); 7484514f5e3Sopenharmony_ci str += COLON; 7494514f5e3Sopenharmony_ci ConvertAndAppend(fields[MIN], STR_LENGTH_OTHERS, str); 7504514f5e3Sopenharmony_ci str += COLON; 7514514f5e3Sopenharmony_ci ConvertAndAppend(fields[SEC], STR_LENGTH_OTHERS, str); 7524514f5e3Sopenharmony_ci str += POINT; 7534514f5e3Sopenharmony_ci ConvertAndAppend(fields[MS], STR_LENGTH_OTHERS + 1, str); 7544514f5e3Sopenharmony_ci str += FLAG_UTC; 7554514f5e3Sopenharmony_ci return thread->GetEcmaVM()->GetFactory()->NewFromASCII(str).GetTaggedValue(); 7564514f5e3Sopenharmony_ci} 7574514f5e3Sopenharmony_ci 7584514f5e3Sopenharmony_ci// 20.4.4.41 7594514f5e3Sopenharmony_ciJSTaggedValue JSDate::ToString(JSThread *thread) const 7604514f5e3Sopenharmony_ci{ 7614514f5e3Sopenharmony_ci int localMin = 0; 7624514f5e3Sopenharmony_ci std::array<int64_t, DATE_LENGTH> fields = {0}; 7634514f5e3Sopenharmony_ci if (!GetThisDateValues(&fields, true)) { 7644514f5e3Sopenharmony_ci return JSTaggedValue(base::NAN_VALUE); 7654514f5e3Sopenharmony_ci } 7664514f5e3Sopenharmony_ci CString localTime; 7674514f5e3Sopenharmony_ci localMin = GetLocalOffsetFromOS(static_cast<int64_t>(this->GetTimeValue().GetDouble()), true); 7684514f5e3Sopenharmony_ci if (localMin >= 0) { 7694514f5e3Sopenharmony_ci localTime += PLUS; 7704514f5e3Sopenharmony_ci } else { 7714514f5e3Sopenharmony_ci localTime += NEG; 7724514f5e3Sopenharmony_ci localMin = -localMin; 7734514f5e3Sopenharmony_ci } 7744514f5e3Sopenharmony_ci localTime = localTime + StrToTargetLength(ToCString(localMin / MINUTE_PER_HOUR), STR_LENGTH_OTHERS); 7754514f5e3Sopenharmony_ci localTime = localTime + StrToTargetLength(ToCString(localMin % MINUTE_PER_HOUR), STR_LENGTH_OTHERS); 7764514f5e3Sopenharmony_ci CString str; 7774514f5e3Sopenharmony_ci str.reserve(TO_STRING_LENGTH); 7784514f5e3Sopenharmony_ci str.append(WEEK_DAY_NAME[fields[WEEKDAY]]) // Append weekday name 7794514f5e3Sopenharmony_ci .append(SPACE_STR) // Append SPACE 7804514f5e3Sopenharmony_ci .append(MONTH_NAME[fields[MONTH]]) // Append mouth name 7814514f5e3Sopenharmony_ci .append(SPACE_STR); // Append SPACE 7824514f5e3Sopenharmony_ci ConvertAndAppend(fields[DAYS], STR_LENGTH_OTHERS, str); 7834514f5e3Sopenharmony_ci str += SPACE; 7844514f5e3Sopenharmony_ci ConvertAndAppend(fields[YEAR], STR_LENGTH_YEAR, str); 7854514f5e3Sopenharmony_ci str += SPACE; 7864514f5e3Sopenharmony_ci ConvertAndAppend(fields[HOUR], STR_LENGTH_OTHERS, str); 7874514f5e3Sopenharmony_ci str += COLON; 7884514f5e3Sopenharmony_ci ConvertAndAppend(fields[MIN], STR_LENGTH_OTHERS, str); 7894514f5e3Sopenharmony_ci str += COLON; 7904514f5e3Sopenharmony_ci ConvertAndAppend(fields[SEC], STR_LENGTH_OTHERS, str); 7914514f5e3Sopenharmony_ci str.append(SPACE_STR) // Append SPACE 7924514f5e3Sopenharmony_ci .append("GMT") // Append GMT 7934514f5e3Sopenharmony_ci .append(localTime); // Append localTime 7944514f5e3Sopenharmony_ci return thread->GetEcmaVM()->GetFactory()->NewFromASCII(str).GetTaggedValue(); 7954514f5e3Sopenharmony_ci} 7964514f5e3Sopenharmony_ci 7974514f5e3Sopenharmony_ci// 20.4.4.42 7984514f5e3Sopenharmony_ciJSTaggedValue JSDate::ToTimeString(JSThread *thread) const 7994514f5e3Sopenharmony_ci{ 8004514f5e3Sopenharmony_ci int localMin = 0; 8014514f5e3Sopenharmony_ci std::array<int64_t, DATE_LENGTH> fields = {0}; 8024514f5e3Sopenharmony_ci if (!GetThisDateValues(&fields, true)) { 8034514f5e3Sopenharmony_ci return JSTaggedValue(base::NAN_VALUE); 8044514f5e3Sopenharmony_ci } 8054514f5e3Sopenharmony_ci CString localTime; 8064514f5e3Sopenharmony_ci localMin = GetLocalOffsetFromOS(static_cast<int64_t>(this->GetTimeValue().GetDouble()), true); 8074514f5e3Sopenharmony_ci if (localMin >= 0) { 8084514f5e3Sopenharmony_ci localTime += PLUS; 8094514f5e3Sopenharmony_ci } else { 8104514f5e3Sopenharmony_ci localTime += NEG; 8114514f5e3Sopenharmony_ci localMin = -localMin; 8124514f5e3Sopenharmony_ci } 8134514f5e3Sopenharmony_ci localTime = localTime + StrToTargetLength(ToCString(localMin / MINUTE_PER_HOUR), STR_LENGTH_OTHERS); 8144514f5e3Sopenharmony_ci localTime = localTime + StrToTargetLength(ToCString(localMin % MINUTE_PER_HOUR), STR_LENGTH_OTHERS); 8154514f5e3Sopenharmony_ci CString str; 8164514f5e3Sopenharmony_ci str.reserve(TIME_STRING_LENGTH); 8174514f5e3Sopenharmony_ci ConvertAndAppend(fields[HOUR], STR_LENGTH_OTHERS, str); 8184514f5e3Sopenharmony_ci str += COLON; 8194514f5e3Sopenharmony_ci ConvertAndAppend(fields[MIN], STR_LENGTH_OTHERS, str); 8204514f5e3Sopenharmony_ci str += COLON; 8214514f5e3Sopenharmony_ci ConvertAndAppend(fields[SEC], STR_LENGTH_OTHERS, str); 8224514f5e3Sopenharmony_ci str.append(SPACE_STR) // Append SPACE 8234514f5e3Sopenharmony_ci .append("GMT") // Append GMT 8244514f5e3Sopenharmony_ci .append(localTime); // Append localTime 8254514f5e3Sopenharmony_ci return thread->GetEcmaVM()->GetFactory()->NewFromASCII(str).GetTaggedValue(); 8264514f5e3Sopenharmony_ci} 8274514f5e3Sopenharmony_ci 8284514f5e3Sopenharmony_ci// 20.4.4.43 8294514f5e3Sopenharmony_ciJSTaggedValue JSDate::ToUTCString(JSThread *thread) const 8304514f5e3Sopenharmony_ci{ 8314514f5e3Sopenharmony_ci std::array<int64_t, DATE_LENGTH> fields = {0}; 8324514f5e3Sopenharmony_ci if (!GetThisDateValues(&fields, false)) { 8334514f5e3Sopenharmony_ci return JSTaggedValue(base::NAN_VALUE); 8344514f5e3Sopenharmony_ci } 8354514f5e3Sopenharmony_ci CString str; 8364514f5e3Sopenharmony_ci str.reserve(UTC_STRING_LENGTH); 8374514f5e3Sopenharmony_ci str.append(WEEK_DAY_NAME[fields[WEEKDAY]]) // Append weekday name 8384514f5e3Sopenharmony_ci .append(COMMA_STR) // Append COMMA 8394514f5e3Sopenharmony_ci .append(SPACE_STR); // Append SPACE 8404514f5e3Sopenharmony_ci ConvertAndAppend(fields[DAYS], STR_LENGTH_OTHERS, str); 8414514f5e3Sopenharmony_ci str.append(SPACE_STR) // Append SPACE 8424514f5e3Sopenharmony_ci .append(MONTH_NAME[fields[MONTH]]) // Append mouth name 8434514f5e3Sopenharmony_ci .append(SPACE_STR); // Append SPACE 8444514f5e3Sopenharmony_ci ConvertAndAppend(fields[YEAR], STR_LENGTH_YEAR, str); 8454514f5e3Sopenharmony_ci str += SPACE; 8464514f5e3Sopenharmony_ci ConvertAndAppend(fields[HOUR], STR_LENGTH_OTHERS, str); 8474514f5e3Sopenharmony_ci str += COLON; 8484514f5e3Sopenharmony_ci ConvertAndAppend(fields[MIN], STR_LENGTH_OTHERS, str); 8494514f5e3Sopenharmony_ci str += COLON; 8504514f5e3Sopenharmony_ci ConvertAndAppend(fields[SEC], STR_LENGTH_OTHERS, str); 8514514f5e3Sopenharmony_ci str.append(SPACE_STR) // Append SPACE 8524514f5e3Sopenharmony_ci .append("GMT"); // Append GMT 8534514f5e3Sopenharmony_ci return thread->GetEcmaVM()->GetFactory()->NewFromASCII(str).GetTaggedValue(); 8544514f5e3Sopenharmony_ci} 8554514f5e3Sopenharmony_ci 8564514f5e3Sopenharmony_ci// 20.4.4.44 8574514f5e3Sopenharmony_ciJSTaggedValue JSDate::ValueOf() const 8584514f5e3Sopenharmony_ci{ 8594514f5e3Sopenharmony_ci return this->GetTimeValue(); 8604514f5e3Sopenharmony_ci} 8614514f5e3Sopenharmony_ci 8624514f5e3Sopenharmony_ci// static 8634514f5e3Sopenharmony_civoid JSDate::GetDateValues(double timeMs, std::array<int64_t, DATE_LENGTH> *date, bool isLocal) 8644514f5e3Sopenharmony_ci{ 8654514f5e3Sopenharmony_ci int64_t tz = 0; 8664514f5e3Sopenharmony_ci int64_t timeMsInt = static_cast<int64_t>(timeMs); 8674514f5e3Sopenharmony_ci if (isLocal) { // timezone offset 8684514f5e3Sopenharmony_ci tz = GetLocalOffsetFromOS(timeMsInt, isLocal); 8694514f5e3Sopenharmony_ci timeMsInt += tz * MS_PER_SECOND * SEC_PER_MINUTE; 8704514f5e3Sopenharmony_ci } 8714514f5e3Sopenharmony_ci 8724514f5e3Sopenharmony_ci DateUtils::TransferTimeToDate(timeMsInt, date); 8734514f5e3Sopenharmony_ci (*date)[TIMEZONE] = -tz; 8744514f5e3Sopenharmony_ci} 8754514f5e3Sopenharmony_ci 8764514f5e3Sopenharmony_cidouble JSDate::GetDateValue(double timeMs, uint8_t code, bool isLocal) const 8774514f5e3Sopenharmony_ci{ 8784514f5e3Sopenharmony_ci if (std::isnan(timeMs)) { 8794514f5e3Sopenharmony_ci return base::NAN_VALUE; 8804514f5e3Sopenharmony_ci } 8814514f5e3Sopenharmony_ci std::array<int64_t, DATE_LENGTH> date = {0}; 8824514f5e3Sopenharmony_ci GetDateValues(timeMs, &date, isLocal); 8834514f5e3Sopenharmony_ci return static_cast<double>(date[code]); 8844514f5e3Sopenharmony_ci} 8854514f5e3Sopenharmony_ci 8864514f5e3Sopenharmony_ciJSTaggedValue JSDate::SetDateValue(EcmaRuntimeCallInfo *argv, uint32_t code, bool isLocal) const 8874514f5e3Sopenharmony_ci{ 8884514f5e3Sopenharmony_ci // get date values. 8894514f5e3Sopenharmony_ci std::array<int64_t, DATE_LENGTH> date = {0}; 8904514f5e3Sopenharmony_ci double timeMs = this->GetTimeValue().GetDouble(); 8914514f5e3Sopenharmony_ci 8924514f5e3Sopenharmony_ci // get values from argv. 8934514f5e3Sopenharmony_ci uint32_t argc = argv->GetArgsNumber(); 8944514f5e3Sopenharmony_ci if (argc == 0) { 8954514f5e3Sopenharmony_ci return JSTaggedValue(base::NAN_VALUE); 8964514f5e3Sopenharmony_ci } 8974514f5e3Sopenharmony_ci 8984514f5e3Sopenharmony_ci uint32_t firstValue = code & CODE_FLAG; 8994514f5e3Sopenharmony_ci uint32_t endValue = (code >> CODE_4_BIT) & CODE_FLAG; 9004514f5e3Sopenharmony_ci uint32_t count = endValue - firstValue; 9014514f5e3Sopenharmony_ci 9024514f5e3Sopenharmony_ci if (argc < count) { 9034514f5e3Sopenharmony_ci count = argc; 9044514f5e3Sopenharmony_ci } 9054514f5e3Sopenharmony_ci if (std::isnan(timeMs) && firstValue == 0) { 9064514f5e3Sopenharmony_ci timeMs = 0.0; 9074514f5e3Sopenharmony_ci GetDateValues(timeMs, &date, false); 9084514f5e3Sopenharmony_ci } else { 9094514f5e3Sopenharmony_ci GetDateValues(timeMs, &date, isLocal); 9104514f5e3Sopenharmony_ci } 9114514f5e3Sopenharmony_ci 9124514f5e3Sopenharmony_ci for (uint32_t i = 0; i < count; i++) { 9134514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> value = base::BuiltinsBase::GetCallArg(argv, i); 9144514f5e3Sopenharmony_ci JSThread *thread = argv->GetThread(); 9154514f5e3Sopenharmony_ci JSTaggedNumber res = JSTaggedValue::ToNumber(thread, value); 9164514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 9174514f5e3Sopenharmony_ci double temp = res.GetNumber(); 9184514f5e3Sopenharmony_ci if (std::isnan(temp)) { 9194514f5e3Sopenharmony_ci return JSTaggedValue(base::NAN_VALUE); 9204514f5e3Sopenharmony_ci } 9214514f5e3Sopenharmony_ci date[firstValue + i] = NumberHelper::TruncateDouble(temp); 9224514f5e3Sopenharmony_ci } 9234514f5e3Sopenharmony_ci // set date values. 9244514f5e3Sopenharmony_ci return JSTaggedValue(SetDateValues(&date, isLocal)); 9254514f5e3Sopenharmony_ci} 9264514f5e3Sopenharmony_ci 9274514f5e3Sopenharmony_ci// static 9284514f5e3Sopenharmony_cidouble JSDate::SetDateValues(const std::array<int64_t, DATE_LENGTH> *date, bool isLocal) 9294514f5e3Sopenharmony_ci{ 9304514f5e3Sopenharmony_ci int64_t month = DateUtils::Mod((*date)[MONTH], MONTH_PER_YEAR); 9314514f5e3Sopenharmony_ci int64_t year = (*date)[YEAR] + ((*date)[MONTH] - month) / MONTH_PER_YEAR; 9324514f5e3Sopenharmony_ci int64_t days = DateUtils::GetDaysFromYear(year); 9334514f5e3Sopenharmony_ci int index = DateUtils::IsLeap(year) ? 1 : 0; 9344514f5e3Sopenharmony_ci days += DAYS_FROM_MONTH[index][month]; 9354514f5e3Sopenharmony_ci 9364514f5e3Sopenharmony_ci days += (*date)[DAYS] - 1; 9374514f5e3Sopenharmony_ci int64_t millisecond = 9384514f5e3Sopenharmony_ci (((*date)[HOUR] * MIN_PER_HOUR + (*date)[MIN]) * SEC_PER_MINUTE + (*date)[SEC]) * MS_PER_SECOND + (*date)[MS]; 9394514f5e3Sopenharmony_ci int64_t result = days * MS_PER_DAY + millisecond; 9404514f5e3Sopenharmony_ci if (isLocal) { 9414514f5e3Sopenharmony_ci int64_t offset = GetLocalOffsetFromOS(result, isLocal) * SEC_PER_MINUTE * MS_PER_SECOND; 9424514f5e3Sopenharmony_ci result -= offset; 9434514f5e3Sopenharmony_ci } 9444514f5e3Sopenharmony_ci return TimeClip(result); 9454514f5e3Sopenharmony_ci} 9464514f5e3Sopenharmony_ci 9474514f5e3Sopenharmony_cidouble JSDate::SetDateValues(int64_t year, int64_t month, int64_t day) 9484514f5e3Sopenharmony_ci{ 9494514f5e3Sopenharmony_ci if (year >= 0 && year < HUNDRED) { 9504514f5e3Sopenharmony_ci year += NINETEEN_HUNDRED_YEAR; 9514514f5e3Sopenharmony_ci } 9524514f5e3Sopenharmony_ci int64_t m = DateUtils::Mod(month, MONTH_PER_YEAR); 9534514f5e3Sopenharmony_ci int64_t y = year + (month - m) / MONTH_PER_YEAR; 9544514f5e3Sopenharmony_ci int64_t d = DateUtils::GetDaysFromYear(y); 9554514f5e3Sopenharmony_ci int index = DateUtils::IsLeap(y) ? 1 : 0; 9564514f5e3Sopenharmony_ci d += DAYS_FROM_MONTH[index][m] + day - 1; 9574514f5e3Sopenharmony_ci int64_t result = d * MS_PER_DAY; 9584514f5e3Sopenharmony_ci 9594514f5e3Sopenharmony_ci int64_t offset = GetLocalOffsetFromOS(result, true) * SEC_PER_MINUTE * MS_PER_SECOND; 9604514f5e3Sopenharmony_ci result -= offset; 9614514f5e3Sopenharmony_ci return TimeClip(result); 9624514f5e3Sopenharmony_ci} 9634514f5e3Sopenharmony_ci} // namespace panda::ecmascript 964