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