1/* 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#ifndef ECMASCRIPT_JSDATE_H 17#define ECMASCRIPT_JSDATE_H 18 19#include <array> 20 21#include "ecmascript/ecma_runtime_call_info.h" 22#include "ecmascript/js_tagged_value-inl.h" 23 24namespace panda::ecmascript { 25static constexpr int64_t DAYS_IN_YEAR = 365; 26static constexpr std::array<int, 2> APPROXIMATION_NUMBER = {100000, 3652425}; 27static constexpr int64_t CHINA_BEFORE_1900_MS = -2177481943000; 28static constexpr int64_t CHINA_1901_MS = -2177452800000; 29static constexpr int CHINA_BEFORE_1901_ADDMS = 343000; 30static constexpr int MS_PER_SECOND = 1000; 31static constexpr int SEC_PER_MINUTE = 60; 32static constexpr int SEC_PER_HOUR = 3600; 33static constexpr int MIN_PER_HOUR = 60; 34static constexpr int MS_PER_HOUR = 3600 * 1000; 35static constexpr int MS_PER_DAY = 86400000; 36static constexpr int DAY_PER_WEEK = 7; 37static constexpr int DATE_LENGTH = 9; 38static constexpr int DATE_STRING_LENGTH = 15; 39static constexpr int DATE_CSTRING_LENGTH = 36; 40static constexpr int ISO_STRING_LENGTH = 25; 41static constexpr int TO_STRING_LENGTH = 36; 42static constexpr int TIME_STRING_LENGTH = 18; 43static constexpr int UTC_STRING_LENGTH = 29; 44// the index in the Date Fields 45static constexpr uint8_t YEAR = 0; 46static constexpr uint8_t MONTH = 1; 47static constexpr uint8_t DAYS = 2; 48static constexpr uint8_t HOUR = 3; 49static constexpr uint8_t MIN = 4; 50static constexpr uint8_t SEC = 5; 51static constexpr uint8_t MS = 6; 52static constexpr uint8_t WEEKDAY = 7; 53static constexpr uint8_t TIMEZONE = 8; 54static constexpr int CHINA_BEFORE_1901_MIN = 485; 55static constexpr int CHINA_AFTER_1901_MIN = 480; 56static constexpr int CHINA_BEFORE_1901_MS = 343000; 57static constexpr std::array<int, 3> LEAP_NUMBER = {4, 100, 400}; 58static constexpr std::array<int, 4> YEAR_NUMBER = {1970, 1969, 1901, 1601}; 59static constexpr int DAYS_1970_TO_0000 = 719468; 60static constexpr int DAYS_IN_4_YEARS = 1460; 61static constexpr int DAYS_IN_100_YEARS = 36524; 62static constexpr int DAYS_IN_400_YEARS = 146097; 63static constexpr int DAYS_MAR_TO_DEC = 306; 64static constexpr int DAYS_JAN_AND_FEB = 59; 65static constexpr int MONTH_COEFFICIENT = 2; 66static constexpr int MOUTH_PER_YEAR = 12; 67static constexpr std::array<int, 2> COEFFICIENT_TO_CIVIL = {5, 153}; 68static constexpr std::array<int, 3> MONTH_TRANSFORM = {3, 10, -9}; 69static constexpr int DAYS_FEBRUARY = 28; 70static constexpr char DEL = 127; 71 72class DateUtils { 73public: 74 static void TransferTimeToDate(int64_t timeMs, std::array<int64_t, DATE_LENGTH> *date); 75 static int64_t Mod(int64_t a, int b); 76 static bool IsLeap(int64_t year); 77 static int64_t GetDaysInYear(int64_t year); 78 static int64_t GetDaysFromYear(int64_t year); 79 // return the year, update days. 80 static void GetYearFromDays(std::array<int64_t, DATE_LENGTH> *date); 81 static int64_t FloorDiv(int64_t a, int64_t b); 82 83private: 84 static bool isCached_; 85 static int preSumDays_; 86 static int preDays_; 87 static int preMonth_; 88 static int preYear_; 89}; 90class JSDate : public JSObject { 91public: 92 CAST_CHECK(JSDate, IsDate); 93 94 static constexpr size_t TIME_VALUE_OFFSET = JSObject::SIZE; 95 ACCESSORS(TimeValue, TIME_VALUE_OFFSET, LOCAL_TIME_OFFSET) 96 ACCESSORS(LocalOffset, LOCAL_TIME_OFFSET, SIZE) // localoffset in min 97 98 DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSObject, TIME_VALUE_OFFSET, SIZE) 99 100 static double MakeDay(double year, double month, double date); 101 static double MakeTime(double hour, double min, double sec, double ms); 102 static double MakeDate(double day, double time); 103 static double TimeClip(double time); 104 static JSTaggedValue LocalParseStringToMs(const CString &str); 105 static JSTaggedValue UtcParseStringToMs(const CString &str); 106 static JSTaggedValue IsoParseStringToMs(const CString &str); 107 static int GetSignedNumFromString(const CString &str, int len, int *index); 108 static bool GetNumFromString(const CString &str, int len, int *index, int *num); 109 110 // 20.4.1.7 111 int64_t GetLocalOffsetInMin(const JSThread *thread, int64_t timeMs, bool isLocal); 112 113 // 20.4.1.8 114 double LocalTime(double timeMs) const; 115 116 // 20.4.1.9 117 double UTCTime(double timeMs) const; 118 119 // 20.4.3.1 120 static JSTaggedValue Now(); 121 122 // 20.4.3.2 123 static JSTaggedValue Parse(EcmaRuntimeCallInfo *argv); 124 125 // 20.4.3.4 126 static JSTaggedValue UTC(EcmaRuntimeCallInfo *argv); 127 128 // 20.4.4.10 129 JSTaggedValue GetTime() const; 130 131 // 20.4.4.19 132 JSTaggedValue GetUTCSeconds(); 133 134 // 20.4.4.35 135 JSTaggedValue ToDateString(JSThread *thread) const; 136 static CString ToDateString(double timeMs); 137 138 // 20.4.4.36 139 JSTaggedValue ToISOString(JSThread *thread) const; 140 141 // 20.4.4.41 142 JSTaggedValue ToString(JSThread *thread) const; 143 144 // 20.4.4.42 145 JSTaggedValue ToTimeString(JSThread *thread) const; 146 147 // 20.4.4.43 148 JSTaggedValue ToUTCString(JSThread *thread) const; 149 150 // 20.4.4.44 151 JSTaggedValue ValueOf() const; 152 153 JSTaggedValue SetDateValue(EcmaRuntimeCallInfo *argv, uint32_t code, bool isLocal) const; 154 double GetDateValue(double timeMs, uint8_t code, bool isLocal) const; 155 static JSTaggedValue GetTimeFromString(const char *str, int len); 156 157 static constexpr double MAX_DOUBLE = std::numeric_limits<double>::max(); 158 static constexpr double MAX_INT = std::numeric_limits<int>::max(); 159 static constexpr uint16_t NINETEEN_HUNDRED_YEAR = 1900; 160 static constexpr uint16_t THOUSAND = 1000; 161 static constexpr uint16_t HUNDRED = 100; 162 static constexpr int TEN = 10; 163 static constexpr int NUM_NINE = 9; 164 static constexpr int MONTH_PER_YEAR = 12; 165 static constexpr int MAX_DAYS_MONTH = 31; 166 static double SetDateValues(const std::array<int64_t, DATE_LENGTH> *date, bool isLocal); 167 static double SetDateValues(int64_t year, int64_t month, int64_t day); 168 static void GetDateValues(double timeMs, std::array<int64_t, DATE_LENGTH> *date, bool isLocal); 169 static CString StrToTargetLength(const CString &str, int length); 170 static void AppendStrToTargetLength(const CString &str, int length, CString &target); 171 DECL_DUMP() 172 173private: 174 bool GetThisDateValues(std::array<int64_t, DATE_LENGTH> *date, bool isLocal) const; 175 CString GetLocaleTimeStr(const std::array<int64_t, DATE_LENGTH> &fields) const; 176 CString GetLocaleDateStr(const std::array<int64_t, DATE_LENGTH> &fields) const; 177 static int64_t MathMod(int64_t a, int b); 178 template<class T> 179 inline static void ConvertAndAppend(T number, int length, CString& str) 180 { 181 const CString cStr = ToCString(number); 182 AppendStrToTargetLength(cStr, length, str); 183 } 184 185 static constexpr int MINUTE_PER_HOUR = 60; 186 static constexpr std::array<int, 12> MONTH_DAYS = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 187 // NOLINTNEXTLINE(readability-braces-around-statements,bugprone-suspicious-semicolon) 188 static constexpr int DAYS_FROM_MONTH [2][13] = { 189 {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365}, 190 {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366} 191 }; 192 static constexpr int STR_LENGTH_YEAR = 4; 193 static constexpr int STR_LENGTH_OTHERS = 2; 194 static constexpr int YEAR_DELTA = 399999; 195 static constexpr int LINE_YEAR = 1970; 196 static constexpr int CENTURY = 100; 197 static constexpr char NEG = '-'; 198 static constexpr char PLUS = '+'; 199 static constexpr char SPACE = ' '; 200 static constexpr char COLON = ':'; 201 static constexpr char POINT = '.'; 202 static constexpr std::string_view NEG_STR = "-"; 203 static constexpr std::string_view COMMA_STR = ","; 204 static constexpr std::string_view SPACE_STR = " "; 205 static constexpr int LENGTH_MONTH_NAME = 3; 206 static constexpr int MS_PER_MINUTE = 60000; 207 static constexpr int64_t MAX_TIME_IN_MS = static_cast<int64_t>(864000000) * 10000000; 208 static constexpr char FLAG_TIME = 'T'; 209 static constexpr char FLAG_UTC = 'Z'; 210 static constexpr char VIRGULE = '/'; 211 static constexpr char COMMA = ','; 212 static constexpr int LENGTH_PER_TIME = 3; 213 static constexpr int MIN_LENGTH = 10; 214 static constexpr int INDEX_PLUS_NEG = 6; 215 static constexpr int ORIGIN_YEAR = 1901; 216 static constexpr uint32_t CODE_FLAG = 0x0FULL; 217 static constexpr size_t CODE_4_BIT = 4; 218}; 219} // namespace panda::ecmascript 220 221#endif // ECMASCRIPT_JSDATE_H 222