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#ifndef ECMASCRIPT_JSDATE_H 174514f5e3Sopenharmony_ci#define ECMASCRIPT_JSDATE_H 184514f5e3Sopenharmony_ci 194514f5e3Sopenharmony_ci#include <array> 204514f5e3Sopenharmony_ci 214514f5e3Sopenharmony_ci#include "ecmascript/ecma_runtime_call_info.h" 224514f5e3Sopenharmony_ci#include "ecmascript/js_tagged_value-inl.h" 234514f5e3Sopenharmony_ci 244514f5e3Sopenharmony_cinamespace panda::ecmascript { 254514f5e3Sopenharmony_cistatic constexpr int64_t DAYS_IN_YEAR = 365; 264514f5e3Sopenharmony_cistatic constexpr std::array<int, 2> APPROXIMATION_NUMBER = {100000, 3652425}; 274514f5e3Sopenharmony_cistatic constexpr int64_t CHINA_BEFORE_1900_MS = -2177481943000; 284514f5e3Sopenharmony_cistatic constexpr int64_t CHINA_1901_MS = -2177452800000; 294514f5e3Sopenharmony_cistatic constexpr int CHINA_BEFORE_1901_ADDMS = 343000; 304514f5e3Sopenharmony_cistatic constexpr int MS_PER_SECOND = 1000; 314514f5e3Sopenharmony_cistatic constexpr int SEC_PER_MINUTE = 60; 324514f5e3Sopenharmony_cistatic constexpr int SEC_PER_HOUR = 3600; 334514f5e3Sopenharmony_cistatic constexpr int MIN_PER_HOUR = 60; 344514f5e3Sopenharmony_cistatic constexpr int MS_PER_HOUR = 3600 * 1000; 354514f5e3Sopenharmony_cistatic constexpr int MS_PER_DAY = 86400000; 364514f5e3Sopenharmony_cistatic constexpr int DAY_PER_WEEK = 7; 374514f5e3Sopenharmony_cistatic constexpr int DATE_LENGTH = 9; 384514f5e3Sopenharmony_cistatic constexpr int DATE_STRING_LENGTH = 15; 394514f5e3Sopenharmony_cistatic constexpr int DATE_CSTRING_LENGTH = 36; 404514f5e3Sopenharmony_cistatic constexpr int ISO_STRING_LENGTH = 25; 414514f5e3Sopenharmony_cistatic constexpr int TO_STRING_LENGTH = 36; 424514f5e3Sopenharmony_cistatic constexpr int TIME_STRING_LENGTH = 18; 434514f5e3Sopenharmony_cistatic constexpr int UTC_STRING_LENGTH = 29; 444514f5e3Sopenharmony_ci// the index in the Date Fields 454514f5e3Sopenharmony_cistatic constexpr uint8_t YEAR = 0; 464514f5e3Sopenharmony_cistatic constexpr uint8_t MONTH = 1; 474514f5e3Sopenharmony_cistatic constexpr uint8_t DAYS = 2; 484514f5e3Sopenharmony_cistatic constexpr uint8_t HOUR = 3; 494514f5e3Sopenharmony_cistatic constexpr uint8_t MIN = 4; 504514f5e3Sopenharmony_cistatic constexpr uint8_t SEC = 5; 514514f5e3Sopenharmony_cistatic constexpr uint8_t MS = 6; 524514f5e3Sopenharmony_cistatic constexpr uint8_t WEEKDAY = 7; 534514f5e3Sopenharmony_cistatic constexpr uint8_t TIMEZONE = 8; 544514f5e3Sopenharmony_cistatic constexpr int CHINA_BEFORE_1901_MIN = 485; 554514f5e3Sopenharmony_cistatic constexpr int CHINA_AFTER_1901_MIN = 480; 564514f5e3Sopenharmony_cistatic constexpr int CHINA_BEFORE_1901_MS = 343000; 574514f5e3Sopenharmony_cistatic constexpr std::array<int, 3> LEAP_NUMBER = {4, 100, 400}; 584514f5e3Sopenharmony_cistatic constexpr std::array<int, 4> YEAR_NUMBER = {1970, 1969, 1901, 1601}; 594514f5e3Sopenharmony_cistatic constexpr int DAYS_1970_TO_0000 = 719468; 604514f5e3Sopenharmony_cistatic constexpr int DAYS_IN_4_YEARS = 1460; 614514f5e3Sopenharmony_cistatic constexpr int DAYS_IN_100_YEARS = 36524; 624514f5e3Sopenharmony_cistatic constexpr int DAYS_IN_400_YEARS = 146097; 634514f5e3Sopenharmony_cistatic constexpr int DAYS_MAR_TO_DEC = 306; 644514f5e3Sopenharmony_cistatic constexpr int DAYS_JAN_AND_FEB = 59; 654514f5e3Sopenharmony_cistatic constexpr int MONTH_COEFFICIENT = 2; 664514f5e3Sopenharmony_cistatic constexpr int MOUTH_PER_YEAR = 12; 674514f5e3Sopenharmony_cistatic constexpr std::array<int, 2> COEFFICIENT_TO_CIVIL = {5, 153}; 684514f5e3Sopenharmony_cistatic constexpr std::array<int, 3> MONTH_TRANSFORM = {3, 10, -9}; 694514f5e3Sopenharmony_cistatic constexpr int DAYS_FEBRUARY = 28; 704514f5e3Sopenharmony_cistatic constexpr char DEL = 127; 714514f5e3Sopenharmony_ci 724514f5e3Sopenharmony_ciclass DateUtils { 734514f5e3Sopenharmony_cipublic: 744514f5e3Sopenharmony_ci static void TransferTimeToDate(int64_t timeMs, std::array<int64_t, DATE_LENGTH> *date); 754514f5e3Sopenharmony_ci static int64_t Mod(int64_t a, int b); 764514f5e3Sopenharmony_ci static bool IsLeap(int64_t year); 774514f5e3Sopenharmony_ci static int64_t GetDaysInYear(int64_t year); 784514f5e3Sopenharmony_ci static int64_t GetDaysFromYear(int64_t year); 794514f5e3Sopenharmony_ci // return the year, update days. 804514f5e3Sopenharmony_ci static void GetYearFromDays(std::array<int64_t, DATE_LENGTH> *date); 814514f5e3Sopenharmony_ci static int64_t FloorDiv(int64_t a, int64_t b); 824514f5e3Sopenharmony_ci 834514f5e3Sopenharmony_ciprivate: 844514f5e3Sopenharmony_ci static bool isCached_; 854514f5e3Sopenharmony_ci static int preSumDays_; 864514f5e3Sopenharmony_ci static int preDays_; 874514f5e3Sopenharmony_ci static int preMonth_; 884514f5e3Sopenharmony_ci static int preYear_; 894514f5e3Sopenharmony_ci}; 904514f5e3Sopenharmony_ciclass JSDate : public JSObject { 914514f5e3Sopenharmony_cipublic: 924514f5e3Sopenharmony_ci CAST_CHECK(JSDate, IsDate); 934514f5e3Sopenharmony_ci 944514f5e3Sopenharmony_ci static constexpr size_t TIME_VALUE_OFFSET = JSObject::SIZE; 954514f5e3Sopenharmony_ci ACCESSORS(TimeValue, TIME_VALUE_OFFSET, LOCAL_TIME_OFFSET) 964514f5e3Sopenharmony_ci ACCESSORS(LocalOffset, LOCAL_TIME_OFFSET, SIZE) // localoffset in min 974514f5e3Sopenharmony_ci 984514f5e3Sopenharmony_ci DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSObject, TIME_VALUE_OFFSET, SIZE) 994514f5e3Sopenharmony_ci 1004514f5e3Sopenharmony_ci static double MakeDay(double year, double month, double date); 1014514f5e3Sopenharmony_ci static double MakeTime(double hour, double min, double sec, double ms); 1024514f5e3Sopenharmony_ci static double MakeDate(double day, double time); 1034514f5e3Sopenharmony_ci static double TimeClip(double time); 1044514f5e3Sopenharmony_ci static JSTaggedValue LocalParseStringToMs(const CString &str); 1054514f5e3Sopenharmony_ci static JSTaggedValue UtcParseStringToMs(const CString &str); 1064514f5e3Sopenharmony_ci static JSTaggedValue IsoParseStringToMs(const CString &str); 1074514f5e3Sopenharmony_ci static int GetSignedNumFromString(const CString &str, int len, int *index); 1084514f5e3Sopenharmony_ci static bool GetNumFromString(const CString &str, int len, int *index, int *num); 1094514f5e3Sopenharmony_ci 1104514f5e3Sopenharmony_ci // 20.4.1.7 1114514f5e3Sopenharmony_ci int64_t GetLocalOffsetInMin(const JSThread *thread, int64_t timeMs, bool isLocal); 1124514f5e3Sopenharmony_ci 1134514f5e3Sopenharmony_ci // 20.4.1.8 1144514f5e3Sopenharmony_ci double LocalTime(double timeMs) const; 1154514f5e3Sopenharmony_ci 1164514f5e3Sopenharmony_ci // 20.4.1.9 1174514f5e3Sopenharmony_ci double UTCTime(double timeMs) const; 1184514f5e3Sopenharmony_ci 1194514f5e3Sopenharmony_ci // 20.4.3.1 1204514f5e3Sopenharmony_ci static JSTaggedValue Now(); 1214514f5e3Sopenharmony_ci 1224514f5e3Sopenharmony_ci // 20.4.3.2 1234514f5e3Sopenharmony_ci static JSTaggedValue Parse(EcmaRuntimeCallInfo *argv); 1244514f5e3Sopenharmony_ci 1254514f5e3Sopenharmony_ci // 20.4.3.4 1264514f5e3Sopenharmony_ci static JSTaggedValue UTC(EcmaRuntimeCallInfo *argv); 1274514f5e3Sopenharmony_ci 1284514f5e3Sopenharmony_ci // 20.4.4.10 1294514f5e3Sopenharmony_ci JSTaggedValue GetTime() const; 1304514f5e3Sopenharmony_ci 1314514f5e3Sopenharmony_ci // 20.4.4.19 1324514f5e3Sopenharmony_ci JSTaggedValue GetUTCSeconds(); 1334514f5e3Sopenharmony_ci 1344514f5e3Sopenharmony_ci // 20.4.4.35 1354514f5e3Sopenharmony_ci JSTaggedValue ToDateString(JSThread *thread) const; 1364514f5e3Sopenharmony_ci static CString ToDateString(double timeMs); 1374514f5e3Sopenharmony_ci 1384514f5e3Sopenharmony_ci // 20.4.4.36 1394514f5e3Sopenharmony_ci JSTaggedValue ToISOString(JSThread *thread) const; 1404514f5e3Sopenharmony_ci 1414514f5e3Sopenharmony_ci // 20.4.4.41 1424514f5e3Sopenharmony_ci JSTaggedValue ToString(JSThread *thread) const; 1434514f5e3Sopenharmony_ci 1444514f5e3Sopenharmony_ci // 20.4.4.42 1454514f5e3Sopenharmony_ci JSTaggedValue ToTimeString(JSThread *thread) const; 1464514f5e3Sopenharmony_ci 1474514f5e3Sopenharmony_ci // 20.4.4.43 1484514f5e3Sopenharmony_ci JSTaggedValue ToUTCString(JSThread *thread) const; 1494514f5e3Sopenharmony_ci 1504514f5e3Sopenharmony_ci // 20.4.4.44 1514514f5e3Sopenharmony_ci JSTaggedValue ValueOf() const; 1524514f5e3Sopenharmony_ci 1534514f5e3Sopenharmony_ci JSTaggedValue SetDateValue(EcmaRuntimeCallInfo *argv, uint32_t code, bool isLocal) const; 1544514f5e3Sopenharmony_ci double GetDateValue(double timeMs, uint8_t code, bool isLocal) const; 1554514f5e3Sopenharmony_ci static JSTaggedValue GetTimeFromString(const char *str, int len); 1564514f5e3Sopenharmony_ci 1574514f5e3Sopenharmony_ci static constexpr double MAX_DOUBLE = std::numeric_limits<double>::max(); 1584514f5e3Sopenharmony_ci static constexpr double MAX_INT = std::numeric_limits<int>::max(); 1594514f5e3Sopenharmony_ci static constexpr uint16_t NINETEEN_HUNDRED_YEAR = 1900; 1604514f5e3Sopenharmony_ci static constexpr uint16_t THOUSAND = 1000; 1614514f5e3Sopenharmony_ci static constexpr uint16_t HUNDRED = 100; 1624514f5e3Sopenharmony_ci static constexpr int TEN = 10; 1634514f5e3Sopenharmony_ci static constexpr int NUM_NINE = 9; 1644514f5e3Sopenharmony_ci static constexpr int MONTH_PER_YEAR = 12; 1654514f5e3Sopenharmony_ci static constexpr int MAX_DAYS_MONTH = 31; 1664514f5e3Sopenharmony_ci static double SetDateValues(const std::array<int64_t, DATE_LENGTH> *date, bool isLocal); 1674514f5e3Sopenharmony_ci static double SetDateValues(int64_t year, int64_t month, int64_t day); 1684514f5e3Sopenharmony_ci static void GetDateValues(double timeMs, std::array<int64_t, DATE_LENGTH> *date, bool isLocal); 1694514f5e3Sopenharmony_ci static CString StrToTargetLength(const CString &str, int length); 1704514f5e3Sopenharmony_ci static void AppendStrToTargetLength(const CString &str, int length, CString &target); 1714514f5e3Sopenharmony_ci DECL_DUMP() 1724514f5e3Sopenharmony_ci 1734514f5e3Sopenharmony_ciprivate: 1744514f5e3Sopenharmony_ci bool GetThisDateValues(std::array<int64_t, DATE_LENGTH> *date, bool isLocal) const; 1754514f5e3Sopenharmony_ci CString GetLocaleTimeStr(const std::array<int64_t, DATE_LENGTH> &fields) const; 1764514f5e3Sopenharmony_ci CString GetLocaleDateStr(const std::array<int64_t, DATE_LENGTH> &fields) const; 1774514f5e3Sopenharmony_ci static int64_t MathMod(int64_t a, int b); 1784514f5e3Sopenharmony_ci template<class T> 1794514f5e3Sopenharmony_ci inline static void ConvertAndAppend(T number, int length, CString& str) 1804514f5e3Sopenharmony_ci { 1814514f5e3Sopenharmony_ci const CString cStr = ToCString(number); 1824514f5e3Sopenharmony_ci AppendStrToTargetLength(cStr, length, str); 1834514f5e3Sopenharmony_ci } 1844514f5e3Sopenharmony_ci 1854514f5e3Sopenharmony_ci static constexpr int MINUTE_PER_HOUR = 60; 1864514f5e3Sopenharmony_ci static constexpr std::array<int, 12> MONTH_DAYS = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 1874514f5e3Sopenharmony_ci // NOLINTNEXTLINE(readability-braces-around-statements,bugprone-suspicious-semicolon) 1884514f5e3Sopenharmony_ci static constexpr int DAYS_FROM_MONTH [2][13] = { 1894514f5e3Sopenharmony_ci {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365}, 1904514f5e3Sopenharmony_ci {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366} 1914514f5e3Sopenharmony_ci }; 1924514f5e3Sopenharmony_ci static constexpr int STR_LENGTH_YEAR = 4; 1934514f5e3Sopenharmony_ci static constexpr int STR_LENGTH_OTHERS = 2; 1944514f5e3Sopenharmony_ci static constexpr int YEAR_DELTA = 399999; 1954514f5e3Sopenharmony_ci static constexpr int LINE_YEAR = 1970; 1964514f5e3Sopenharmony_ci static constexpr int CENTURY = 100; 1974514f5e3Sopenharmony_ci static constexpr char NEG = '-'; 1984514f5e3Sopenharmony_ci static constexpr char PLUS = '+'; 1994514f5e3Sopenharmony_ci static constexpr char SPACE = ' '; 2004514f5e3Sopenharmony_ci static constexpr char COLON = ':'; 2014514f5e3Sopenharmony_ci static constexpr char POINT = '.'; 2024514f5e3Sopenharmony_ci static constexpr std::string_view NEG_STR = "-"; 2034514f5e3Sopenharmony_ci static constexpr std::string_view COMMA_STR = ","; 2044514f5e3Sopenharmony_ci static constexpr std::string_view SPACE_STR = " "; 2054514f5e3Sopenharmony_ci static constexpr int LENGTH_MONTH_NAME = 3; 2064514f5e3Sopenharmony_ci static constexpr int MS_PER_MINUTE = 60000; 2074514f5e3Sopenharmony_ci static constexpr int64_t MAX_TIME_IN_MS = static_cast<int64_t>(864000000) * 10000000; 2084514f5e3Sopenharmony_ci static constexpr char FLAG_TIME = 'T'; 2094514f5e3Sopenharmony_ci static constexpr char FLAG_UTC = 'Z'; 2104514f5e3Sopenharmony_ci static constexpr char VIRGULE = '/'; 2114514f5e3Sopenharmony_ci static constexpr char COMMA = ','; 2124514f5e3Sopenharmony_ci static constexpr int LENGTH_PER_TIME = 3; 2134514f5e3Sopenharmony_ci static constexpr int MIN_LENGTH = 10; 2144514f5e3Sopenharmony_ci static constexpr int INDEX_PLUS_NEG = 6; 2154514f5e3Sopenharmony_ci static constexpr int ORIGIN_YEAR = 1901; 2164514f5e3Sopenharmony_ci static constexpr uint32_t CODE_FLAG = 0x0FULL; 2174514f5e3Sopenharmony_ci static constexpr size_t CODE_4_BIT = 4; 2184514f5e3Sopenharmony_ci}; 2194514f5e3Sopenharmony_ci} // namespace panda::ecmascript 2204514f5e3Sopenharmony_ci 2214514f5e3Sopenharmony_ci#endif // ECMASCRIPT_JSDATE_H 222