14514f5e3Sopenharmony_ci/*
24514f5e3Sopenharmony_ci * Copyright (c) 2023 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/date_parse.h"
174514f5e3Sopenharmony_ci
184514f5e3Sopenharmony_cinamespace panda::ecmascript {
194514f5e3Sopenharmony_ci    const std::array<CString, MOUTH_PER_YEAR> DateParse::MONTH_NAME = {
204514f5e3Sopenharmony_ci    "jan", "feb", "mar", "apr", "may", "jun",
214514f5e3Sopenharmony_ci    "jul", "aug", "sep", "oct", "nov", "dec"
224514f5e3Sopenharmony_ci};
234514f5e3Sopenharmony_cibool DateParse::ParseDateString(const char *str, int length, int *time)
244514f5e3Sopenharmony_ci{
254514f5e3Sopenharmony_ci    StringReader reader(str, length);
264514f5e3Sopenharmony_ci    DateProxy proxy(&reader);
274514f5e3Sopenharmony_ci    DayValue dayValue;
284514f5e3Sopenharmony_ci    TimeValue timeValue;
294514f5e3Sopenharmony_ci    TimeZone timeZone;
304514f5e3Sopenharmony_ci    bool isIso = IsIsoDateTime(&proxy, &dayValue);
314514f5e3Sopenharmony_ci    bool result;
324514f5e3Sopenharmony_ci    if (isIso) {
334514f5e3Sopenharmony_ci        result =  ParseIsoDateTime(&proxy, &dayValue, &timeValue, &timeZone);
344514f5e3Sopenharmony_ci    } else {
354514f5e3Sopenharmony_ci        result = ParseLegacyDates(&proxy, &dayValue, &timeValue, &timeZone);
364514f5e3Sopenharmony_ci    }
374514f5e3Sopenharmony_ci    if (result) {
384514f5e3Sopenharmony_ci        bool success = timeZone.SetTimeZone(time) && timeValue.SetTimeValue(time) && dayValue.SetDayValue(time);
394514f5e3Sopenharmony_ci        return success;
404514f5e3Sopenharmony_ci    } else {
414514f5e3Sopenharmony_ci        return false;
424514f5e3Sopenharmony_ci    }
434514f5e3Sopenharmony_ci}
444514f5e3Sopenharmony_ci
454514f5e3Sopenharmony_cibool DateParse::IsIsoDateTime(DateProxy *proxy, DayValue *dayValue)
464514f5e3Sopenharmony_ci{
474514f5e3Sopenharmony_ci    if (proxy->GetDate().IsSign()) {
484514f5e3Sopenharmony_ci        DateUnit sign = proxy->NextDate();
494514f5e3Sopenharmony_ci        if (!proxy->GetDate().IsSixDecimalDigit()) {
504514f5e3Sopenharmony_ci            return false;
514514f5e3Sopenharmony_ci        }
524514f5e3Sopenharmony_ci        int signYear = proxy->NextDate().GetValue();
534514f5e3Sopenharmony_ci        if (sign.IsSymbol('-') && signYear == 0) {
544514f5e3Sopenharmony_ci            return false;
554514f5e3Sopenharmony_ci        }
564514f5e3Sopenharmony_ci        if (sign.IsSymbol('-')) {
574514f5e3Sopenharmony_ci            signYear = -signYear;
584514f5e3Sopenharmony_ci        }
594514f5e3Sopenharmony_ci        dayValue->SetData(signYear);
604514f5e3Sopenharmony_ci    } else if (proxy->GetDate().IsFourDecimalDigit()) {
614514f5e3Sopenharmony_ci        int year = proxy->NextDate().GetValue();
624514f5e3Sopenharmony_ci        dayValue->SetData(year);
634514f5e3Sopenharmony_ci    } else {
644514f5e3Sopenharmony_ci        return false;
654514f5e3Sopenharmony_ci    }
664514f5e3Sopenharmony_ci    if (proxy->GetDate().IsSymbol('-')) {
674514f5e3Sopenharmony_ci        proxy->NextDate();
684514f5e3Sopenharmony_ci        DateUnit mon = proxy->GetDate();
694514f5e3Sopenharmony_ci        if (!mon.IsTwoDecimalDigit()) {
704514f5e3Sopenharmony_ci            return false;
714514f5e3Sopenharmony_ci        }
724514f5e3Sopenharmony_ci        dayValue->SetData(mon.GetValue());
734514f5e3Sopenharmony_ci        proxy->NextDate();
744514f5e3Sopenharmony_ci        if (proxy->GetDate().IsSymbol('-')) {
754514f5e3Sopenharmony_ci            proxy->NextDate();
764514f5e3Sopenharmony_ci            DateUnit day = proxy->GetDate();
774514f5e3Sopenharmony_ci            if (!day.IsTwoDecimalDigit()) {
784514f5e3Sopenharmony_ci                return false;
794514f5e3Sopenharmony_ci            }
804514f5e3Sopenharmony_ci            dayValue->SetData(day.GetValue());
814514f5e3Sopenharmony_ci            proxy->NextDate();
824514f5e3Sopenharmony_ci        }
834514f5e3Sopenharmony_ci    }
844514f5e3Sopenharmony_ci    if (!proxy->GetDate().IsTimeFlag()) {
854514f5e3Sopenharmony_ci        if (!proxy->GetDate().IsStringEnd()) {
864514f5e3Sopenharmony_ci            return false;
874514f5e3Sopenharmony_ci        }
884514f5e3Sopenharmony_ci    }
894514f5e3Sopenharmony_ci    return true;
904514f5e3Sopenharmony_ci}
914514f5e3Sopenharmony_ci
924514f5e3Sopenharmony_cibool DateParse::ParseIsoDateTime(DateProxy *proxy, DayValue *dayValue, TimeValue *timeValue, TimeZone *timeZone)
934514f5e3Sopenharmony_ci{
944514f5e3Sopenharmony_ci    if (proxy->GetDate().IsTimeFlag()) {
954514f5e3Sopenharmony_ci        // skip 'T'
964514f5e3Sopenharmony_ci        proxy->NextDate();
974514f5e3Sopenharmony_ci        DateUnit hour = proxy->GetDate();
984514f5e3Sopenharmony_ci        if (!hour.IsTwoDecimalDigit()) {
994514f5e3Sopenharmony_ci            return false;
1004514f5e3Sopenharmony_ci        }
1014514f5e3Sopenharmony_ci        timeValue->SetData(hour.GetValue());
1024514f5e3Sopenharmony_ci        proxy->NextDate();
1034514f5e3Sopenharmony_ci        if (!proxy->GetDate().IsSymbol(':')) {
1044514f5e3Sopenharmony_ci            return false;
1054514f5e3Sopenharmony_ci        }
1064514f5e3Sopenharmony_ci        // skip ':'
1074514f5e3Sopenharmony_ci        proxy->NextDate();
1084514f5e3Sopenharmony_ci        DateUnit min = proxy->GetDate();
1094514f5e3Sopenharmony_ci        if (!min.IsTwoDecimalDigit()) {
1104514f5e3Sopenharmony_ci            return false;
1114514f5e3Sopenharmony_ci        }
1124514f5e3Sopenharmony_ci        timeValue->SetData(min.GetValue());
1134514f5e3Sopenharmony_ci        proxy->NextDate();
1144514f5e3Sopenharmony_ci        if (proxy->GetDate().IsSymbol(':')) {
1154514f5e3Sopenharmony_ci            // skip ':'
1164514f5e3Sopenharmony_ci            proxy->NextDate();
1174514f5e3Sopenharmony_ci            DateUnit second = proxy->GetDate();
1184514f5e3Sopenharmony_ci            if (!second.IsTwoDecimalDigit()) {
1194514f5e3Sopenharmony_ci                return false;
1204514f5e3Sopenharmony_ci            }
1214514f5e3Sopenharmony_ci            timeValue->SetData(second.GetValue());
1224514f5e3Sopenharmony_ci            proxy->NextDate();
1234514f5e3Sopenharmony_ci            if (proxy->GetDate().IsSymbol('.')) {
1244514f5e3Sopenharmony_ci                // skip '.'
1254514f5e3Sopenharmony_ci                proxy->NextDate();
1264514f5e3Sopenharmony_ci                DateUnit milliSec = proxy->GetDate();
1274514f5e3Sopenharmony_ci                if (!milliSec.IsNumber()) {
1284514f5e3Sopenharmony_ci                    return false;
1294514f5e3Sopenharmony_ci                }
1304514f5e3Sopenharmony_ci                timeValue->SetData(TimeValue::NormMilliSecond(milliSec));
1314514f5e3Sopenharmony_ci                proxy->NextDate();
1324514f5e3Sopenharmony_ci            }
1334514f5e3Sopenharmony_ci        }
1344514f5e3Sopenharmony_ci        // parse 'z' | '+' | '-' time zone
1354514f5e3Sopenharmony_ci        if (proxy->GetDate().IsWordZ()) {
1364514f5e3Sopenharmony_ci            timeZone->SetUTC();
1374514f5e3Sopenharmony_ci            proxy->NextDate();
1384514f5e3Sopenharmony_ci        } else if (proxy->GetDate().IsSign()) {
1394514f5e3Sopenharmony_ci            if (proxy->GetDate().IsSymbol('-')) {
1404514f5e3Sopenharmony_ci                timeZone->SetSign(-1);
1414514f5e3Sopenharmony_ci            } else {
1424514f5e3Sopenharmony_ci                timeZone->SetSign(1);
1434514f5e3Sopenharmony_ci            }
1444514f5e3Sopenharmony_ci            // skip '+' | '-'
1454514f5e3Sopenharmony_ci            proxy->NextDate();
1464514f5e3Sopenharmony_ci            DateUnit hourZone = proxy->GetDate();
1474514f5e3Sopenharmony_ci            if (hourZone.IsTwoDecimalDigit()) {
1484514f5e3Sopenharmony_ci                timeZone->SetHour(hourZone.GetValue());
1494514f5e3Sopenharmony_ci                proxy->NextDate();
1504514f5e3Sopenharmony_ci                if (!proxy->GetDate().IsSymbol(':')) {
1514514f5e3Sopenharmony_ci                    return false;
1524514f5e3Sopenharmony_ci                }
1534514f5e3Sopenharmony_ci                proxy->NextDate();
1544514f5e3Sopenharmony_ci                DateUnit minZone = proxy->GetDate();
1554514f5e3Sopenharmony_ci                if (!minZone.IsTwoDecimalDigit()) {
1564514f5e3Sopenharmony_ci                    return false;
1574514f5e3Sopenharmony_ci                }
1584514f5e3Sopenharmony_ci                timeZone->SetMin(minZone.GetValue());
1594514f5e3Sopenharmony_ci                proxy->NextDate();
1604514f5e3Sopenharmony_ci            } else if (hourZone.IsFourDecimalDigit()) {
1614514f5e3Sopenharmony_ci                timeZone->SetHour(hourZone.GetValue() / JSDate::HUNDRED);
1624514f5e3Sopenharmony_ci                timeZone->SetMin(hourZone.GetValue() % JSDate::HUNDRED);
1634514f5e3Sopenharmony_ci                proxy->NextDate();
1644514f5e3Sopenharmony_ci            } else {
1654514f5e3Sopenharmony_ci                return false;
1664514f5e3Sopenharmony_ci            }
1674514f5e3Sopenharmony_ci        } else {
1684514f5e3Sopenharmony_ci            if (!proxy->GetDate().IsStringEnd()) {
1694514f5e3Sopenharmony_ci                return false;
1704514f5e3Sopenharmony_ci            }
1714514f5e3Sopenharmony_ci        }
1724514f5e3Sopenharmony_ci    }
1734514f5e3Sopenharmony_ci    if (timeZone->IsLocal() && timeValue->GetIndex() == 0) {
1744514f5e3Sopenharmony_ci        timeZone->SetUTC();
1754514f5e3Sopenharmony_ci    }
1764514f5e3Sopenharmony_ci    dayValue->SetIsoFlag(true);
1774514f5e3Sopenharmony_ci    return true;
1784514f5e3Sopenharmony_ci}
1794514f5e3Sopenharmony_ci
1804514f5e3Sopenharmony_cibool DateParse::ParseLegacyDates(DateProxy *proxy, DayValue *dayValue, TimeValue *timeValue, TimeZone *timeZone)
1814514f5e3Sopenharmony_ci{
1824514f5e3Sopenharmony_ci    DateUnit date = proxy->NextDate();
1834514f5e3Sopenharmony_ci    bool hasNumber = (dayValue->GetIndex() > 0);
1844514f5e3Sopenharmony_ci    while (!date.IsStringEnd()) {
1854514f5e3Sopenharmony_ci        if (date.IsNumber()) {
1864514f5e3Sopenharmony_ci            hasNumber = true;
1874514f5e3Sopenharmony_ci            int num = date.GetValue();
1884514f5e3Sopenharmony_ci            // first parse as time "hh:" or "mm:"
1894514f5e3Sopenharmony_ci            if (proxy->GetDate().IsSymbol(':')) {
1904514f5e3Sopenharmony_ci                // skip ':'
1914514f5e3Sopenharmony_ci                proxy->NextDate();
1924514f5e3Sopenharmony_ci                if (!proxy->GetDate().IsNumber()) {
1934514f5e3Sopenharmony_ci                    return false;
1944514f5e3Sopenharmony_ci                }
1954514f5e3Sopenharmony_ci                if (!timeValue->SetData(num)) {
1964514f5e3Sopenharmony_ci                    return false;
1974514f5e3Sopenharmony_ci                }
1984514f5e3Sopenharmony_ci            // second parse as "ss.sss"
1994514f5e3Sopenharmony_ci            } else if (proxy->GetDate().IsSymbol('.') && timeValue->IsValidSecond(num)) {
2004514f5e3Sopenharmony_ci                // skip '.'
2014514f5e3Sopenharmony_ci                proxy->NextDate();
2024514f5e3Sopenharmony_ci                timeValue->SetData(num);
2034514f5e3Sopenharmony_ci                DateUnit milliSec = proxy->GetDate();
2044514f5e3Sopenharmony_ci                if (!milliSec.IsNumber()) {
2054514f5e3Sopenharmony_ci                    return false;
2064514f5e3Sopenharmony_ci                }
2074514f5e3Sopenharmony_ci                timeValue->SetData(TimeValue::NormMilliSecond(milliSec));
2084514f5e3Sopenharmony_ci                // ship "sss"
2094514f5e3Sopenharmony_ci                proxy->NextDate();
2104514f5e3Sopenharmony_ci                if (!proxy->GetDate().IsValidFinallyTime()) {
2114514f5e3Sopenharmony_ci                    return false;
2124514f5e3Sopenharmony_ci                }
2134514f5e3Sopenharmony_ci            // then parse time "mm" or "ss"
2144514f5e3Sopenharmony_ci            } else if (timeValue->IsValid(num)) {
2154514f5e3Sopenharmony_ci                timeValue->SetData(num);
2164514f5e3Sopenharmony_ci                if (!proxy->GetDate().IsValidFinallyTime()) {
2174514f5e3Sopenharmony_ci                    return false;
2184514f5e3Sopenharmony_ci                }
2194514f5e3Sopenharmony_ci            } else {
2204514f5e3Sopenharmony_ci                if (!dayValue->SetData(num)) {
2214514f5e3Sopenharmony_ci                    return false;
2224514f5e3Sopenharmony_ci                }
2234514f5e3Sopenharmony_ci            }
2244514f5e3Sopenharmony_ci        } else if (date.IsMonth()) {
2254514f5e3Sopenharmony_ci            dayValue->SetMonth(date.GetValue());
2264514f5e3Sopenharmony_ci        } else if (date.IsTimeZone() && hasNumber) {
2274514f5e3Sopenharmony_ci            timeZone->SetUTC();
2284514f5e3Sopenharmony_ci        } else if (date.IsTimeFlag() || date.IsInvalidWord()) {
2294514f5e3Sopenharmony_ci            if (hasNumber) {
2304514f5e3Sopenharmony_ci                return false;
2314514f5e3Sopenharmony_ci            }
2324514f5e3Sopenharmony_ci            if (proxy->GetDate().IsNumber()) {
2334514f5e3Sopenharmony_ci                return false;
2344514f5e3Sopenharmony_ci            }
2354514f5e3Sopenharmony_ci        } else if (date.IsSign() && ((timeValue->GetIndex() > 0) || timeZone->IsUTC())) {
2364514f5e3Sopenharmony_ci            if (date.IsSymbol('-')) {
2374514f5e3Sopenharmony_ci                timeZone->SetSign(-1);
2384514f5e3Sopenharmony_ci            } else {
2394514f5e3Sopenharmony_ci                timeZone->SetSign(1);
2404514f5e3Sopenharmony_ci            }
2414514f5e3Sopenharmony_ci            DateUnit timeNumUnit = proxy->GetDate();
2424514f5e3Sopenharmony_ci            if (!timeNumUnit.IsNumber()) {
2434514f5e3Sopenharmony_ci                return false;
2444514f5e3Sopenharmony_ci            }
2454514f5e3Sopenharmony_ci            int timeNum = timeNumUnit.GetValue();
2464514f5e3Sopenharmony_ci            uint32_t numLength = timeNumUnit.GetLength();
2474514f5e3Sopenharmony_ci            proxy->NextDate();
2484514f5e3Sopenharmony_ci            // parse +hh:mm
2494514f5e3Sopenharmony_ci            if (proxy->GetDate().IsSymbol(':')) {
2504514f5e3Sopenharmony_ci                // skip ':'
2514514f5e3Sopenharmony_ci                proxy->NextDate();
2524514f5e3Sopenharmony_ci                if (!proxy->GetDate().IsNumber()) {
2534514f5e3Sopenharmony_ci                    return false;
2544514f5e3Sopenharmony_ci                }
2554514f5e3Sopenharmony_ci                timeZone->SetHour(timeNum);
2564514f5e3Sopenharmony_ci                timeZone->SetMin(proxy->GetDate().GetValue());
2574514f5e3Sopenharmony_ci                proxy->NextDate();
2584514f5e3Sopenharmony_ci            // 2: hour length
2594514f5e3Sopenharmony_ci            } else if (numLength == 1 || numLength == 2) {
2604514f5e3Sopenharmony_ci                // parse GMT+hh
2614514f5e3Sopenharmony_ci                timeZone->SetHour(timeNum);
2624514f5e3Sopenharmony_ci                timeZone->SetMin(0);
2634514f5e3Sopenharmony_ci            // 3,4:"GMT+hhmm" hhmm length
2644514f5e3Sopenharmony_ci            } else if (numLength == 3 || numLength == 4) {
2654514f5e3Sopenharmony_ci                // parse GMT+hhmm
2664514f5e3Sopenharmony_ci                timeZone->SetHour(timeNum / JSDate::HUNDRED);
2674514f5e3Sopenharmony_ci                timeZone->SetMin(timeNum % JSDate::HUNDRED);
2684514f5e3Sopenharmony_ci            } else {
2694514f5e3Sopenharmony_ci                return false;
2704514f5e3Sopenharmony_ci            }
2714514f5e3Sopenharmony_ci        }
2724514f5e3Sopenharmony_ci        date = proxy->NextDate();
2734514f5e3Sopenharmony_ci    }
2744514f5e3Sopenharmony_ci    return true;
2754514f5e3Sopenharmony_ci}
2764514f5e3Sopenharmony_ci
2774514f5e3Sopenharmony_ciDateParse::DateUnit DateParse::DateProxy::Read()
2784514f5e3Sopenharmony_ci{
2794514f5e3Sopenharmony_ci    if (str_->IsDigit()) {
2804514f5e3Sopenharmony_ci        int len = 0;
2814514f5e3Sopenharmony_ci        int num = str_->ReadNumber(&len);
2824514f5e3Sopenharmony_ci        return DateUnit::Number(num, len);
2834514f5e3Sopenharmony_ci    }
2844514f5e3Sopenharmony_ci    if (str_->IsEnd()) {
2854514f5e3Sopenharmony_ci        return DateUnit::StringEnd();
2864514f5e3Sopenharmony_ci    }
2874514f5e3Sopenharmony_ci    if (str_->IsChar(':')) {
2884514f5e3Sopenharmony_ci        str_->NextChar();
2894514f5e3Sopenharmony_ci        return DateUnit::Symbol(':');
2904514f5e3Sopenharmony_ci    }
2914514f5e3Sopenharmony_ci    if (str_->IsChar('+')) {
2924514f5e3Sopenharmony_ci        str_->NextChar();
2934514f5e3Sopenharmony_ci        return DateUnit::Symbol('+');
2944514f5e3Sopenharmony_ci    }
2954514f5e3Sopenharmony_ci    if (str_->IsChar('-')) {
2964514f5e3Sopenharmony_ci        str_->NextChar();
2974514f5e3Sopenharmony_ci        return DateUnit::Symbol('-');
2984514f5e3Sopenharmony_ci    }
2994514f5e3Sopenharmony_ci    if (str_->IsChar('.')) {
3004514f5e3Sopenharmony_ci        str_->NextChar();
3014514f5e3Sopenharmony_ci        return DateUnit::Symbol('.');
3024514f5e3Sopenharmony_ci    }
3034514f5e3Sopenharmony_ci    if (str_->IsAlpha()) {
3044514f5e3Sopenharmony_ci        // 3: month name length
3054514f5e3Sopenharmony_ci        char buf[3] = {0};
3064514f5e3Sopenharmony_ci        int len = str_->ReadAlphabet(buf, 3);
3074514f5e3Sopenharmony_ci        int minLen = len < 3 ? len : 3;
3084514f5e3Sopenharmony_ci        CString str(buf, minLen);
3094514f5e3Sopenharmony_ci        int value = 0;
3104514f5e3Sopenharmony_ci        DateValueType type = MatchKeyWord(str, &value);
3114514f5e3Sopenharmony_ci        return DateUnit::Word(type, value, len);
3124514f5e3Sopenharmony_ci    }
3134514f5e3Sopenharmony_ci    if (str_->IsSpaceOrTab()) {
3144514f5e3Sopenharmony_ci        str_->NextChar();
3154514f5e3Sopenharmony_ci        return DateUnit::Space();
3164514f5e3Sopenharmony_ci    }
3174514f5e3Sopenharmony_ci    str_->NextChar();
3184514f5e3Sopenharmony_ci    return DateUnit::Unknown();
3194514f5e3Sopenharmony_ci}
3204514f5e3Sopenharmony_ci
3214514f5e3Sopenharmony_ciDateParse::DateValueType DateParse::DateProxy::MatchKeyWord(const CString &str, int *value)
3224514f5e3Sopenharmony_ci{
3234514f5e3Sopenharmony_ci    if (str == "t") {
3244514f5e3Sopenharmony_ci        return DATE_TIME_FALG;
3254514f5e3Sopenharmony_ci    }
3264514f5e3Sopenharmony_ci    if (str == "z") {
3274514f5e3Sopenharmony_ci        return DATE_TIME_ZONE;
3284514f5e3Sopenharmony_ci    }
3294514f5e3Sopenharmony_ci
3304514f5e3Sopenharmony_ci    if (str == "utc" || str == "gmt") {
3314514f5e3Sopenharmony_ci        *value = 1;
3324514f5e3Sopenharmony_ci        return DATE_TIME_ZONE;
3334514f5e3Sopenharmony_ci    }
3344514f5e3Sopenharmony_ci    for (int i = 0; i < MOUTH_PER_YEAR; i++) {
3354514f5e3Sopenharmony_ci        if (str == DateParse::MONTH_NAME[i]) {
3364514f5e3Sopenharmony_ci            *value = i + 1;
3374514f5e3Sopenharmony_ci            return DATE_MONTH;
3384514f5e3Sopenharmony_ci        }
3394514f5e3Sopenharmony_ci    }
3404514f5e3Sopenharmony_ci    return DATE_INVALID_WORD;
3414514f5e3Sopenharmony_ci}
3424514f5e3Sopenharmony_ci
3434514f5e3Sopenharmony_cibool DateParse::TimeZone::SetTimeZone(int *time)
3444514f5e3Sopenharmony_ci{
3454514f5e3Sopenharmony_ci    if (!IsLocal()) {
3464514f5e3Sopenharmony_ci        if (!TimeValue::HourIsValid(hour_) || !TimeValue::MinuteIsValid(min_)) {
3474514f5e3Sopenharmony_ci            return false;
3484514f5e3Sopenharmony_ci        }
3494514f5e3Sopenharmony_ci        time[TIMEZONE] = sign_ * (hour_ * SEC_PER_HOUR + min_ * SEC_PER_MINUTE);
3504514f5e3Sopenharmony_ci    } else {
3514514f5e3Sopenharmony_ci        time[TIMEZONE] = INT_MAX;
3524514f5e3Sopenharmony_ci    }
3534514f5e3Sopenharmony_ci    return true;
3544514f5e3Sopenharmony_ci}
3554514f5e3Sopenharmony_ci
3564514f5e3Sopenharmony_cibool DateParse::TimeValue::SetTimeValue(int *time)
3574514f5e3Sopenharmony_ci{
3584514f5e3Sopenharmony_ci    for (int i = 0; i < TIME_LEN; i++) {
3594514f5e3Sopenharmony_ci        if (i < index_) {
3604514f5e3Sopenharmony_ci            time[HOUR + i] = data_[i];
3614514f5e3Sopenharmony_ci        } else {
3624514f5e3Sopenharmony_ci            time[HOUR + i] = 0;
3634514f5e3Sopenharmony_ci        }
3644514f5e3Sopenharmony_ci    }
3654514f5e3Sopenharmony_ci    // 24: allow 24:00:00
3664514f5e3Sopenharmony_ci    if (time[HOUR] == 24) {
3674514f5e3Sopenharmony_ci        if (time[MIN] == 0 && time[SEC] == 0 && time[MS] == 0) {
3684514f5e3Sopenharmony_ci            return true;
3694514f5e3Sopenharmony_ci        }
3704514f5e3Sopenharmony_ci        return false;
3714514f5e3Sopenharmony_ci    }
3724514f5e3Sopenharmony_ci    if (!HourIsValid(time[HOUR]) || !MinuteIsValid(time[MIN]) || !SecondIsValid(time[SEC]) ||
3734514f5e3Sopenharmony_ci        !MilliSecondIsValid(time[MS])) {
3744514f5e3Sopenharmony_ci        return false;
3754514f5e3Sopenharmony_ci    }
3764514f5e3Sopenharmony_ci    return true;
3774514f5e3Sopenharmony_ci}
3784514f5e3Sopenharmony_ci
3794514f5e3Sopenharmony_cibool DateParse::DayValue::SetDayValue(int *time)
3804514f5e3Sopenharmony_ci{
3814514f5e3Sopenharmony_ci    if (index_ == 0) {
3824514f5e3Sopenharmony_ci        return false;
3834514f5e3Sopenharmony_ci    }
3844514f5e3Sopenharmony_ci    int year = 1;
3854514f5e3Sopenharmony_ci    int mon = 1;
3864514f5e3Sopenharmony_ci    int day = 1;
3874514f5e3Sopenharmony_ci    for (int i = index_; i < DAY_LEN; i++) {
3884514f5e3Sopenharmony_ci        data_[i] = 1;
3894514f5e3Sopenharmony_ci    }
3904514f5e3Sopenharmony_ci    if (month_ == INT_MAX) {
3914514f5e3Sopenharmony_ci        // 2:index of year
3924514f5e3Sopenharmony_ci        if (isIsoFlag_ || (IsFull() && DayIsValid(data_[2]) && !MonthIsValid(data_[0]))) {
3934514f5e3Sopenharmony_ci            year = data_[YEAR];
3944514f5e3Sopenharmony_ci            mon = data_[MONTH];
3954514f5e3Sopenharmony_ci            day = data_[DAYS];
3964514f5e3Sopenharmony_ci        } else {
3974514f5e3Sopenharmony_ci            if (IsFull()) {
3984514f5e3Sopenharmony_ci                // input:month-day-year
3994514f5e3Sopenharmony_ci                year = data_[2]; // 2:index of year
4004514f5e3Sopenharmony_ci                mon = data_[0];  // 0:index of month
4014514f5e3Sopenharmony_ci                day = data_[1];  // 1:index of day
4024514f5e3Sopenharmony_ci            } else {
4034514f5e3Sopenharmony_ci                // input:year-month
4044514f5e3Sopenharmony_ci                year = data_[0]; // 0:index of year
4054514f5e3Sopenharmony_ci                mon = data_[1];  // 1:index of month
4064514f5e3Sopenharmony_ci                day = data_[2];  // 2:index of day
4074514f5e3Sopenharmony_ci            }
4084514f5e3Sopenharmony_ci        }
4094514f5e3Sopenharmony_ci    } else {
4104514f5e3Sopenharmony_ci        mon = month_;
4114514f5e3Sopenharmony_ci        if (IsFull()) {
4124514f5e3Sopenharmony_ci            return false;
4134514f5e3Sopenharmony_ci        }
4144514f5e3Sopenharmony_ci        // 2: day and year
4154514f5e3Sopenharmony_ci        if (index_ == 2) {
4164514f5e3Sopenharmony_ci            if (!DayIsValid(data_[0])) {
4174514f5e3Sopenharmony_ci                year = data_[0];
4184514f5e3Sopenharmony_ci                day = data_[1];
4194514f5e3Sopenharmony_ci            } else {
4204514f5e3Sopenharmony_ci                day = data_[0];
4214514f5e3Sopenharmony_ci                year = data_[1];
4224514f5e3Sopenharmony_ci            }
4234514f5e3Sopenharmony_ci        } else {
4244514f5e3Sopenharmony_ci            day = data_[0];
4254514f5e3Sopenharmony_ci        }
4264514f5e3Sopenharmony_ci    }
4274514f5e3Sopenharmony_ci    if (!IsIso()) {
4284514f5e3Sopenharmony_ci        if (IsBetween(year, 0, 49)) { // if year is between 0-49
4294514f5e3Sopenharmony_ci            year += 2000; // 2000 : it means 2001-2049
4304514f5e3Sopenharmony_ci        } else if (IsBetween(year, 50, 99)) { // if year is between 50-99
4314514f5e3Sopenharmony_ci            year += 1900; // 1900 : it may means 1950-1999
4324514f5e3Sopenharmony_ci        }
4334514f5e3Sopenharmony_ci    }
4344514f5e3Sopenharmony_ci    if (!MonthIsValid(mon) || !DayIsValid(day)) {
4354514f5e3Sopenharmony_ci        return false;
4364514f5e3Sopenharmony_ci    }
4374514f5e3Sopenharmony_ci    time[YEAR] = year;
4384514f5e3Sopenharmony_ci    time[MONTH] = mon - 1;
4394514f5e3Sopenharmony_ci    time[DAYS] = day;
4404514f5e3Sopenharmony_ci    return true;
4414514f5e3Sopenharmony_ci}
4424514f5e3Sopenharmony_ci}  // namespace panda::ecmascript