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 24 namespace panda::ecmascript { 25 static constexpr int64_t DAYS_IN_YEAR = 365; 26 static constexpr std::array<int, 2> APPROXIMATION_NUMBER = {100000, 3652425}; 27 static constexpr int64_t CHINA_BEFORE_1900_MS = -2177481943000; 28 static constexpr int64_t CHINA_1901_MS = -2177452800000; 29 static constexpr int CHINA_BEFORE_1901_ADDMS = 343000; 30 static constexpr int MS_PER_SECOND = 1000; 31 static constexpr int SEC_PER_MINUTE = 60; 32 static constexpr int MIN_PER_HOUR = 60; 33 static constexpr int MS_PER_HOUR = 3600 * 1000; 34 static constexpr int MS_PER_DAY = 86400000; 35 static constexpr int DAY_PER_WEEK = 7; 36 static constexpr int DATE_LENGTH = 9; 37 // the index in the Date Fields 38 static constexpr uint8_t YEAR = 0; 39 static constexpr uint8_t MONTH = 1; 40 static constexpr uint8_t DAYS = 2; 41 static constexpr uint8_t HOUR = 3; 42 static constexpr uint8_t MIN = 4; 43 static constexpr uint8_t SEC = 5; 44 static constexpr uint8_t MS = 6; 45 static constexpr uint8_t WEEKDAY = 7; 46 static constexpr uint8_t TIMEZONE = 8; 47 static constexpr int CHINA_BEFORE_1901_MIN = 485; 48 static constexpr int CHINA_AFTER_1901_MIN = 480; 49 static constexpr int CHINA_BEFORE_1901_MS = 343000; 50 static constexpr std::array<int, 3> LEAP_NUMBER = {4, 100, 400}; 51 static constexpr std::array<int, 4> YEAR_NUMBER = {1970, 1969, 1901, 1601}; 52 53 class DateUtils { 54 public: 55 static void TransferTimeToDate(int64_t timeMs, std::array<int64_t, DATE_LENGTH> *date); 56 static int64_t Mod(int64_t a, int b); 57 static bool IsLeap(int64_t year); 58 static int64_t GetDaysInYear(int64_t year); 59 static int64_t GetDaysFromYear(int64_t year); 60 // return the year, update days. 61 static int64_t GetYearFromDays(int64_t *days); 62 static int64_t FloorDiv(int64_t a, int64_t b); 63 64 private: 65 static bool isCached_; 66 static int32_t preSumDays_; 67 static int32_t preDays_; 68 static int32_t preYear_; 69 }; 70 class JSDate : public JSObject { 71 public: 72 CAST_CHECK(JSDate, IsDate); 73 74 static constexpr size_t TIME_VALUE_OFFSET = JSObject::SIZE; 75 ACCESSORS(TimeValue, TIME_VALUE_OFFSET, LOCAL_TIME_OFFSET) 76 ACCESSORS(LocalOffset, LOCAL_TIME_OFFSET, SIZE) // localoffset in min 77 78 DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSObject, TIME_VALUE_OFFSET, SIZE) 79 80 static double MakeDay(double year, double month, double date); 81 static double MakeTime(double hour, double min, double sec, double ms); 82 static double MakeDate(double day, double time); 83 static double TimeClip(double time); 84 static JSTaggedValue LocalParseStringToMs(const CString &str); 85 static JSTaggedValue UtcParseStringToMs(const CString &str); 86 static JSTaggedValue IsoParseStringToMs(const CString &str); 87 static int GetSignedNumFromString(const CString &str, int len, int *index); 88 static bool GetNumFromString(const CString &str, int len, int *index, int *num); 89 90 // 20.4.1.7 91 int64_t GetLocalOffsetInMin(const JSThread *thread, int64_t timeMs, bool isLocal); 92 93 // 20.4.1.8 94 double LocalTime(double timeMs) const; 95 96 // 20.4.1.9 97 double UTCTime(double timeMs) const; 98 99 // 20.4.3.1 100 static JSTaggedValue Now(); 101 102 // 20.4.3.2 103 static JSTaggedValue Parse(EcmaRuntimeCallInfo *argv); 104 105 // 20.4.3.4 106 static JSTaggedValue UTC(EcmaRuntimeCallInfo *argv); 107 108 // 20.4.4.10 109 JSTaggedValue GetTime() const; 110 111 // 20.4.4.19 112 JSTaggedValue GetUTCSeconds(); 113 114 // 20.4.4.35 115 JSTaggedValue ToDateString(JSThread *thread) const; 116 static CString ToDateString(double timeMs); 117 118 // 20.4.4.36 119 JSTaggedValue ToISOString(JSThread *thread) const; 120 121 // 20.4.4.38 122 JSTaggedValue ToLocaleDateString(JSThread *thread) const; 123 124 // 20.4.4.39 125 JSTaggedValue ToLocaleString(JSThread *thread) const; 126 127 // 20.4.4.40 128 JSTaggedValue ToLocaleTimeString(JSThread *thread) const; 129 130 // 20.4.4.41 131 JSTaggedValue ToString(JSThread *thread) const; 132 133 // 20.4.4.42 134 JSTaggedValue ToTimeString(JSThread *thread) const; 135 136 // 20.4.4.43 137 JSTaggedValue ToUTCString(JSThread *thread) const; 138 139 // 20.4.4.44 140 JSTaggedValue ValueOf() const; 141 142 JSTaggedValue SetDateValue(EcmaRuntimeCallInfo *argv, uint32_t code, bool isLocal) const; 143 double GetDateValue(double timeMs, uint8_t code, bool isLocal) const; 144 145 static constexpr double MAX_DOUBLE = std::numeric_limits<double>::max(); 146 static constexpr double MAX_INT = std::numeric_limits<int>::max(); 147 static constexpr uint16_t NINETEEN_HUNDRED_YEAR = 1900; 148 static constexpr uint16_t HUNDRED = 100; 149 static constexpr uint16_t THOUSAND = 1000; 150 static double SetDateValues(const std::array<int64_t, DATE_LENGTH> *date, bool isLocal); 151 static void GetDateValues(double timeMs, std::array<int64_t, DATE_LENGTH> *date, bool isLocal); 152 static int64_t GetLocalOffsetFromOS(int64_t timeMs, bool isLocal); 153 static CString StrToTargetLength(const CString &str, int length); 154 DECL_DUMP() 155 156 private: 157 bool GetThisDateValues(std::array<int64_t, DATE_LENGTH> *date, bool isLocal) const; 158 CString GetLocaleTimeStr(const std::array<int64_t, DATE_LENGTH> &fields) const; 159 CString GetLocaleDateStr(const std::array<int64_t, DATE_LENGTH> &fields) const; 160 static int64_t MathMod(int64_t a, int b); 161 162 static constexpr int MINUTE_PER_HOUR = 60; 163 static constexpr int MOUTH_PER_YEAR = 12; 164 static constexpr std::array<int, 12> MONTH_DAYS = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 165 // NOLINTNEXTLINE(readability-braces-around-statements,bugprone-suspicious-semicolon) 166 static constexpr int DAYS_FROM_MONTH [2][13] = { 167 {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365}, 168 {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366} 169 }; 170 static constexpr int STR_LENGTH_YEAR = 4; 171 static constexpr int STR_LENGTH_OTHERS = 2; 172 static constexpr int MONTH_PER_YEAR = 12; 173 static constexpr int YEAR_DELTA = 399999; 174 static constexpr int LINE_YEAR = 1970; 175 static constexpr int CENTURY = 100; 176 static constexpr char NEG = '-'; 177 static constexpr char PLUS = '+'; 178 static constexpr char SPACE = ' '; 179 static constexpr char COLON = ':'; 180 static constexpr char POINT = '.'; 181 static constexpr int LENGTH_MONTH_NAME = 3; 182 static constexpr int MS_PER_MINUTE = 60000; 183 static constexpr int64_t MAX_TIME_IN_MS = static_cast<int64_t>(864000000) * 10000000; 184 static constexpr int TEN = 10; 185 static constexpr char FLAG_TIME = 'T'; 186 static constexpr char FLAG_UTC = 'Z'; 187 static constexpr char VIRGULE = '/'; 188 static constexpr char COMMA = ','; 189 static constexpr int LENGTH_PER_TIME = 3; 190 static constexpr int MIN_LENGTH = 10; 191 static constexpr int INDEX_PLUS_NEG = 6; 192 static constexpr int NUM_NINE = 9; 193 static constexpr int ORIGIN_YEAR = 1901; 194 195 static constexpr uint32_t CODE_FLAG = 0x0FULL; 196 static constexpr size_t CODE_4_BIT = 4; 197 }; 198 } // namespace panda::ecmascript 199 200 #endif // ECMASCRIPT_JSDATE_H 201