123b3eb3cSopenharmony_ci/*
223b3eb3cSopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
323b3eb3cSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
423b3eb3cSopenharmony_ci * you may not use this file except in compliance with the License.
523b3eb3cSopenharmony_ci * You may obtain a copy of the License at
623b3eb3cSopenharmony_ci *
723b3eb3cSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
823b3eb3cSopenharmony_ci *
923b3eb3cSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1023b3eb3cSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1123b3eb3cSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1223b3eb3cSopenharmony_ci * See the License for the specific language governing permissions and
1323b3eb3cSopenharmony_ci * limitations under the License.
1423b3eb3cSopenharmony_ci */
1523b3eb3cSopenharmony_ci
1623b3eb3cSopenharmony_ci#include "base/i18n/localization.h"
1723b3eb3cSopenharmony_ci
1823b3eb3cSopenharmony_ci#include "chnsecal.h"
1923b3eb3cSopenharmony_ci#if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
2023b3eb3cSopenharmony_ci#include "lunar_calendar.h"
2123b3eb3cSopenharmony_ci#endif
2223b3eb3cSopenharmony_ci#include "unicode/dtfmtsym.h"
2323b3eb3cSopenharmony_ci#include "unicode/dtptngen.h"
2423b3eb3cSopenharmony_ci#include "unicode/measfmt.h"
2523b3eb3cSopenharmony_ci#include "unicode/numberformatter.h"
2623b3eb3cSopenharmony_ci#include "unicode/reldatefmt.h"
2723b3eb3cSopenharmony_ci#include "unicode/smpdtfmt.h"
2823b3eb3cSopenharmony_ci#include "date_time_sequence.h"
2923b3eb3cSopenharmony_ci#include "base/json/json_util.h"
3023b3eb3cSopenharmony_ci#include "base/resource/internal_resource.h"
3123b3eb3cSopenharmony_ci#include "base/utils/string_utils.h"
3223b3eb3cSopenharmony_ci#include "base/utils/utils.h"
3323b3eb3cSopenharmony_ci
3423b3eb3cSopenharmony_cinamespace OHOS::Ace {
3523b3eb3cSopenharmony_ci
3623b3eb3cSopenharmony_ciusing namespace icu;
3723b3eb3cSopenharmony_ci
3823b3eb3cSopenharmony_cistruct LocaleProxy final {
3923b3eb3cSopenharmony_ci    LocaleProxy(const char* language, const char* countryOrRegion, const char* variant, const char* keywordsAndValues)
4023b3eb3cSopenharmony_ci        : instance(language, countryOrRegion, variant, keywordsAndValues)
4123b3eb3cSopenharmony_ci    {}
4223b3eb3cSopenharmony_ci    ~LocaleProxy() = default;
4323b3eb3cSopenharmony_ci
4423b3eb3cSopenharmony_ci    Locale instance;
4523b3eb3cSopenharmony_ci};
4623b3eb3cSopenharmony_ci
4723b3eb3cSopenharmony_cinamespace {
4823b3eb3cSopenharmony_ci
4923b3eb3cSopenharmony_ci#define CHECK_RETURN(status, ret)                                      \
5023b3eb3cSopenharmony_ci    do {                                                               \
5123b3eb3cSopenharmony_ci        if ((status) > U_ZERO_ERROR) {                                 \
5223b3eb3cSopenharmony_ci            LOGW("status = %{public}d", static_cast<int32_t>(status)); \
5323b3eb3cSopenharmony_ci            return (ret);                                              \
5423b3eb3cSopenharmony_ci        }                                                              \
5523b3eb3cSopenharmony_ci    } while (0)
5623b3eb3cSopenharmony_ci
5723b3eb3cSopenharmony_ci#define CHECK_NO_RETURN(status)                                        \
5823b3eb3cSopenharmony_ci    do {                                                               \
5923b3eb3cSopenharmony_ci        if ((status) > U_ZERO_ERROR) {                                 \
6023b3eb3cSopenharmony_ci            LOGW("status = %{public}d", static_cast<int32_t>(status)); \
6123b3eb3cSopenharmony_ci        }                                                              \
6223b3eb3cSopenharmony_ci    } while (0)
6323b3eb3cSopenharmony_ci
6423b3eb3cSopenharmony_ciconst char JSON_PATH_CARVE = '.';
6523b3eb3cSopenharmony_ciconst char DEFAULT_LANGUAGE[] = "en-US";
6623b3eb3cSopenharmony_ciconstexpr uint32_t SEXAGENARY_CYCLE_SIZE = 60;
6723b3eb3cSopenharmony_ciconstexpr uint32_t GUIHAI_YEAR_RECENT = 3;
6823b3eb3cSopenharmony_ciconstexpr uint32_t SECONDS_IN_HOUR = 3600;
6923b3eb3cSopenharmony_ci
7023b3eb3cSopenharmony_ciconst char CHINESE_LEAP[] = u8"\u95f0";
7123b3eb3cSopenharmony_ciconst char CHINESE_FIRST[] = u8"\u521d";
7223b3eb3cSopenharmony_ciconst char CHINESE_TEN[] = u8"\u5341";
7323b3eb3cSopenharmony_ciconst char CHINESE_TWENTY[] = u8"\u5eff";
7423b3eb3cSopenharmony_ciconst char* g_chineseOneToNine[] = { u8"\u4e00", u8"\u4e8c", u8"\u4e09", u8"\u56db", u8"\u4e94", u8"\u516d", u8"\u4e03",
7523b3eb3cSopenharmony_ci    u8"\u516b", u8"\u4e5d" };
7623b3eb3cSopenharmony_ciconst std::unordered_map<std::string, std::string> LANGUAGE_CODE_MAP {
7723b3eb3cSopenharmony_ci    { "he", "iw" },
7823b3eb3cSopenharmony_ci    { "fil", "tl" },
7923b3eb3cSopenharmony_ci    { "id", "in" },
8023b3eb3cSopenharmony_ci};
8123b3eb3cSopenharmony_ci
8223b3eb3cSopenharmony_ciinline void UnicodeString2String(const UnicodeString& source, std::string& result)
8323b3eb3cSopenharmony_ci{
8423b3eb3cSopenharmony_ci    source.toUTF8String(result);
8523b3eb3cSopenharmony_ci}
8623b3eb3cSopenharmony_ci
8723b3eb3cSopenharmony_ciDateFormat::EStyle DateTimeStyle2EStyle(DateTimeStyle dateTimeStyle)
8823b3eb3cSopenharmony_ci{
8923b3eb3cSopenharmony_ci    switch (dateTimeStyle) {
9023b3eb3cSopenharmony_ci        case DateTimeStyle::NONE:
9123b3eb3cSopenharmony_ci            return DateFormat::EStyle::kNone;
9223b3eb3cSopenharmony_ci        case DateTimeStyle::FULL:
9323b3eb3cSopenharmony_ci            return DateFormat::EStyle::kFull;
9423b3eb3cSopenharmony_ci        case DateTimeStyle::LONG:
9523b3eb3cSopenharmony_ci            return DateFormat::EStyle::kLong;
9623b3eb3cSopenharmony_ci        case DateTimeStyle::MEDIUM:
9723b3eb3cSopenharmony_ci            return DateFormat::EStyle::kMedium;
9823b3eb3cSopenharmony_ci        case DateTimeStyle::SHORT:
9923b3eb3cSopenharmony_ci            return DateFormat::EStyle::kShort;
10023b3eb3cSopenharmony_ci        default:
10123b3eb3cSopenharmony_ci            return DateFormat::EStyle::kNone;
10223b3eb3cSopenharmony_ci    }
10323b3eb3cSopenharmony_ci}
10423b3eb3cSopenharmony_ci
10523b3eb3cSopenharmony_ciUMeasureFormatWidth GetMeasureFormatWidth(MeasureFormatStyle formatStyle)
10623b3eb3cSopenharmony_ci{
10723b3eb3cSopenharmony_ci    switch (formatStyle) {
10823b3eb3cSopenharmony_ci        case MeasureFormatStyle::WIDTH_WIDE:
10923b3eb3cSopenharmony_ci            return UMeasureFormatWidth::UMEASFMT_WIDTH_WIDE;
11023b3eb3cSopenharmony_ci        case MeasureFormatStyle::WIDTH_SHORT:
11123b3eb3cSopenharmony_ci            return UMeasureFormatWidth::UMEASFMT_WIDTH_SHORT;
11223b3eb3cSopenharmony_ci        case MeasureFormatStyle::WIDTH_NARROW:
11323b3eb3cSopenharmony_ci            return UMeasureFormatWidth::UMEASFMT_WIDTH_NARROW;
11423b3eb3cSopenharmony_ci        case MeasureFormatStyle::WIDTH_NUMERIC:
11523b3eb3cSopenharmony_ci            return UMeasureFormatWidth::UMEASFMT_WIDTH_NUMERIC;
11623b3eb3cSopenharmony_ci        case MeasureFormatStyle::WIDTH_COUNT:
11723b3eb3cSopenharmony_ci            return UMeasureFormatWidth::UMEASFMT_WIDTH_COUNT;
11823b3eb3cSopenharmony_ci        default:
11923b3eb3cSopenharmony_ci            return UMeasureFormatWidth::UMEASFMT_WIDTH_WIDE;
12023b3eb3cSopenharmony_ci    }
12123b3eb3cSopenharmony_ci}
12223b3eb3cSopenharmony_ci
12323b3eb3cSopenharmony_ciMeasureUnit* GetMeasureUnit(TimeUnitStyle timeUnitStyle, UErrorCode& status)
12423b3eb3cSopenharmony_ci{
12523b3eb3cSopenharmony_ci    switch (timeUnitStyle) {
12623b3eb3cSopenharmony_ci        case TimeUnitStyle::YEAR:
12723b3eb3cSopenharmony_ci            return MeasureUnit::createYear(status);
12823b3eb3cSopenharmony_ci        case TimeUnitStyle::MONTH:
12923b3eb3cSopenharmony_ci            return MeasureUnit::createMonth(status);
13023b3eb3cSopenharmony_ci        case TimeUnitStyle::DAY:
13123b3eb3cSopenharmony_ci            return MeasureUnit::createDay(status);
13223b3eb3cSopenharmony_ci        case TimeUnitStyle::HOUR:
13323b3eb3cSopenharmony_ci            return MeasureUnit::createHour(status);
13423b3eb3cSopenharmony_ci        case TimeUnitStyle::MINUTE:
13523b3eb3cSopenharmony_ci            return MeasureUnit::createMinute(status);
13623b3eb3cSopenharmony_ci        case TimeUnitStyle::SECOND:
13723b3eb3cSopenharmony_ci            return MeasureUnit::createSecond(status);
13823b3eb3cSopenharmony_ci        case TimeUnitStyle::MILLISECOND:
13923b3eb3cSopenharmony_ci            return MeasureUnit::createMillisecond(status);
14023b3eb3cSopenharmony_ci        default:
14123b3eb3cSopenharmony_ci            return MeasureUnit::createYear(status);
14223b3eb3cSopenharmony_ci    }
14323b3eb3cSopenharmony_ci}
14423b3eb3cSopenharmony_ci
14523b3eb3cSopenharmony_civoid GetLocalJsonObject(InternalResource::ResourceId id, std::string language, std::unique_ptr<JsonValue>& indexJson,
14623b3eb3cSopenharmony_ci    std::unique_ptr<JsonValue>& json)
14723b3eb3cSopenharmony_ci{
14823b3eb3cSopenharmony_ci    if (indexJson == nullptr) {
14923b3eb3cSopenharmony_ci        size_t size = 0;
15023b3eb3cSopenharmony_ci        const uint8_t* buf = InternalResource::GetInstance().GetResource(id, size);
15123b3eb3cSopenharmony_ci        if (buf == nullptr) {
15223b3eb3cSopenharmony_ci            return;
15323b3eb3cSopenharmony_ci        }
15423b3eb3cSopenharmony_ci
15523b3eb3cSopenharmony_ci        std::string jsonStr(reinterpret_cast<const char*>(buf), size);
15623b3eb3cSopenharmony_ci        const char* endMsg = nullptr;
15723b3eb3cSopenharmony_ci        indexJson = JsonUtil::ParseJsonString(jsonStr, &endMsg);
15823b3eb3cSopenharmony_ci        if (indexJson == nullptr) {
15923b3eb3cSopenharmony_ci            LOGE("read indexletter json failed. reason: %{private}s.", endMsg);
16023b3eb3cSopenharmony_ci            return;
16123b3eb3cSopenharmony_ci        }
16223b3eb3cSopenharmony_ci    }
16323b3eb3cSopenharmony_ci
16423b3eb3cSopenharmony_ci    if (indexJson->Contains(language) && indexJson->GetValue(language)->IsObject()) {
16523b3eb3cSopenharmony_ci        json = indexJson->GetValue(language);
16623b3eb3cSopenharmony_ci    } else if (indexJson->Contains(DEFAULT_LANGUAGE) && indexJson->GetValue(DEFAULT_LANGUAGE)->IsObject()) {
16723b3eb3cSopenharmony_ci        json = indexJson->GetValue(DEFAULT_LANGUAGE);
16823b3eb3cSopenharmony_ci    }
16923b3eb3cSopenharmony_ci}
17023b3eb3cSopenharmony_ci
17123b3eb3cSopenharmony_ci} // namespace
17223b3eb3cSopenharmony_ci
17323b3eb3cSopenharmony_ci// for entry.json
17423b3eb3cSopenharmony_cistatic std::unique_ptr<JsonValue> g_indexJsonEntry = nullptr;
17523b3eb3cSopenharmony_cistatic std::unique_ptr<JsonValue> g_indexJsonError = nullptr;
17623b3eb3cSopenharmony_ci
17723b3eb3cSopenharmony_ciLocalization::~Localization() = default;
17823b3eb3cSopenharmony_ci
17923b3eb3cSopenharmony_civoid Localization::SetLocaleImpl(const std::string& language, const std::string& countryOrRegion,
18023b3eb3cSopenharmony_ci    const std::string& script, const std::string& selectLanguage, const std::string& keywordsAndValues)
18123b3eb3cSopenharmony_ci{
18223b3eb3cSopenharmony_ci    locale_ = std::make_unique<LocaleProxy>(language.c_str(), countryOrRegion.c_str(), "", keywordsAndValues.c_str());
18323b3eb3cSopenharmony_ci
18423b3eb3cSopenharmony_ci    UErrorCode status = U_ZERO_ERROR;
18523b3eb3cSopenharmony_ci    std::vector<std::string> keyValuePairs;
18623b3eb3cSopenharmony_ci    StringUtils::StringSplitter(keywordsAndValues, ';', keyValuePairs);
18723b3eb3cSopenharmony_ci    for (const auto& pair : keyValuePairs) {
18823b3eb3cSopenharmony_ci        // [pair] is like "nu=arab" or "nu=" for most occasions, but may be "=" under extreme scenarios
18923b3eb3cSopenharmony_ci        std::vector<std::string> res;
19023b3eb3cSopenharmony_ci        StringUtils::StringSplitter(pair, '=', res);
19123b3eb3cSopenharmony_ci        if (res.size() == 0) {
19223b3eb3cSopenharmony_ci            continue;
19323b3eb3cSopenharmony_ci        }
19423b3eb3cSopenharmony_ci        auto value = (res.size() == 2) ? res[1] : "";
19523b3eb3cSopenharmony_ci        locale_->instance.setUnicodeKeywordValue(res[0], value, status);
19623b3eb3cSopenharmony_ci        CHECK_NO_RETURN(status);
19723b3eb3cSopenharmony_ci    }
19823b3eb3cSopenharmony_ci
19923b3eb3cSopenharmony_ci    languageTag_ = language;
20023b3eb3cSopenharmony_ci    if (!script.empty()) {
20123b3eb3cSopenharmony_ci        languageTag_.append("-").append(script);
20223b3eb3cSopenharmony_ci    }
20323b3eb3cSopenharmony_ci    if (!countryOrRegion.empty()) {
20423b3eb3cSopenharmony_ci        languageTag_.append("-").append(countryOrRegion);
20523b3eb3cSopenharmony_ci    }
20623b3eb3cSopenharmony_ci    fontLocale_ = languageTag_;
20723b3eb3cSopenharmony_ci    // Simple chinese
20823b3eb3cSopenharmony_ci    if (languageTag_ == "zh-Hans-CN") {
20923b3eb3cSopenharmony_ci        languageTag_ = "zh-CN";
21023b3eb3cSopenharmony_ci        fontLocale_ = "";
21123b3eb3cSopenharmony_ci    }
21223b3eb3cSopenharmony_ci
21323b3eb3cSopenharmony_ci    selectLanguage_ = selectLanguage;
21423b3eb3cSopenharmony_ci    // match json of latin
21523b3eb3cSopenharmony_ci    if (selectLanguage_ == "jv-Latn") {
21623b3eb3cSopenharmony_ci        selectLanguage_ = "b+jv+Latn";
21723b3eb3cSopenharmony_ci    } else if (selectLanguage_ == "sr-Latn") {
21823b3eb3cSopenharmony_ci        selectLanguage_ = "b+sr+Latn";
21923b3eb3cSopenharmony_ci    }
22023b3eb3cSopenharmony_ci
22123b3eb3cSopenharmony_ci    LOGI("SetLocale language tag: %{public}s, select language: %{public}s", languageTag_.c_str(),
22223b3eb3cSopenharmony_ci        selectLanguage_.c_str());
22323b3eb3cSopenharmony_ci    if (!isPromiseUsed_) {
22423b3eb3cSopenharmony_ci        promise_.set_value(true);
22523b3eb3cSopenharmony_ci        isPromiseUsed_ = true;
22623b3eb3cSopenharmony_ci    }
22723b3eb3cSopenharmony_ci}
22823b3eb3cSopenharmony_ci
22923b3eb3cSopenharmony_cistd::string Localization::GetLanguage()
23023b3eb3cSopenharmony_ci{
23123b3eb3cSopenharmony_ci    WaitingForInit();
23223b3eb3cSopenharmony_ci    if (locale_) {
23323b3eb3cSopenharmony_ci        return locale_->instance.getLanguage();
23423b3eb3cSopenharmony_ci    }
23523b3eb3cSopenharmony_ci    return "";
23623b3eb3cSopenharmony_ci}
23723b3eb3cSopenharmony_ci
23823b3eb3cSopenharmony_cistd::string Localization::GetLanguageTag()
23923b3eb3cSopenharmony_ci{
24023b3eb3cSopenharmony_ci    WaitingForInit();
24123b3eb3cSopenharmony_ci    return languageTag_;
24223b3eb3cSopenharmony_ci}
24323b3eb3cSopenharmony_ci
24423b3eb3cSopenharmony_cistd::string Localization::GetFontLocale()
24523b3eb3cSopenharmony_ci{
24623b3eb3cSopenharmony_ci    WaitingForInit();
24723b3eb3cSopenharmony_ci    return fontLocale_;
24823b3eb3cSopenharmony_ci}
24923b3eb3cSopenharmony_ci
25023b3eb3cSopenharmony_ciconst std::string Localization::FormatDuration(uint32_t duration, bool needShowHour)
25123b3eb3cSopenharmony_ci{
25223b3eb3cSopenharmony_ci    WaitingForInit();
25323b3eb3cSopenharmony_ci    UErrorCode status = U_ZERO_ERROR;
25423b3eb3cSopenharmony_ci    // duration greater than 1 hour, use HH:mm:ss;
25523b3eb3cSopenharmony_ci    if (!needShowHour && duration > SECONDS_IN_HOUR) {
25623b3eb3cSopenharmony_ci        needShowHour = true;
25723b3eb3cSopenharmony_ci    }
25823b3eb3cSopenharmony_ci    const char* engTimeFormat = needShowHour ? "HH:mm:ss" : "mm:ss";
25923b3eb3cSopenharmony_ci    auto simpleDateFormat = std::make_unique<SimpleDateFormat>(UnicodeString(engTimeFormat), locale_->instance, status);
26023b3eb3cSopenharmony_ci    CHECK_RETURN(status, "");
26123b3eb3cSopenharmony_ci    TimeZone* timeZone = TimeZone::createTimeZone("GMT+0:00");
26223b3eb3cSopenharmony_ci    simpleDateFormat->setTimeZone(*timeZone);
26323b3eb3cSopenharmony_ci
26423b3eb3cSopenharmony_ci    UnicodeString simpleStr;
26523b3eb3cSopenharmony_ci    simpleDateFormat->format(1000.0 * duration, simpleStr, status);
26623b3eb3cSopenharmony_ci    delete(timeZone);
26723b3eb3cSopenharmony_ci    CHECK_RETURN(status, "");
26823b3eb3cSopenharmony_ci
26923b3eb3cSopenharmony_ci    std::string ret;
27023b3eb3cSopenharmony_ci    UnicodeString2String(simpleStr, ret);
27123b3eb3cSopenharmony_ci
27223b3eb3cSopenharmony_ci    return ret;
27323b3eb3cSopenharmony_ci}
27423b3eb3cSopenharmony_ci
27523b3eb3cSopenharmony_cistd::string Localization::FormatDuration(uint32_t duration, const std::string& format)
27623b3eb3cSopenharmony_ci{
27723b3eb3cSopenharmony_ci    WaitingForInit();
27823b3eb3cSopenharmony_ci    UErrorCode status = U_ZERO_ERROR;
27923b3eb3cSopenharmony_ci
28023b3eb3cSopenharmony_ci    const char* engTimeFormat = format.c_str();
28123b3eb3cSopenharmony_ci    auto simpleDateFormat = std::make_unique<SimpleDateFormat>(UnicodeString(engTimeFormat), locale_->instance, status);
28223b3eb3cSopenharmony_ci    CHECK_RETURN(status, "");
28323b3eb3cSopenharmony_ci    TimeZone* timeZone = TimeZone::createTimeZone("GMT+0:00");
28423b3eb3cSopenharmony_ci    simpleDateFormat->setTimeZone(*timeZone);
28523b3eb3cSopenharmony_ci
28623b3eb3cSopenharmony_ci    UnicodeString simpleStr;
28723b3eb3cSopenharmony_ci    simpleDateFormat->format(1.0 * duration, simpleStr, status);
28823b3eb3cSopenharmony_ci    CHECK_RETURN(status, "");
28923b3eb3cSopenharmony_ci
29023b3eb3cSopenharmony_ci    std::string ret;
29123b3eb3cSopenharmony_ci    UnicodeString2String(simpleStr, ret);
29223b3eb3cSopenharmony_ci
29323b3eb3cSopenharmony_ci    delete(timeZone);
29423b3eb3cSopenharmony_ci    return ret;
29523b3eb3cSopenharmony_ci}
29623b3eb3cSopenharmony_ci
29723b3eb3cSopenharmony_ciconst std::string Localization::FormatDateTime(DateTime dateTime, const std::string& format)
29823b3eb3cSopenharmony_ci{
29923b3eb3cSopenharmony_ci    WaitingForInit();
30023b3eb3cSopenharmony_ci    UErrorCode status = U_ZERO_ERROR;
30123b3eb3cSopenharmony_ci    auto cal = Calendar::createInstance(locale_->instance, status);
30223b3eb3cSopenharmony_ci    CHECK_RETURN(status, "");
30323b3eb3cSopenharmony_ci    cal->set(dateTime.year, dateTime.month, dateTime.day, dateTime.hour, dateTime.minute, dateTime.second);
30423b3eb3cSopenharmony_ci
30523b3eb3cSopenharmony_ci    UDate date = cal->getTime(status);
30623b3eb3cSopenharmony_ci    delete cal;
30723b3eb3cSopenharmony_ci    CHECK_RETURN(status, "");
30823b3eb3cSopenharmony_ci
30923b3eb3cSopenharmony_ci    auto patternGenerator = DateTimePatternGenerator::createInstance(locale_->instance, status);
31023b3eb3cSopenharmony_ci    CHECK_RETURN(status, "");
31123b3eb3cSopenharmony_ci    UnicodeString pattern = patternGenerator->getBestPattern(UnicodeString(format.c_str()), status);
31223b3eb3cSopenharmony_ci    delete patternGenerator;
31323b3eb3cSopenharmony_ci    CHECK_RETURN(status, "");
31423b3eb3cSopenharmony_ci
31523b3eb3cSopenharmony_ci    auto dateFormat = std::make_unique<SimpleDateFormat>(pattern, locale_->instance, status);
31623b3eb3cSopenharmony_ci    CHECK_RETURN(status, "");
31723b3eb3cSopenharmony_ci
31823b3eb3cSopenharmony_ci    UnicodeString dateTimeStr;
31923b3eb3cSopenharmony_ci    dateFormat->format(date, dateTimeStr, status);
32023b3eb3cSopenharmony_ci    CHECK_RETURN(status, "");
32123b3eb3cSopenharmony_ci
32223b3eb3cSopenharmony_ci    std::string ret;
32323b3eb3cSopenharmony_ci    UnicodeString2String(dateTimeStr, ret);
32423b3eb3cSopenharmony_ci    return ret;
32523b3eb3cSopenharmony_ci}
32623b3eb3cSopenharmony_ci
32723b3eb3cSopenharmony_cibool Localization::GetDateColumnFormatOrder(std::vector<std::string>& outOrder)
32823b3eb3cSopenharmony_ci{
32923b3eb3cSopenharmony_ci    outOrder.clear();
33023b3eb3cSopenharmony_ci    WaitingForInit();
33123b3eb3cSopenharmony_ci    UErrorCode status = U_ZERO_ERROR;
33223b3eb3cSopenharmony_ci
33323b3eb3cSopenharmony_ci    auto patternGenerator = DateTimePatternGenerator::createInstance(locale_->instance, status);
33423b3eb3cSopenharmony_ci    CHECK_RETURN(status, false);
33523b3eb3cSopenharmony_ci    std::string format = "yyyyMMdd";
33623b3eb3cSopenharmony_ci    UnicodeString pattern = patternGenerator->getBestPattern(UnicodeString(format.c_str()), status);
33723b3eb3cSopenharmony_ci    delete patternGenerator;
33823b3eb3cSopenharmony_ci    CHECK_RETURN(status, false);
33923b3eb3cSopenharmony_ci
34023b3eb3cSopenharmony_ci    std::string result;
34123b3eb3cSopenharmony_ci    UnicodeString2String(pattern, result);
34223b3eb3cSopenharmony_ci
34323b3eb3cSopenharmony_ci    std::map<std::size_t, std::string> order;
34423b3eb3cSopenharmony_ci    std::size_t position = result.find("yyyy");
34523b3eb3cSopenharmony_ci    if (position == std::string::npos) {
34623b3eb3cSopenharmony_ci        return false;
34723b3eb3cSopenharmony_ci    }
34823b3eb3cSopenharmony_ci    order[position] = "year";
34923b3eb3cSopenharmony_ci
35023b3eb3cSopenharmony_ci    position = result.find("MM");
35123b3eb3cSopenharmony_ci    if (position == std::string::npos) {
35223b3eb3cSopenharmony_ci        return false;
35323b3eb3cSopenharmony_ci    }
35423b3eb3cSopenharmony_ci    order[position] = "month";
35523b3eb3cSopenharmony_ci
35623b3eb3cSopenharmony_ci    position = result.find("dd");
35723b3eb3cSopenharmony_ci    if (position == std::string::npos) {
35823b3eb3cSopenharmony_ci        return false;
35923b3eb3cSopenharmony_ci    }
36023b3eb3cSopenharmony_ci    order[position] = "day";
36123b3eb3cSopenharmony_ci
36223b3eb3cSopenharmony_ci    for (auto it = order.begin(); it != order.end(); ++it) {
36323b3eb3cSopenharmony_ci        outOrder.emplace_back(it->second);
36423b3eb3cSopenharmony_ci    }
36523b3eb3cSopenharmony_ci
36623b3eb3cSopenharmony_ci    return true;
36723b3eb3cSopenharmony_ci}
36823b3eb3cSopenharmony_ci
36923b3eb3cSopenharmony_cibool Localization::GetDateOrder(std::vector<std::string>& outOrder)
37023b3eb3cSopenharmony_ci{
37123b3eb3cSopenharmony_ci    std::string dateOrder;
37223b3eb3cSopenharmony_ci    DateTimeSequence sequence;
37323b3eb3cSopenharmony_ci    std::string language = locale_->instance.getLanguage();
37423b3eb3cSopenharmony_ci    OrderResult orderResult = sequence.GetDateOrder(language);
37523b3eb3cSopenharmony_ci    dateOrder = orderResult.dateOrder;
37623b3eb3cSopenharmony_ci
37723b3eb3cSopenharmony_ci    std::map<std::size_t, std::string> order;
37823b3eb3cSopenharmony_ci    std::size_t position = dateOrder.find("y");
37923b3eb3cSopenharmony_ci    if (position == std::string::npos) {
38023b3eb3cSopenharmony_ci        return false;
38123b3eb3cSopenharmony_ci    }
38223b3eb3cSopenharmony_ci    order[position] = "year";
38323b3eb3cSopenharmony_ci
38423b3eb3cSopenharmony_ci    position = dateOrder.find("M");
38523b3eb3cSopenharmony_ci    if (position == std::string::npos) {
38623b3eb3cSopenharmony_ci        return false;
38723b3eb3cSopenharmony_ci    }
38823b3eb3cSopenharmony_ci    order[position] = "month";
38923b3eb3cSopenharmony_ci
39023b3eb3cSopenharmony_ci    position = dateOrder.find("d");
39123b3eb3cSopenharmony_ci    if (position == std::string::npos) {
39223b3eb3cSopenharmony_ci        return false;
39323b3eb3cSopenharmony_ci    }
39423b3eb3cSopenharmony_ci    order[position] = "day";
39523b3eb3cSopenharmony_ci
39623b3eb3cSopenharmony_ci    for (auto it = order.begin(); it != order.end(); ++it) {
39723b3eb3cSopenharmony_ci        outOrder.emplace_back(it->second);
39823b3eb3cSopenharmony_ci    }
39923b3eb3cSopenharmony_ci
40023b3eb3cSopenharmony_ci    return true;
40123b3eb3cSopenharmony_ci}
40223b3eb3cSopenharmony_ci
40323b3eb3cSopenharmony_cibool Localization::Contain(const std::string& str, const std::string& tag)
40423b3eb3cSopenharmony_ci{
40523b3eb3cSopenharmony_ci    auto pos = str.find(tag);
40623b3eb3cSopenharmony_ci    return (pos != std::string::npos);
40723b3eb3cSopenharmony_ci}
40823b3eb3cSopenharmony_ci
40923b3eb3cSopenharmony_cibool Localization::GetHourFormat(bool& isAmPm, bool& hasZero)
41023b3eb3cSopenharmony_ci{
41123b3eb3cSopenharmony_ci    WaitingForInit();
41223b3eb3cSopenharmony_ci    UErrorCode status = U_ZERO_ERROR;
41323b3eb3cSopenharmony_ci
41423b3eb3cSopenharmony_ci    auto patternGenerator = DateTimePatternGenerator::createInstance(locale_->instance, status);
41523b3eb3cSopenharmony_ci    CHECK_RETURN(status, false);
41623b3eb3cSopenharmony_ci    std::string format = "J:mm";
41723b3eb3cSopenharmony_ci    UnicodeString pattern = patternGenerator->getBestPattern(UnicodeString(format.c_str()), status);
41823b3eb3cSopenharmony_ci    delete patternGenerator;
41923b3eb3cSopenharmony_ci    CHECK_RETURN(status, false);
42023b3eb3cSopenharmony_ci
42123b3eb3cSopenharmony_ci    std::string result;
42223b3eb3cSopenharmony_ci    UnicodeString2String(pattern, result);
42323b3eb3cSopenharmony_ci
42423b3eb3cSopenharmony_ci    if (Contain(result, "hh") || Contain(result, "KK")) {
42523b3eb3cSopenharmony_ci        isAmPm = true;
42623b3eb3cSopenharmony_ci        hasZero = true;
42723b3eb3cSopenharmony_ci        return true;
42823b3eb3cSopenharmony_ci    }
42923b3eb3cSopenharmony_ci
43023b3eb3cSopenharmony_ci    if (Contain(result, "h") || Contain(result, "K")) {
43123b3eb3cSopenharmony_ci        isAmPm = true;
43223b3eb3cSopenharmony_ci        hasZero = false;
43323b3eb3cSopenharmony_ci        return true;
43423b3eb3cSopenharmony_ci    }
43523b3eb3cSopenharmony_ci
43623b3eb3cSopenharmony_ci    if (Contain(result, "HH") || Contain(result, "kk")) {
43723b3eb3cSopenharmony_ci        isAmPm = false;
43823b3eb3cSopenharmony_ci        hasZero = true;
43923b3eb3cSopenharmony_ci        return true;
44023b3eb3cSopenharmony_ci    }
44123b3eb3cSopenharmony_ci
44223b3eb3cSopenharmony_ci    if (Contain(result, "H") || Contain(result, "k")) {
44323b3eb3cSopenharmony_ci        isAmPm = false;
44423b3eb3cSopenharmony_ci        hasZero = false;
44523b3eb3cSopenharmony_ci        return true;
44623b3eb3cSopenharmony_ci    }
44723b3eb3cSopenharmony_ci
44823b3eb3cSopenharmony_ci    return false;
44923b3eb3cSopenharmony_ci}
45023b3eb3cSopenharmony_ci
45123b3eb3cSopenharmony_ciconst std::string Localization::FormatDateTime(DateTime dateTime, DateTimeStyle dateStyle, DateTimeStyle timeStyle)
45223b3eb3cSopenharmony_ci{
45323b3eb3cSopenharmony_ci    WaitingForInit();
45423b3eb3cSopenharmony_ci    UErrorCode status = U_ZERO_ERROR;
45523b3eb3cSopenharmony_ci    auto cal = Calendar::createInstance(locale_->instance, status);
45623b3eb3cSopenharmony_ci    CHECK_RETURN(status, "");
45723b3eb3cSopenharmony_ci    cal->set(dateTime.year, dateTime.month, dateTime.day, dateTime.hour, dateTime.minute, dateTime.second);
45823b3eb3cSopenharmony_ci
45923b3eb3cSopenharmony_ci    UDate date = cal->getTime(status);
46023b3eb3cSopenharmony_ci    delete cal;
46123b3eb3cSopenharmony_ci    CHECK_RETURN(status, "");
46223b3eb3cSopenharmony_ci
46323b3eb3cSopenharmony_ci    auto dateFormat = DateFormat::createDateTimeInstance(
46423b3eb3cSopenharmony_ci        DateTimeStyle2EStyle(dateStyle), DateTimeStyle2EStyle(timeStyle), locale_->instance);
46523b3eb3cSopenharmony_ci    if (dateFormat == nullptr) {
46623b3eb3cSopenharmony_ci        return "";
46723b3eb3cSopenharmony_ci    }
46823b3eb3cSopenharmony_ci
46923b3eb3cSopenharmony_ci    UnicodeString dateTimeStr;
47023b3eb3cSopenharmony_ci    dateFormat->format(date, dateTimeStr, status);
47123b3eb3cSopenharmony_ci    delete dateFormat;
47223b3eb3cSopenharmony_ci    CHECK_RETURN(status, "");
47323b3eb3cSopenharmony_ci
47423b3eb3cSopenharmony_ci    std::string ret;
47523b3eb3cSopenharmony_ci    UnicodeString2String(dateTimeStr, ret);
47623b3eb3cSopenharmony_ci    return ret;
47723b3eb3cSopenharmony_ci}
47823b3eb3cSopenharmony_ci
47923b3eb3cSopenharmony_cistd::vector<std::string> Localization::GetMonths(bool isShortType, const std::string& calendarType)
48023b3eb3cSopenharmony_ci{
48123b3eb3cSopenharmony_ci    WaitingForInit();
48223b3eb3cSopenharmony_ci    std::vector<std::string> months;
48323b3eb3cSopenharmony_ci    UErrorCode status = U_ZERO_ERROR;
48423b3eb3cSopenharmony_ci    DateFormatSymbols dateformat(locale_->instance, calendarType.c_str(), status);
48523b3eb3cSopenharmony_ci    CHECK_RETURN(status, months);
48623b3eb3cSopenharmony_ci
48723b3eb3cSopenharmony_ci    int32_t count = 0;
48823b3eb3cSopenharmony_ci
48923b3eb3cSopenharmony_ci    auto monthsUniStr = dateformat.getMonths(count, DateFormatSymbols::DtContextType::STANDALONE,
49023b3eb3cSopenharmony_ci        isShortType ? DateFormatSymbols::DtWidthType::SHORT : DateFormatSymbols::DtWidthType::WIDE);
49123b3eb3cSopenharmony_ci    if (count > 0) {
49223b3eb3cSopenharmony_ci        std::string month;
49323b3eb3cSopenharmony_ci        for (int32_t i = 0; i < count; i++) {
49423b3eb3cSopenharmony_ci            month.clear();
49523b3eb3cSopenharmony_ci            UnicodeString2String(monthsUniStr[i], month);
49623b3eb3cSopenharmony_ci            months.push_back(month);
49723b3eb3cSopenharmony_ci        }
49823b3eb3cSopenharmony_ci    }
49923b3eb3cSopenharmony_ci    return months;
50023b3eb3cSopenharmony_ci}
50123b3eb3cSopenharmony_ci
50223b3eb3cSopenharmony_cistd::vector<std::string> Localization::GetWeekdays(bool isShortType)
50323b3eb3cSopenharmony_ci{
50423b3eb3cSopenharmony_ci    WaitingForInit();
50523b3eb3cSopenharmony_ci    std::vector<std::string> weekdays;
50623b3eb3cSopenharmony_ci    UErrorCode status = U_ZERO_ERROR;
50723b3eb3cSopenharmony_ci    DateFormatSymbols dateformat(locale_->instance, status);
50823b3eb3cSopenharmony_ci    CHECK_RETURN(status, weekdays);
50923b3eb3cSopenharmony_ci
51023b3eb3cSopenharmony_ci    int32_t count = 0;
51123b3eb3cSopenharmony_ci
51223b3eb3cSopenharmony_ci    auto language = locale_->instance.getLanguage();
51323b3eb3cSopenharmony_ci    auto widthType = isShortType ? (strcmp(language, "zh") == 0 || strcmp(language, "bo") == 0)
51423b3eb3cSopenharmony_ci                                       ? DateFormatSymbols::DtWidthType::NARROW
51523b3eb3cSopenharmony_ci                                       : DateFormatSymbols::DtWidthType::ABBREVIATED
51623b3eb3cSopenharmony_ci                                 : DateFormatSymbols::DtWidthType::WIDE;
51723b3eb3cSopenharmony_ci    auto weekdaysUniStr = dateformat.getWeekdays(count, DateFormatSymbols::DtContextType::STANDALONE, widthType);
51823b3eb3cSopenharmony_ci    if (count > 0) {
51923b3eb3cSopenharmony_ci        std::string weekday;
52023b3eb3cSopenharmony_ci        for (int32_t i = 0; i < count; i++) {
52123b3eb3cSopenharmony_ci            weekday.clear();
52223b3eb3cSopenharmony_ci            UnicodeString2String(weekdaysUniStr[i], weekday);
52323b3eb3cSopenharmony_ci            if (!weekday.empty()) {
52423b3eb3cSopenharmony_ci                weekdays.push_back(weekday);
52523b3eb3cSopenharmony_ci            }
52623b3eb3cSopenharmony_ci        }
52723b3eb3cSopenharmony_ci    }
52823b3eb3cSopenharmony_ci    return weekdays;
52923b3eb3cSopenharmony_ci}
53023b3eb3cSopenharmony_ci
53123b3eb3cSopenharmony_cistd::vector<std::string> Localization::GetAmPmStrings()
53223b3eb3cSopenharmony_ci{
53323b3eb3cSopenharmony_ci    WaitingForInit();
53423b3eb3cSopenharmony_ci    std::vector<std::string> amPms;
53523b3eb3cSopenharmony_ci    UErrorCode status = U_ZERO_ERROR;
53623b3eb3cSopenharmony_ci    DateFormatSymbols dateformat(locale_->instance, status);
53723b3eb3cSopenharmony_ci    CHECK_RETURN(status, amPms);
53823b3eb3cSopenharmony_ci
53923b3eb3cSopenharmony_ci    int32_t count = 0;
54023b3eb3cSopenharmony_ci
54123b3eb3cSopenharmony_ci    auto amPmUniStr = dateformat.getAmPmStrings(count);
54223b3eb3cSopenharmony_ci    if (count > 0) {
54323b3eb3cSopenharmony_ci        std::string amPm;
54423b3eb3cSopenharmony_ci        for (int32_t i = 0; i < count; i++) {
54523b3eb3cSopenharmony_ci            amPm.clear();
54623b3eb3cSopenharmony_ci            UnicodeString2String(amPmUniStr[i], amPm);
54723b3eb3cSopenharmony_ci            amPms.push_back(amPm);
54823b3eb3cSopenharmony_ci        }
54923b3eb3cSopenharmony_ci    }
55023b3eb3cSopenharmony_ci    return amPms;
55123b3eb3cSopenharmony_ci}
55223b3eb3cSopenharmony_ci
55323b3eb3cSopenharmony_cistd::string Localization::GetRelativeDateTime(double offset)
55423b3eb3cSopenharmony_ci{
55523b3eb3cSopenharmony_ci    WaitingForInit();
55623b3eb3cSopenharmony_ci    UErrorCode status = U_ZERO_ERROR;
55723b3eb3cSopenharmony_ci    RelativeDateTimeFormatter relativeDateformat(locale_->instance, status);
55823b3eb3cSopenharmony_ci    CHECK_RETURN(status, "");
55923b3eb3cSopenharmony_ci
56023b3eb3cSopenharmony_ci    UnicodeString relativeDate;
56123b3eb3cSopenharmony_ci    relativeDateformat.format(offset, URelativeDateTimeUnit::UDAT_REL_UNIT_DAY, relativeDate, status);
56223b3eb3cSopenharmony_ci    CHECK_RETURN(status, "");
56323b3eb3cSopenharmony_ci
56423b3eb3cSopenharmony_ci    std::string ret;
56523b3eb3cSopenharmony_ci    UnicodeString2String(relativeDate, ret);
56623b3eb3cSopenharmony_ci    return ret;
56723b3eb3cSopenharmony_ci}
56823b3eb3cSopenharmony_ci
56923b3eb3cSopenharmony_ciLunarDate Localization::GetLunarDate(Date date)
57023b3eb3cSopenharmony_ci{
57123b3eb3cSopenharmony_ci    WaitingForInit();
57223b3eb3cSopenharmony_ci#if defined(IOS_PLATFORM) || defined(ANDROID_PLATFORM)
57323b3eb3cSopenharmony_ci    return GetIcuLunarDate(date);
57423b3eb3cSopenharmony_ci#else
57523b3eb3cSopenharmony_ci    LunarDate dateRet;
57623b3eb3cSopenharmony_ci    auto chineseCalendar = std::make_unique<Global::I18n::LunarCalendar>();
57723b3eb3cSopenharmony_ci    CHECK_NULL_RETURN(chineseCalendar, dateRet);
57823b3eb3cSopenharmony_ci    chineseCalendar->SetGregorianDate(date.year, date.month, date.day);
57923b3eb3cSopenharmony_ci    int32_t lunarYear = chineseCalendar->GetLunarYear();
58023b3eb3cSopenharmony_ci    CHECK_EQUAL_RETURN(lunarYear, -1, dateRet);
58123b3eb3cSopenharmony_ci    int32_t lunarMonth = chineseCalendar->GetLunarMonth();
58223b3eb3cSopenharmony_ci    CHECK_EQUAL_RETURN(lunarMonth, -1, dateRet);
58323b3eb3cSopenharmony_ci    int32_t lunarDay = chineseCalendar->GetLunarDay();
58423b3eb3cSopenharmony_ci    CHECK_EQUAL_RETURN(lunarDay, -1, dateRet);
58523b3eb3cSopenharmony_ci
58623b3eb3cSopenharmony_ci    dateRet.year = static_cast<uint32_t>(lunarYear);
58723b3eb3cSopenharmony_ci    dateRet.month = static_cast<uint32_t>(lunarMonth);
58823b3eb3cSopenharmony_ci    dateRet.day = static_cast<uint32_t>(lunarDay);
58923b3eb3cSopenharmony_ci    dateRet.isLeapMonth = chineseCalendar->IsLeapMonth();
59023b3eb3cSopenharmony_ci    return dateRet;
59123b3eb3cSopenharmony_ci#endif
59223b3eb3cSopenharmony_ci}
59323b3eb3cSopenharmony_ci
59423b3eb3cSopenharmony_ciLunarDate Localization::GetIcuLunarDate(Date date)
59523b3eb3cSopenharmony_ci{
59623b3eb3cSopenharmony_ci    LunarDate dateRet;
59723b3eb3cSopenharmony_ci    UErrorCode status = U_ZERO_ERROR;
59823b3eb3cSopenharmony_ci    Locale locale("zh", "CN");
59923b3eb3cSopenharmony_ci    auto cal = Calendar::createInstance(locale, status);
60023b3eb3cSopenharmony_ci    CHECK_RETURN(status, dateRet);
60123b3eb3cSopenharmony_ci    // 0 means January,  1 means February, so month - 1
60223b3eb3cSopenharmony_ci    if (date.month == 0u) {
60323b3eb3cSopenharmony_ci        date.month = 11u;
60423b3eb3cSopenharmony_ci        cal->set(date.year, date.month, date.day);
60523b3eb3cSopenharmony_ci    } else {
60623b3eb3cSopenharmony_ci        cal->set(date.year, date.month - 1u, date.day);
60723b3eb3cSopenharmony_ci    }
60823b3eb3cSopenharmony_ci    UDate udate = cal->getTime(status);
60923b3eb3cSopenharmony_ci    delete cal;
61023b3eb3cSopenharmony_ci    CHECK_RETURN(status, dateRet);
61123b3eb3cSopenharmony_ci
61223b3eb3cSopenharmony_ci    ChineseCalendar chineseCalendar(locale, status);
61323b3eb3cSopenharmony_ci    CHECK_RETURN(status, dateRet);
61423b3eb3cSopenharmony_ci
61523b3eb3cSopenharmony_ci    chineseCalendar.setTime(udate, status);
61623b3eb3cSopenharmony_ci    CHECK_RETURN(status, dateRet);
61723b3eb3cSopenharmony_ci
61823b3eb3cSopenharmony_ci    int32_t lunarYear = chineseCalendar.get(UCalendarDateFields::UCAL_YEAR, status);
61923b3eb3cSopenharmony_ci    CHECK_RETURN(status, dateRet);
62023b3eb3cSopenharmony_ci    int32_t lunarMonth = chineseCalendar.get(UCalendarDateFields::UCAL_MONTH, status);
62123b3eb3cSopenharmony_ci    CHECK_RETURN(status, dateRet);
62223b3eb3cSopenharmony_ci    int32_t lunarDate = chineseCalendar.get(UCalendarDateFields::UCAL_DATE, status);
62323b3eb3cSopenharmony_ci    CHECK_RETURN(status, dateRet);
62423b3eb3cSopenharmony_ci    int32_t isLeapMonth = chineseCalendar.get(UCalendarDateFields::UCAL_IS_LEAP_MONTH, status);
62523b3eb3cSopenharmony_ci    CHECK_RETURN(status, dateRet);
62623b3eb3cSopenharmony_ci
62723b3eb3cSopenharmony_ci    // Sexagenary cycle years convert to Western years
62823b3eb3cSopenharmony_ci    bool repeatCalc = false;
62923b3eb3cSopenharmony_ci    if ((static_cast<uint32_t>(date.year) - GUIHAI_YEAR_RECENT) % SEXAGENARY_CYCLE_SIZE == 0 ||
63023b3eb3cSopenharmony_ci        static_cast<uint32_t>(lunarYear) == SEXAGENARY_CYCLE_SIZE) {
63123b3eb3cSopenharmony_ci        repeatCalc = true;
63223b3eb3cSopenharmony_ci    }
63323b3eb3cSopenharmony_ci    dateRet.year = static_cast<uint32_t>(lunarYear) + GUIHAI_YEAR_RECENT;
63423b3eb3cSopenharmony_ci    dateRet.year +=
63523b3eb3cSopenharmony_ci        ((static_cast<uint32_t>(date.year) - GUIHAI_YEAR_RECENT) / SEXAGENARY_CYCLE_SIZE - (repeatCalc ? 1 : 0)) *
63623b3eb3cSopenharmony_ci        SEXAGENARY_CYCLE_SIZE;
63723b3eb3cSopenharmony_ci    // 0 means January,  1 means February, so month + 1
63823b3eb3cSopenharmony_ci    dateRet.month = static_cast<uint32_t>(lunarMonth) + 1;
63923b3eb3cSopenharmony_ci    dateRet.day = static_cast<uint32_t>(lunarDate);
64023b3eb3cSopenharmony_ci    dateRet.isLeapMonth = !(isLeapMonth == 0);
64123b3eb3cSopenharmony_ci    return dateRet;
64223b3eb3cSopenharmony_ci}
64323b3eb3cSopenharmony_ci
64423b3eb3cSopenharmony_cistd::string Localization::GetLunarMonth(uint32_t month, bool isLeapMonth)
64523b3eb3cSopenharmony_ci{
64623b3eb3cSopenharmony_ci    WaitingForInit();
64723b3eb3cSopenharmony_ci    std::vector<std::string> months = Localization::GetInstance()->GetMonths(false, "chinese");
64823b3eb3cSopenharmony_ci    if (month <= months.size() && month > 0) {
64923b3eb3cSopenharmony_ci        std::string leap;
65023b3eb3cSopenharmony_ci        if (isLeapMonth) {
65123b3eb3cSopenharmony_ci            leap += std::string(CHINESE_LEAP);
65223b3eb3cSopenharmony_ci        }
65323b3eb3cSopenharmony_ci        return leap + months[month - 1];
65423b3eb3cSopenharmony_ci    } else {
65523b3eb3cSopenharmony_ci        return "";
65623b3eb3cSopenharmony_ci    }
65723b3eb3cSopenharmony_ci}
65823b3eb3cSopenharmony_ci
65923b3eb3cSopenharmony_cistd::string Localization::GetLunarDay(uint32_t dayOfMonth)
66023b3eb3cSopenharmony_ci{
66123b3eb3cSopenharmony_ci    WaitingForInit();
66223b3eb3cSopenharmony_ci    if (dayOfMonth > 30 || dayOfMonth == 0) {
66323b3eb3cSopenharmony_ci        return "";
66423b3eb3cSopenharmony_ci    }
66523b3eb3cSopenharmony_ci
66623b3eb3cSopenharmony_ci    std::string ret;
66723b3eb3cSopenharmony_ci    if (dayOfMonth < 10) {
66823b3eb3cSopenharmony_ci        ret = std::string(CHINESE_FIRST) + std::string(g_chineseOneToNine[dayOfMonth - 1]);
66923b3eb3cSopenharmony_ci    } else if (dayOfMonth == 10) {
67023b3eb3cSopenharmony_ci        ret = std::string(CHINESE_FIRST) + std::string(CHINESE_TEN);
67123b3eb3cSopenharmony_ci    } else if (dayOfMonth < 20) {
67223b3eb3cSopenharmony_ci        ret = std::string(CHINESE_TEN) + std::string(g_chineseOneToNine[dayOfMonth - 11]);
67323b3eb3cSopenharmony_ci    } else if (dayOfMonth == 20) {
67423b3eb3cSopenharmony_ci        ret = std::string(CHINESE_TWENTY) + std::string(CHINESE_TEN);
67523b3eb3cSopenharmony_ci    } else if (dayOfMonth == 30) {
67623b3eb3cSopenharmony_ci        ret = g_chineseOneToNine[2] + std::string(CHINESE_TEN);
67723b3eb3cSopenharmony_ci    } else {
67823b3eb3cSopenharmony_ci        ret = std::string(CHINESE_TWENTY) + std::string(g_chineseOneToNine[dayOfMonth - 21]);
67923b3eb3cSopenharmony_ci    }
68023b3eb3cSopenharmony_ci
68123b3eb3cSopenharmony_ci    return ret;
68223b3eb3cSopenharmony_ci}
68323b3eb3cSopenharmony_ci
68423b3eb3cSopenharmony_cistd::string Localization::TimeUnitFormat(double timeValue, TimeUnitStyle timeStyle, MeasureFormatStyle formatStyle)
68523b3eb3cSopenharmony_ci{
68623b3eb3cSopenharmony_ci    WaitingForInit();
68723b3eb3cSopenharmony_ci    UErrorCode status = U_ZERO_ERROR;
68823b3eb3cSopenharmony_ci    MeasureFormat measureFormat(locale_->instance, GetMeasureFormatWidth(formatStyle), status);
68923b3eb3cSopenharmony_ci    CHECK_RETURN(status, "");
69023b3eb3cSopenharmony_ci
69123b3eb3cSopenharmony_ci    MeasureUnit* minuteUnit = GetMeasureUnit(timeStyle, status);
69223b3eb3cSopenharmony_ci    CHECK_RETURN(status, "");
69323b3eb3cSopenharmony_ci
69423b3eb3cSopenharmony_ci    Formattable formattable(timeValue);
69523b3eb3cSopenharmony_ci    Measure measure(formattable, minuteUnit, status);
69623b3eb3cSopenharmony_ci    CHECK_RETURN(status, "");
69723b3eb3cSopenharmony_ci
69823b3eb3cSopenharmony_ci    UnicodeString timeUnit;
69923b3eb3cSopenharmony_ci    FieldPosition fieldPosition;
70023b3eb3cSopenharmony_ci    measureFormat.formatMeasures(&measure, 1, timeUnit, fieldPosition, status);
70123b3eb3cSopenharmony_ci    CHECK_RETURN(status, "");
70223b3eb3cSopenharmony_ci
70323b3eb3cSopenharmony_ci    std::string ret;
70423b3eb3cSopenharmony_ci    UnicodeString2String(timeUnit, ret);
70523b3eb3cSopenharmony_ci    return ret;
70623b3eb3cSopenharmony_ci}
70723b3eb3cSopenharmony_ci
70823b3eb3cSopenharmony_cistd::string Localization::PluralRulesFormat(double number, bool isCardinal)
70923b3eb3cSopenharmony_ci{
71023b3eb3cSopenharmony_ci    WaitingForInit();
71123b3eb3cSopenharmony_ci    UErrorCode status = U_ZERO_ERROR;
71223b3eb3cSopenharmony_ci    UPluralType pluralType = isCardinal ? UPluralType::UPLURAL_TYPE_CARDINAL : UPluralType::UPLURAL_TYPE_ORDINAL;
71323b3eb3cSopenharmony_ci    PluralRules* pluralRules = PluralRules::forLocale(locale_->instance, pluralType, status);
71423b3eb3cSopenharmony_ci    CHECK_RETURN(status, "");
71523b3eb3cSopenharmony_ci
71623b3eb3cSopenharmony_ci    UnicodeString numberFormat = pluralRules->select(number);
71723b3eb3cSopenharmony_ci    delete pluralRules;
71823b3eb3cSopenharmony_ci
71923b3eb3cSopenharmony_ci    std::string ret;
72023b3eb3cSopenharmony_ci    UnicodeString2String(numberFormat, ret);
72123b3eb3cSopenharmony_ci    return ret;
72223b3eb3cSopenharmony_ci}
72323b3eb3cSopenharmony_ci
72423b3eb3cSopenharmony_cistd::string Localization::NumberFormat(double number)
72523b3eb3cSopenharmony_ci{
72623b3eb3cSopenharmony_ci    WaitingForInit();
72723b3eb3cSopenharmony_ci    UErrorCode status = U_ZERO_ERROR;
72823b3eb3cSopenharmony_ci
72923b3eb3cSopenharmony_ci    icu::number::LocalizedNumberFormatter formatter = icu::number::NumberFormatter::withLocale(locale_->instance);
73023b3eb3cSopenharmony_ci    icu::number::FormattedNumber formattedNumber = formatter.formatDouble(number, status);
73123b3eb3cSopenharmony_ci    CHECK_RETURN(status, "");
73223b3eb3cSopenharmony_ci
73323b3eb3cSopenharmony_ci    UnicodeString numberFormat = formattedNumber.toString(status);
73423b3eb3cSopenharmony_ci    CHECK_RETURN(status, "");
73523b3eb3cSopenharmony_ci
73623b3eb3cSopenharmony_ci    std::string ret;
73723b3eb3cSopenharmony_ci    UnicodeString2String(numberFormat, ret);
73823b3eb3cSopenharmony_ci    return ret;
73923b3eb3cSopenharmony_ci}
74023b3eb3cSopenharmony_ci
74123b3eb3cSopenharmony_cistd::vector<std::u16string> Localization::GetLetters(bool alphabet)
74223b3eb3cSopenharmony_ci{
74323b3eb3cSopenharmony_ci    WaitingForInit();
74423b3eb3cSopenharmony_ci    std::vector<std::u16string> letters;
74523b3eb3cSopenharmony_ci    size_t size = 0;
74623b3eb3cSopenharmony_ci    const uint8_t* buf =
74723b3eb3cSopenharmony_ci        InternalResource::GetInstance().GetResource(InternalResource::ResourceId::INDEXLETTER_BAR_JSON, size);
74823b3eb3cSopenharmony_ci    if (buf == nullptr) {
74923b3eb3cSopenharmony_ci        return letters;
75023b3eb3cSopenharmony_ci    }
75123b3eb3cSopenharmony_ci
75223b3eb3cSopenharmony_ci    std::string jsonStr(reinterpret_cast<const char*>(buf), size);
75323b3eb3cSopenharmony_ci    const char* endMsg = nullptr;
75423b3eb3cSopenharmony_ci    auto indexLetterJson = JsonUtil::ParseJsonString(jsonStr, &endMsg);
75523b3eb3cSopenharmony_ci    if (indexLetterJson == nullptr) {
75623b3eb3cSopenharmony_ci        return letters;
75723b3eb3cSopenharmony_ci    }
75823b3eb3cSopenharmony_ci
75923b3eb3cSopenharmony_ci    std::string language = locale_->instance.getLanguage();
76023b3eb3cSopenharmony_ci    if (language == "zh") {
76123b3eb3cSopenharmony_ci        language = language + "-" + std::string(locale_->instance.getCountry());
76223b3eb3cSopenharmony_ci    }
76323b3eb3cSopenharmony_ci    auto iter = LANGUAGE_CODE_MAP.find(language);
76423b3eb3cSopenharmony_ci    if (iter != LANGUAGE_CODE_MAP.end()) {
76523b3eb3cSopenharmony_ci        language = iter->second;
76623b3eb3cSopenharmony_ci    }
76723b3eb3cSopenharmony_ci    LOGI("[alphabet] Localization::GetLetters. language: %{private}s", language.c_str());
76823b3eb3cSopenharmony_ci    std::unique_ptr<JsonValue> lettersSet;
76923b3eb3cSopenharmony_ci    if (!indexLetterJson->Contains(language) || !indexLetterJson->GetValue(language)->IsObject()) {
77023b3eb3cSopenharmony_ci        lettersSet = indexLetterJson->GetValue("default");
77123b3eb3cSopenharmony_ci    } else {
77223b3eb3cSopenharmony_ci        lettersSet = indexLetterJson->GetValue(language);
77323b3eb3cSopenharmony_ci    }
77423b3eb3cSopenharmony_ci
77523b3eb3cSopenharmony_ci    std::string letterType = alphabet ? "alphabet" : "index";
77623b3eb3cSopenharmony_ci    std::unique_ptr<JsonValue> lettersArray;
77723b3eb3cSopenharmony_ci    if (!lettersSet->Contains(letterType) || !lettersSet->GetValue(letterType)->IsArray()) {
77823b3eb3cSopenharmony_ci        return letters;
77923b3eb3cSopenharmony_ci    } else {
78023b3eb3cSopenharmony_ci        lettersArray = lettersSet->GetValue(letterType)->GetChild();
78123b3eb3cSopenharmony_ci    }
78223b3eb3cSopenharmony_ci
78323b3eb3cSopenharmony_ci    while (lettersArray->IsValid()) {
78423b3eb3cSopenharmony_ci        letters.push_back(StringUtils::Str8ToStr16(lettersArray->GetString()));
78523b3eb3cSopenharmony_ci        lettersArray = lettersArray->GetNext();
78623b3eb3cSopenharmony_ci    }
78723b3eb3cSopenharmony_ci    return letters;
78823b3eb3cSopenharmony_ci}
78923b3eb3cSopenharmony_ci
79023b3eb3cSopenharmony_cistd::vector<std::u16string> Localization::GetIndexLetter()
79123b3eb3cSopenharmony_ci{
79223b3eb3cSopenharmony_ci    return GetLetters(false);
79323b3eb3cSopenharmony_ci}
79423b3eb3cSopenharmony_ci
79523b3eb3cSopenharmony_cistd::vector<std::u16string> Localization::GetIndexAlphabet()
79623b3eb3cSopenharmony_ci{
79723b3eb3cSopenharmony_ci    return GetLetters(true);
79823b3eb3cSopenharmony_ci}
79923b3eb3cSopenharmony_ci
80023b3eb3cSopenharmony_cistd::string Localization::GetEntryLetters(const std::string& lettersIndex)
80123b3eb3cSopenharmony_ci{
80223b3eb3cSopenharmony_ci    WaitingForInit();
80323b3eb3cSopenharmony_ci    if (lettersIndex.empty()) {
80423b3eb3cSopenharmony_ci        return "";
80523b3eb3cSopenharmony_ci    }
80623b3eb3cSopenharmony_ci
80723b3eb3cSopenharmony_ci    std::unique_ptr<JsonValue> localJsonEntry;
80823b3eb3cSopenharmony_ci    auto language = selectLanguage_;
80923b3eb3cSopenharmony_ci    auto iter = LANGUAGE_CODE_MAP.find(language);
81023b3eb3cSopenharmony_ci    if (iter != LANGUAGE_CODE_MAP.end()) {
81123b3eb3cSopenharmony_ci        language = iter->second;
81223b3eb3cSopenharmony_ci    }
81323b3eb3cSopenharmony_ci    GetLocalJsonObject(InternalResource::ResourceId::ENTRY_JSON, language, g_indexJsonEntry, localJsonEntry);
81423b3eb3cSopenharmony_ci    if (localJsonEntry == nullptr) {
81523b3eb3cSopenharmony_ci        LOGW("read JsonObject fail. language: %{public}s.", selectLanguage_.c_str());
81623b3eb3cSopenharmony_ci        return "";
81723b3eb3cSopenharmony_ci    }
81823b3eb3cSopenharmony_ci
81923b3eb3cSopenharmony_ci    std::vector<std::string> jsonLetterIndex;
82023b3eb3cSopenharmony_ci    StringUtils::StringSplitter(lettersIndex, JSON_PATH_CARVE, jsonLetterIndex);
82123b3eb3cSopenharmony_ci
82223b3eb3cSopenharmony_ci    for (const auto& letter : jsonLetterIndex) {
82323b3eb3cSopenharmony_ci        if (localJsonEntry && localJsonEntry->Contains(letter)) {
82423b3eb3cSopenharmony_ci            localJsonEntry = localJsonEntry->GetValue(letter);
82523b3eb3cSopenharmony_ci        } else {
82623b3eb3cSopenharmony_ci            return "";
82723b3eb3cSopenharmony_ci        }
82823b3eb3cSopenharmony_ci    }
82923b3eb3cSopenharmony_ci
83023b3eb3cSopenharmony_ci    if (localJsonEntry->IsString()) {
83123b3eb3cSopenharmony_ci        return localJsonEntry->GetString();
83223b3eb3cSopenharmony_ci    }
83323b3eb3cSopenharmony_ci
83423b3eb3cSopenharmony_ci    return "";
83523b3eb3cSopenharmony_ci}
83623b3eb3cSopenharmony_ci
83723b3eb3cSopenharmony_cistd::string Localization::GetErrorDescription(const std::string& errorIndex)
83823b3eb3cSopenharmony_ci{
83923b3eb3cSopenharmony_ci    WaitingForInit();
84023b3eb3cSopenharmony_ci    if (errorIndex.empty()) {
84123b3eb3cSopenharmony_ci        return "";
84223b3eb3cSopenharmony_ci    }
84323b3eb3cSopenharmony_ci
84423b3eb3cSopenharmony_ci    std::unique_ptr<JsonValue> localJsonError;
84523b3eb3cSopenharmony_ci    auto language = selectLanguage_;
84623b3eb3cSopenharmony_ci    auto iter = LANGUAGE_CODE_MAP.find(language);
84723b3eb3cSopenharmony_ci    if (iter != LANGUAGE_CODE_MAP.end()) {
84823b3eb3cSopenharmony_ci        language = iter->second;
84923b3eb3cSopenharmony_ci    }
85023b3eb3cSopenharmony_ci    GetLocalJsonObject(InternalResource::ResourceId::ERRORINFO_JSON, language, g_indexJsonError, localJsonError);
85123b3eb3cSopenharmony_ci    if (localJsonError == nullptr) {
85223b3eb3cSopenharmony_ci        LOGW("read JsonObject fail. language: %{public}s.", selectLanguage_.c_str());
85323b3eb3cSopenharmony_ci        return "";
85423b3eb3cSopenharmony_ci    }
85523b3eb3cSopenharmony_ci
85623b3eb3cSopenharmony_ci    if (localJsonError->Contains(errorIndex)) {
85723b3eb3cSopenharmony_ci        localJsonError = localJsonError->GetValue(errorIndex);
85823b3eb3cSopenharmony_ci    } else {
85923b3eb3cSopenharmony_ci        LOGW("read error json failed. error path: %{private}s.", errorIndex.c_str());
86023b3eb3cSopenharmony_ci        return "";
86123b3eb3cSopenharmony_ci    }
86223b3eb3cSopenharmony_ci
86323b3eb3cSopenharmony_ci    if (localJsonError->IsString()) {
86423b3eb3cSopenharmony_ci        return localJsonError->GetString();
86523b3eb3cSopenharmony_ci    }
86623b3eb3cSopenharmony_ci
86723b3eb3cSopenharmony_ci    return "";
86823b3eb3cSopenharmony_ci}
86923b3eb3cSopenharmony_ci
87023b3eb3cSopenharmony_ciconst std::vector<std::string>& Localization::GetLanguageList(const std::string& language)
87123b3eb3cSopenharmony_ci{
87223b3eb3cSopenharmony_ci    static const LinearMapNode<std::vector<std::string>> multiLanguageMap[] = {
87323b3eb3cSopenharmony_ci        { "am", { "am" } },
87423b3eb3cSopenharmony_ci        { "ar", { "ar" } },
87523b3eb3cSopenharmony_ci        { "as", { "as" } },
87623b3eb3cSopenharmony_ci        { "az", { "az-AZ" } },
87723b3eb3cSopenharmony_ci        { "be", { "be" } },
87823b3eb3cSopenharmony_ci        { "bg", { "bg" } },
87923b3eb3cSopenharmony_ci        { "bn", { "bn" } },
88023b3eb3cSopenharmony_ci        { "bo", { "bo-CN" } },
88123b3eb3cSopenharmony_ci        { "bs", { "bs" } },
88223b3eb3cSopenharmony_ci        { "ca", { "ca" } },
88323b3eb3cSopenharmony_ci        { "cs", { "cs" } },
88423b3eb3cSopenharmony_ci        { "da", { "da" } },
88523b3eb3cSopenharmony_ci        { "de", { "de" } },
88623b3eb3cSopenharmony_ci        { "el", { "el" } },
88723b3eb3cSopenharmony_ci        { "en", { "en-US", "en-GB" } },
88823b3eb3cSopenharmony_ci        { "es", { "es,es-US" } },
88923b3eb3cSopenharmony_ci        { "et", { "et" } },
89023b3eb3cSopenharmony_ci        { "fa", { "fa" } },
89123b3eb3cSopenharmony_ci        { "fi", { "fi" } },
89223b3eb3cSopenharmony_ci        { "fil", { "fil" } },
89323b3eb3cSopenharmony_ci        { "fr", { "fr" } },
89423b3eb3cSopenharmony_ci        { "gl", { "gl-ES" } },
89523b3eb3cSopenharmony_ci        { "he", { "he" } },
89623b3eb3cSopenharmony_ci        { "hi", { "hi" } },
89723b3eb3cSopenharmony_ci        { "hr", { "hr" } },
89823b3eb3cSopenharmony_ci        { "hu", { "hu" } },
89923b3eb3cSopenharmony_ci        { "id", { "id" } },
90023b3eb3cSopenharmony_ci        { "in", { "in" } },
90123b3eb3cSopenharmony_ci        { "it", { "it" } },
90223b3eb3cSopenharmony_ci        { "iw", { "iw" } },
90323b3eb3cSopenharmony_ci        { "ja", { "ja" } },
90423b3eb3cSopenharmony_ci        { "jv", { "jv-Latn" } },
90523b3eb3cSopenharmony_ci        { "ka", { "ka-GE" } },
90623b3eb3cSopenharmony_ci        { "kk", { "kk-KZ" } },
90723b3eb3cSopenharmony_ci        { "km", { "km-KH" } },
90823b3eb3cSopenharmony_ci        { "kn", { "kn" } },
90923b3eb3cSopenharmony_ci        { "ko", { "ko" } },
91023b3eb3cSopenharmony_ci        { "lo", { "lo-LA" } },
91123b3eb3cSopenharmony_ci        { "lt", { "lt" } },
91223b3eb3cSopenharmony_ci        { "lv", { "lv" } },
91323b3eb3cSopenharmony_ci        { "mai", { "mai" } },
91423b3eb3cSopenharmony_ci        { "mi", { "mi" } },
91523b3eb3cSopenharmony_ci        { "mk", { "mk" } },
91623b3eb3cSopenharmony_ci        { "ml", { "ml" } },
91723b3eb3cSopenharmony_ci        { "mn", { "mn" } },
91823b3eb3cSopenharmony_ci        { "mr", { "mr" } },
91923b3eb3cSopenharmony_ci        { "ms", { "ms" } },
92023b3eb3cSopenharmony_ci        { "my", { "my-ZG", "my-MM" } },
92123b3eb3cSopenharmony_ci        { "nb", { "nb" } },
92223b3eb3cSopenharmony_ci        { "ne", { "ne" } },
92323b3eb3cSopenharmony_ci        { "nl", { "nl" } },
92423b3eb3cSopenharmony_ci        { "or", { "or" } },
92523b3eb3cSopenharmony_ci        { "pa", { "pa" } },
92623b3eb3cSopenharmony_ci        { "pl", { "pl" } },
92723b3eb3cSopenharmony_ci        { "pt", { "pt", "pt-PT" } },
92823b3eb3cSopenharmony_ci        { "ro", { "ro" } },
92923b3eb3cSopenharmony_ci        { "ru", { "ru" } },
93023b3eb3cSopenharmony_ci        { "si", { "si-LK" } },
93123b3eb3cSopenharmony_ci        { "sk", { "sk" } },
93223b3eb3cSopenharmony_ci        { "sl", { "sl" } },
93323b3eb3cSopenharmony_ci        { "sr", { "sr-Latn" } },
93423b3eb3cSopenharmony_ci        { "sv", { "sv" } },
93523b3eb3cSopenharmony_ci        { "sw", { "sw" } },
93623b3eb3cSopenharmony_ci        { "ta", { "ta" } },
93723b3eb3cSopenharmony_ci        { "te", { "te" } },
93823b3eb3cSopenharmony_ci        { "th", { "th" } },
93923b3eb3cSopenharmony_ci        { "tl", { "tl" } },
94023b3eb3cSopenharmony_ci        { "tr", { "tr" } },
94123b3eb3cSopenharmony_ci        { "ug", { "ug" } },
94223b3eb3cSopenharmony_ci        { "uk", { "uk" } },
94323b3eb3cSopenharmony_ci        { "ur", { "ur" } },
94423b3eb3cSopenharmony_ci        { "uz", { "uz-UZ" } },
94523b3eb3cSopenharmony_ci        { "vi", { "vi" } },
94623b3eb3cSopenharmony_ci        { "zh", { "zh-CN", "zh-HK", "zh-TW" } },
94723b3eb3cSopenharmony_ci        { "zz", { "zz-ZX" } },
94823b3eb3cSopenharmony_ci    };
94923b3eb3cSopenharmony_ci    int64_t list = BinarySearchFindIndex(multiLanguageMap, ArraySize(multiLanguageMap), language.c_str());
95023b3eb3cSopenharmony_ci    if (list == -1) {
95123b3eb3cSopenharmony_ci        static const std::vector<std::string> defaultLanguage = { "en-US" };
95223b3eb3cSopenharmony_ci        return defaultLanguage;
95323b3eb3cSopenharmony_ci    }
95423b3eb3cSopenharmony_ci    return multiLanguageMap[list].value;
95523b3eb3cSopenharmony_ci}
95623b3eb3cSopenharmony_ci
95723b3eb3cSopenharmony_cistd::mutex Localization::mutex_;
95823b3eb3cSopenharmony_cistd::shared_ptr<Localization> Localization::instance_;
95923b3eb3cSopenharmony_cibool Localization::firstInstance_ = true;
96023b3eb3cSopenharmony_ci
96123b3eb3cSopenharmony_cistd::shared_ptr<Localization> Localization::GetInstance()
96223b3eb3cSopenharmony_ci{
96323b3eb3cSopenharmony_ci    std::lock_guard<std::mutex> lock(mutex_);
96423b3eb3cSopenharmony_ci    if (!instance_) {
96523b3eb3cSopenharmony_ci        instance_ = std::make_shared<Localization>();
96623b3eb3cSopenharmony_ci    }
96723b3eb3cSopenharmony_ci    return instance_;
96823b3eb3cSopenharmony_ci}
96923b3eb3cSopenharmony_ci
97023b3eb3cSopenharmony_civoid Localization::SetLocale(const std::string& language, const std::string& countryOrRegion, const std::string& script,
97123b3eb3cSopenharmony_ci    const std::string& selectLanguage, const std::string& keywordsAndValues)
97223b3eb3cSopenharmony_ci{
97323b3eb3cSopenharmony_ci    std::lock_guard<std::mutex> lock(mutex_);
97423b3eb3cSopenharmony_ci
97523b3eb3cSopenharmony_ci    if (instance_) {
97623b3eb3cSopenharmony_ci        instance_->HandleOnChange();
97723b3eb3cSopenharmony_ci        instance_->HandleOnMymrChange(script == "Qaag");
97823b3eb3cSopenharmony_ci    }
97923b3eb3cSopenharmony_ci
98023b3eb3cSopenharmony_ci    std::shared_ptr<Localization> instance;
98123b3eb3cSopenharmony_ci    if (!firstInstance_ || !instance_) {
98223b3eb3cSopenharmony_ci        if (instance_) {
98323b3eb3cSopenharmony_ci            auto onMymrChange = instance_->GetOnMymrChange();
98423b3eb3cSopenharmony_ci            instance_ = std::make_shared<Localization>();
98523b3eb3cSopenharmony_ci            instance_->SetOnMymrChange(onMymrChange);
98623b3eb3cSopenharmony_ci        } else {
98723b3eb3cSopenharmony_ci            instance_ = std::make_shared<Localization>();
98823b3eb3cSopenharmony_ci        }
98923b3eb3cSopenharmony_ci    }
99023b3eb3cSopenharmony_ci
99123b3eb3cSopenharmony_ci    firstInstance_ = false;
99223b3eb3cSopenharmony_ci    instance = instance_;
99323b3eb3cSopenharmony_ci
99423b3eb3cSopenharmony_ci    instance->SetLocaleImpl(language, countryOrRegion, script, selectLanguage, keywordsAndValues);
99523b3eb3cSopenharmony_ci}
99623b3eb3cSopenharmony_ci
99723b3eb3cSopenharmony_cistd::string Localization::ComputeScript(const std::string& language, const std::string& region)
99823b3eb3cSopenharmony_ci{
99923b3eb3cSopenharmony_ci    icu::Locale locale(language.c_str(), region.c_str());
100023b3eb3cSopenharmony_ci    UErrorCode status = U_ZERO_ERROR;
100123b3eb3cSopenharmony_ci    locale.addLikelySubtags(status);
100223b3eb3cSopenharmony_ci    if (status != U_ZERO_ERROR) {
100323b3eb3cSopenharmony_ci        return std::string();
100423b3eb3cSopenharmony_ci    }
100523b3eb3cSopenharmony_ci    return locale.getScript();
100623b3eb3cSopenharmony_ci}
100723b3eb3cSopenharmony_ci
100823b3eb3cSopenharmony_civoid Localization::ParseLocaleTag(
100923b3eb3cSopenharmony_ci    const std::string& localeTag, std::string& language, std::string& script, std::string& region, bool needAddSubtags)
101023b3eb3cSopenharmony_ci{
101123b3eb3cSopenharmony_ci    UErrorCode status = U_ZERO_ERROR;
101223b3eb3cSopenharmony_ci    icu::Locale locale = icu::Locale::forLanguageTag(icu::StringPiece(localeTag.c_str()), status);
101323b3eb3cSopenharmony_ci    if (needAddSubtags) {
101423b3eb3cSopenharmony_ci        locale.addLikelySubtags(status);
101523b3eb3cSopenharmony_ci    }
101623b3eb3cSopenharmony_ci    if (status != U_ZERO_ERROR) {
101723b3eb3cSopenharmony_ci        return;
101823b3eb3cSopenharmony_ci    }
101923b3eb3cSopenharmony_ci    language = locale.getLanguage();
102023b3eb3cSopenharmony_ci    script = locale.getScript();
102123b3eb3cSopenharmony_ci    region = locale.getCountry();
102223b3eb3cSopenharmony_ci}
102323b3eb3cSopenharmony_ci
102423b3eb3cSopenharmony_ci} // namespace OHOS::Ace
1025