提交 3759d35e 编写于 作者: S sunyaozu

add Class TimeZone

Signed-off-by: Nsunyaozu <sunyaozu@huawei.com>
上级 6320cb7f
......@@ -74,6 +74,7 @@ ohos_shared_library("intl_util") {
"src/date_time_format.cpp",
"src/i18n_break_iterator.cpp",
"src/i18n_calendar.cpp",
"src/i18n_timezone.cpp",
"src/index_util.cpp",
"src/locale_config.cpp",
"src/locale_info.cpp",
......
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except", "in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef OHOS_GLOBAL_I18N_TIMEZONE_H
#define OHOS_GLOBAL_I18N_TIMEZONE_H
#include <string>
#include "unicode/timezone.h"
namespace OHOS {
namespace Global {
namespace I18n {
class I18nTimeZone {
public:
I18nTimeZone(std::string zoneID);
~I18nTimeZone();
int32_t GetOffset(double date);
int32_t GetRawOffset();
std::string GetID();
std::string GetDisplayName();
std::string GetDisplayName(bool isDST);
std::string GetDisplayName(std::string localeStr);
std::string GetDisplayName(std::string localeStr, bool isDST);
private:
icu::TimeZone *timezone;
};
} // namespace I18n
} // namespace Global
} // namespace OHOS
#endif
\ No newline at end of file
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "locale_config.h"
#include "unicode/locid.h"
#include "unicode/unistr.h"
#include "i18n_timezone.h"
namespace OHOS {
namespace Global {
namespace I18n {
I18nTimeZone::I18nTimeZone(std::string zoneID)
{
if (zoneID.empty()) {
timezone = icu::TimeZone::createDefault();
} else {
icu::UnicodeString unicodeZoneID(zoneID.data(), zoneID.length());
timezone = icu::TimeZone::createTimeZone(unicodeZoneID);
}
}
I18nTimeZone::~I18nTimeZone()
{
if (timezone != nullptr) {
delete timezone;
timezone = nullptr;
}
}
int32_t I18nTimeZone::GetOffset(double date)
{
int32_t rawOffset = 0;
int32_t dstOffset = 0;
bool local = false;
UErrorCode status = U_ZERO_ERROR;
timezone->getOffset(date, (UBool)local, rawOffset, dstOffset, status);
if (status != U_ZERO_ERROR) {
return 0;
}
return rawOffset + dstOffset;
}
int32_t I18nTimeZone::GetRawOffset()
{
return timezone->getRawOffset();
}
std::string I18nTimeZone::GetID()
{
icu::UnicodeString zoneID;
timezone->getID(zoneID);
std::string result;
zoneID.toUTF8String(result);
return result;
}
std::string I18nTimeZone::GetDisplayName()
{
std::string localeStr = LocaleConfig::GetSystemLocale();
return GetDisplayName(localeStr, false);
}
std::string I18nTimeZone::GetDisplayName(bool isDST)
{
std::string localeStr = LocaleConfig::GetSystemLocale();
return GetDisplayName(localeStr, isDST);
}
std::string I18nTimeZone::GetDisplayName(std::string localeStr)
{
return GetDisplayName(localeStr, false);
}
std::string I18nTimeZone::GetDisplayName(std::string localeStr, bool isDST)
{
icu::TimeZone::EDisplayType style = icu::TimeZone::EDisplayType::LONG_GENERIC;
icu::Locale locale(localeStr.data());
icu::UnicodeString name;
timezone->getDisplayName((UBool)isDST, style, locale, name);
std::string result;
name.toUTF8String(result);
return result;
}
}
}
}
\ No newline at end of file
......@@ -20,6 +20,7 @@
#include "napi/native_api.h"
#include "i18n_break_iterator.h"
#include "i18n_calendar.h"
#include "i18n_timezone.h"
#include "index_util.h"
#include "napi/native_node_api.h"
#include "locale_config.h"
......@@ -73,6 +74,8 @@ public:
static napi_value RemovePreferredLanguage(napi_env env, napi_callback_info info);
static napi_value GetPreferredLanguageList(napi_env env, napi_callback_info info);
static napi_value GetFirstPreferredLanguage(napi_env env, napi_callback_info info);
static napi_value InitI18nTimeZone(napi_env env, napi_value exports);
static napi_value GetI18nTimeZone(napi_env env, napi_callback_info info);
private:
static void CreateInitProperties(napi_property_descriptor *properties);
......@@ -122,12 +125,20 @@ private:
static napi_value CreateUtilObject(napi_env env);
static napi_value CreateCharacterObject(napi_env env);
static napi_value I18nTimeZoneConstructor(napi_env env, napi_callback_info info);
static napi_value GetID(napi_env env, napi_callback_info info);
static int32_t GetParameter(napi_env env, napi_value *argv, std::string &localeStr, bool &isDST);
static napi_value GetTimeZoneDisplayName(napi_env env, napi_callback_info info);
static napi_value GetOffset(napi_env env, napi_callback_info info);
static napi_value GetRawOffset(napi_env env, napi_callback_info info);
napi_env env_;
napi_ref wrapper_;
std::unique_ptr<PhoneNumberFormat> phonenumberfmt_;
std::unique_ptr<I18nCalendar> calendar_;
std::unique_ptr<I18nBreakIterator> brkiter_;
std::unique_ptr<IndexUtil> indexUtil_;
std::unique_ptr<I18nTimeZone> timezone_;
};
} // namespace I18n
} // namespace Global
......
......@@ -26,6 +26,7 @@ namespace I18n {
static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, 0xD001E00, "I18nJs" };
static thread_local napi_ref* g_constructor = nullptr;
static thread_local napi_ref* g_brkConstructor = nullptr;
static thread_local napi_ref* g_timezoneConstructor = nullptr;
static thread_local napi_ref g_indexUtilConstructor = nullptr;
static std::unordered_map<std::string, UCalendarDateFields> g_fieldsMap {
{ "era", UCAL_ERA },
......@@ -141,6 +142,8 @@ void I18nAddon::CreateInitProperties(napi_property_descriptor *properties)
properties[21] = DECLARE_NAPI_FUNCTION("is24HourClock", Is24HourClock);
// 22 is properties index
properties[22] = DECLARE_NAPI_FUNCTION("set24HourClock", Set24HourClock);
// 23 is properties index
properties[23] = DECLARE_NAPI_FUNCTION("getTimeZone", GetI18nTimeZone);
}
napi_value I18nAddon::Init(napi_env env, napi_value exports)
......@@ -166,7 +169,7 @@ napi_value I18nAddon::Init(napi_env env, napi_value exports)
if (character == nullptr) {
return nullptr;
}
size_t propertiesNums = 23;
size_t propertiesNums = 24;
napi_property_descriptor properties[propertiesNums];
CreateInitProperties(properties);
properties[13] = DECLARE_NAPI_PROPERTY("Util", util); // 13 is properties index
......@@ -2382,13 +2385,287 @@ napi_value I18nAddon::GetFirstPreferredLanguage(napi_env env, napi_callback_info
return result;
}
napi_value I18nAddon::InitI18nTimeZone(napi_env env, napi_value exports)
{
napi_status status = napi_ok;
napi_property_descriptor properties[] = {
DECLARE_NAPI_FUNCTION("getID", GetID),
DECLARE_NAPI_FUNCTION("getDisplayName", GetTimeZoneDisplayName),
DECLARE_NAPI_FUNCTION("getRawOffset", GetRawOffset),
DECLARE_NAPI_FUNCTION("getOffset", GetOffset),
};
napi_value constructor = nullptr;
status = napi_define_class(env, "TimeZone", NAPI_AUTO_LENGTH, I18nTimeZoneConstructor, nullptr,
sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor);
if (status != napi_ok) {
HiLog::Error(LABEL, "Failed to define class TimeZone at Init");
return nullptr;
}
g_timezoneConstructor = new (std::nothrow) napi_ref;
if (g_timezoneConstructor == nullptr) {
HiLog::Error(LABEL, "Failed to create TimeZone ref at init");
return nullptr;
}
status = napi_create_reference(env, constructor, 1, g_timezoneConstructor);
if (status != napi_ok) {
HiLog::Error(LABEL, "Failed to create reference g_timezoneConstructor at init");
return nullptr;
}
return exports;
}
napi_value I18nAddon::I18nTimeZoneConstructor(napi_env env, napi_callback_info info)
{
size_t argc = 1;
napi_value argv[1] = { nullptr };
napi_value thisVar = nullptr;
void *data = nullptr;
napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
if (status != napi_ok) {
return nullptr;
}
std::string zoneID = "";
if (argv[0] != nullptr) {
napi_valuetype valueType = napi_valuetype::napi_undefined;
napi_typeof(env, argv[0], &valueType);
if (valueType != napi_valuetype::napi_string) {
napi_throw_type_error(env, nullptr, "Parameter type does not match");
return nullptr;
}
int32_t code = 0;
zoneID = GetString(env, argv[0], code);
if (code != 0) {
return nullptr;
}
}
std::unique_ptr<I18nAddon> obj = std::make_unique<I18nAddon>();
if (obj == nullptr) {
HiLog::Error(LABEL, "Create I18nAddon failed");
return nullptr;
}
status =
napi_wrap(env, thisVar, reinterpret_cast<void *>(obj.get()), I18nAddon::Destructor, nullptr, &obj->wrapper_);
if (status != napi_ok) {
HiLog::Error(LABEL, "Wrap II18nAddon failed");
return nullptr;
}
obj->timezone_ = std::make_unique<I18nTimeZone>(zoneID);
if (obj->timezone_ == nullptr) {
HiLog::Error(LABEL, "Wrap TimeZone failed");
return nullptr;
}
obj.release();
return thisVar;
}
napi_value I18nAddon::GetI18nTimeZone(napi_env env, napi_callback_info info)
{
size_t argc = 1;
napi_value argv[1] = { nullptr };
napi_value thisVar = nullptr;
void *data = nullptr;
napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
napi_value constructor = nullptr;
napi_status status = napi_get_reference_value(env, *g_timezoneConstructor, &constructor);
if (status != napi_ok) {
HiLog::Error(LABEL, "Failed to create reference at GetTimeZoneInstance");
return nullptr;
}
napi_value result = nullptr;
if (argv[0] == nullptr) {
status = napi_new_instance(env, constructor, 0, nullptr, &result); // 1 arguments
} else {
status = napi_new_instance(env, constructor, 1, argv, &result); // 1 arguments
}
if (status != napi_ok) {
HiLog::Error(LABEL, "GetTimeZone create instance failed");
return nullptr;
}
return result;
}
napi_value I18nAddon::GetID(napi_env env, napi_callback_info info)
{
size_t argc = 0;
napi_value *argv = nullptr;
napi_value thisVar = nullptr;
void *data = nullptr;
napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
I18nAddon *obj = nullptr;
napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
if (status != napi_ok || obj == nullptr || obj->timezone_ == nullptr) {
HiLog::Error(LABEL, "Get TimeZone object failed");
return nullptr;
}
std::string result = obj->timezone_->GetID();
napi_value value = nullptr;
status = napi_create_string_utf8(env, result.c_str(), NAPI_AUTO_LENGTH, &value);
if (status != napi_ok) {
HiLog::Error(LABEL, "Create result failed");
return nullptr;
}
return value;
}
int32_t I18nAddon::GetParameter(napi_env env, napi_value *argv, std::string &localeStr, bool &isDST)
{
if (argv[0] == nullptr) {
return 0; // 0 represents no parameter.
}
napi_status status = napi_ok;
size_t len = 0;
if (argv[1] == nullptr) {
napi_valuetype valueType = napi_valuetype::napi_undefined;
napi_typeof(env, argv[0], &valueType);
if (valueType == napi_valuetype::napi_string) {
status = napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
std::vector<char> buf(len + 1);
status = napi_get_value_string_utf8(env, argv[0], buf.data(), len + 1, &len);
localeStr.insert(localeStr.end(), buf.begin(), buf.end());
if (status != napi_ok) {
return -1; // -1 represents Invalid parameter.
}
return 1; // 1 represents one string parameter.
} else if (valueType == napi_valuetype::napi_boolean) {
status = napi_get_value_bool(env, argv[0], &isDST);
if (status != napi_ok) {
return -1; // -1 represents Invalid parameter.
}
return 2; // 2 represents one boolean parameter.
} else {
return -1; // -1 represents Invalid parameter.
}
}
napi_valuetype valueType0 = napi_valuetype::napi_undefined;
napi_valuetype valueType1 = napi_valuetype::napi_undefined;
napi_typeof(env, argv[0], &valueType0); // 0 represents first parameter
napi_typeof(env, argv[1], &valueType1); // 0 represents second parameter
if (valueType0 != napi_valuetype::napi_string || valueType1 != napi_valuetype::napi_boolean) {
return -1; // -1 represents Invalid parameter.
}
status = napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
std::vector<char> buf(len + 1);
status = napi_get_value_string_utf8(env, argv[0], buf.data(), len + 1, &len);
localeStr.insert(localeStr.end(), buf.begin(), buf.end());
status = napi_get_value_bool(env, argv[1], &isDST);
if (status != napi_ok) {
return -1; // -1 represents Invalid parameter.
}
return 3; // 3 represents one string parameter and one bool parameter.
}
napi_value I18nAddon::GetTimeZoneDisplayName(napi_env env, napi_callback_info info)
{
size_t argc = 2;
napi_value argv[2] = { 0 };
napi_value thisVar = nullptr;
void *data = nullptr;
napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
I18nAddon *obj = nullptr;
status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
if (status != napi_ok || obj == nullptr || obj->timezone_ == nullptr) {
HiLog::Error(LABEL, "Get TimeZone object failed");
return nullptr;
}
std::string locale;
bool isDST = false;
int32_t parameterStatus = GetParameter(env, argv, locale, isDST);
std::string result;
if (parameterStatus == -1) { // -1 represents Invalid parameter.
napi_throw_type_error(env, nullptr, "Parameter type does not match");
return nullptr;
} else if (parameterStatus == 0) {
result = obj->timezone_->GetDisplayName();
} else if (parameterStatus == 1) { // 1 represents one string parameter.
result = obj->timezone_->GetDisplayName(locale);
} else if (parameterStatus == 2) { // 2 represents one boolean parameter.
result = obj->timezone_->GetDisplayName(isDST);
} else {
result = obj->timezone_->GetDisplayName(locale, isDST);
}
napi_value value = nullptr;
status = napi_create_string_utf8(env, result.c_str(), NAPI_AUTO_LENGTH, &value);
if (status != napi_ok) {
HiLog::Error(LABEL, "Create result failed");
return nullptr;
}
return value;
}
napi_value I18nAddon::GetOffset(napi_env env, napi_callback_info info)
{
size_t argc = 1;
napi_value argv[1] = { 0 };
napi_value thisVar = nullptr;
void *data = nullptr;
napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
napi_valuetype valueType = napi_valuetype::napi_undefined;
napi_typeof(env, argv[0], &valueType);
if (valueType != napi_valuetype::napi_number) {
HiLog::Error(LABEL, "Invalid parameter type");
return nullptr;
}
double date = 0;
status = napi_get_value_double(env, argv[0], &date);
if (status != napi_ok) {
HiLog::Error(LABEL, "Get parameter date failed");
return nullptr;
}
I18nAddon *obj = nullptr;
status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
if (status != napi_ok || obj == nullptr || obj->timezone_ == nullptr) {
HiLog::Error(LABEL, "Get TimeZone object failed");
return nullptr;
}
int32_t result = obj->timezone_->GetOffset(date);
napi_value value = nullptr;
status = napi_create_int32(env, result, &value);
if (status != napi_ok) {
HiLog::Error(LABEL, "Create result failed");
return nullptr;
}
return value;
}
napi_value I18nAddon::GetRawOffset(napi_env env, napi_callback_info info)
{
size_t argc = 0;
napi_value *argv = nullptr;
napi_value thisVar = nullptr;
void *data = nullptr;
napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
I18nAddon *obj = nullptr;
napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
if (status != napi_ok || obj == nullptr || obj->timezone_ == nullptr) {
HiLog::Error(LABEL, "Get TimeZone object failed");
return nullptr;
}
int32_t result = obj->timezone_->GetRawOffset();
napi_value value = nullptr;
status = napi_create_int32(env, result, &value);
if (status != napi_ok) {
HiLog::Error(LABEL, "Create result failed");
return nullptr;
}
return value;
}
napi_value Init(napi_env env, napi_value exports)
{
napi_value val = I18nAddon::Init(env, exports);
val = I18nAddon::InitPhoneNumberFormat(env, val);
val = I18nAddon::InitBreakIterator(env, val);
val = I18nAddon::InitI18nCalendar(env, val);
return I18nAddon::InitIndexUtil(env, val);
val = I18nAddon::InitIndexUtil(env, val);
return I18nAddon::InitI18nTimeZone(env, val);
}
static napi_module g_i18nModule = {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册