• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "time_zone_info.h"
17 
18 namespace OHOS {
19 namespace MiscServices {
20 namespace {
21     constexpr const char *TIMEZONE_KEY = "persist.time.timezone";
22     const int TIMEZONE_OK = 0;
23     const int CONFIG_LEN = 35;
24     const int HOUR_TO_MILLI = 60;
25 }
26 
TimeZoneInfo()27 TimeZoneInfo::TimeZoneInfo()
28 {
29     std::vector<struct zoneInfoEntry> timezoneList = { { "Antarctica/McMurdo", "AQ", 12 },
30         { "America/Argentina/Buenos_Aires", "AR", -3 }, { "Australia/Sydney", "AU", 10 },
31         { "America/Noronha", "BR", -2 }, { "America/St_Johns", "CA", -3 }, { "Africa/Kinshasa", "CD", 1 },
32         { "America/Santiago", "CL", -3 }, { "Asia/Shanghai", "CN", 8 }, { "Asia/Nicosia", "CY", 3 },
33         { "Europe/Berlin", "DE", 2 }, { "America/Guayaquil", "CEST", -5 }, { "Europe/Madrid", "ES", 2 },
34         { "Pacific/Pohnpei", "FM", 11 }, { "America/Godthab", "GL", -2 }, { "Asia/Jakarta", "ID", 7 },
35         { "Pacific/Tarawa", "KI", 12 }, { "Asia/Almaty", "KZ", 6 }, { "Pacific/Majuro", "MH", 12 },
36         { "Asia/Ulaanbaatar", "MN", 8 }, { "America/Mexico_City", "MX", -5 }, { "Asia/Kuala_Lumpur", "MY", 8 },
37         { "Pacific/Auckland", "NZ", 12 }, { "Pacific/Tahiti", "PF", -10 }, { "Pacific/Port_Moresby", "PG", 10 },
38         { "Asia/Gaza", "PS", 3 }, { "Europe/Lisbon", "PT", 1 }, { "Europe/Moscow", "RU", 3 },
39         { "Europe/Kiev", "UA", 3 }, { "Pacific/Wake", "UM", 12 }, { "America/New_York", "US", -4 },
40         { "Asia/Tashkent", "UZ", 5 } };
41 
42     for (const auto &tz : timezoneList) {
43         timezoneInfoMap_[tz.ID] = tz;
44     }
45 }
46 
~TimeZoneInfo()47 TimeZoneInfo::~TimeZoneInfo()
48 {
49     timezoneInfoMap_.clear();
50 }
51 
Init()52 void TimeZoneInfo::Init()
53 {
54     TIME_HILOGD(TIME_MODULE_SERVICE, "Start.");
55     char value[CONFIG_LEN] = "Asia/Shanghai";
56     if (GetParameter(TIMEZONE_KEY, "", value, CONFIG_LEN) < TIMEZONE_OK) {
57         TIME_HILOGW(TIME_MODULE_SERVICE, "No found timezone from system parameter.");
58     }
59 
60     if (!SetTimezoneToKernel(value)) {
61         TIME_HILOGE(TIME_MODULE_SERVICE, "Init Set kernel failed.");
62     }
63     curTimezoneId_ = value;
64     TIME_HILOGI(TIME_MODULE_SERVICE, "Timezone value: %{public}s", value);
65 }
66 
SetTimezone(std::string timezoneId)67 bool TimeZoneInfo::SetTimezone(std::string timezoneId)
68 {
69     if (curTimezoneId_ == timezoneId) {
70         TIME_HILOGI(TIME_MODULE_SERVICE, "Same Timezone has been set.");
71         return true;
72     }
73 
74     auto errNo = SetParameter(TIMEZONE_KEY, timezoneId.c_str());
75     if (errNo > TIMEZONE_OK) {
76         TIME_HILOGE(TIME_MODULE_SERVICE, "SetTimezone timezoneId: %{public}d: %{public}s", errNo, timezoneId.c_str());
77         return false;
78     }
79 
80     if (!SetTimezoneToKernel(timezoneId)) {
81         TIME_HILOGE(TIME_MODULE_SERVICE, "SetTimezone Set kernel failed.");
82         return false;
83     }
84     curTimezoneId_ = timezoneId;
85     return true;
86 }
87 
GetTimezone(std::string & timezoneId)88 bool TimeZoneInfo::GetTimezone(std::string &timezoneId)
89 {
90     timezoneId = curTimezoneId_;
91     return true;
92 }
93 
SetTimezoneToKernel(std::string timezoneId)94 bool TimeZoneInfo::SetTimezoneToKernel(std::string timezoneId)
95 {
96     auto itEntry = timezoneInfoMap_.find(timezoneId);
97     if (itEntry != timezoneInfoMap_.end()) {
98         auto offset = itEntry->second.utcOffsetHours;
99         struct timezone tz;
100         tz.tz_minuteswest = offset * HOUR_TO_MILLI;
101         tz.tz_dsttime = 0;
102 
103         int result = settimeofday(NULL, &tz);
104         if (result < 0) {
105             TIME_HILOGI(TIME_MODULE_SERVICE, "Settimeofday timezone fail: %{public}d.", result);
106             return false;
107         } else {
108             TIME_HILOGI(TIME_MODULE_SERVICE, "Timezone offset: %{public}d", offset);
109             return true;
110         }
111     }
112     return false;
113 }
114 }
115 }