• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 #include "zone_rules.h"
16 
17 #include "i18n_hilog.h"
18 #include "unicode/tzrule.h"
19 #include "unicode/tztrans.h"
20 #include "unicode/gregocal.h"
21 
22 namespace OHOS {
23 namespace Global {
24 namespace I18n {
ZoneRules(const std::string & tzid)25 ZoneRules::ZoneRules(const std::string &tzid)
26 {
27     this->tzId = tzid;
28     InitBasicTimeZone();
29 }
30 
~ZoneRules()31 ZoneRules::~ZoneRules()
32 {
33 }
34 
InitBasicTimeZone()35 void ZoneRules::InitBasicTimeZone()
36 {
37     if (tzId.empty()) {
38         HILOG_ERROR_I18N("ZoneRules::InitBasicTimeZone: param tzid is empty.");
39         return;
40     }
41     icu::UnicodeString unicodeZoneId(tzId.data(), tzId.length());
42     icu::TimeZone* icuTz = icu::TimeZone::createTimeZone(unicodeZoneId);
43     if (icuTz == nullptr) {
44         HILOG_ERROR_I18N("ZoneRules::InitBasicTimeZone: param tzid: %{public}s invalid.", tzId.c_str());
45         return;
46     }
47     icu::BasicTimeZone* btzPtr = static_cast<icu::BasicTimeZone*>(icuTz);
48     if (btzPtr == nullptr) {
49         HILOG_ERROR_I18N("ZoneRules::InitBasicTimeZone: static_cast icu::TimeZone failed.");
50         return;
51     }
52     this->btz = std::unique_ptr<icu::BasicTimeZone>(btzPtr);
53     if (btz == nullptr) {
54         HILOG_ERROR_I18N("ZoneRules::InitBasicTimeZone: btz is nullptr.");
55     }
56 }
57 
NextTransition()58 std::unique_ptr<ZoneOffsetTransition> ZoneRules::NextTransition()
59 {
60     auto time = std::chrono::system_clock::now();
61     auto since_epoch = time.time_since_epoch();
62     auto millis = std::chrono::duration_cast<std::chrono::milliseconds>(since_epoch);
63     UDate currentTime = static_cast<double>(millis.count());
64     return NextTransition(currentTime);
65 }
66 
NextTransition(double date)67 std::unique_ptr<ZoneOffsetTransition> ZoneRules::NextTransition(double date)
68 {
69     if (btz == nullptr) {
70         HILOG_ERROR_I18N("ZoneRules::NextTransition: btz is nullptr.");
71         return std::make_unique<ZoneOffsetTransition>();
72     }
73     icu::TimeZoneTransition trans;
74     if (!btz->getNextTransition(date, false, trans)) {
75         HILOG_ERROR_I18N("ZoneRules::nextTransition: get next transition after %{public}s failed.",
76             std::to_string(date).c_str());
77         return std::make_unique<ZoneOffsetTransition>();
78     }
79     const icu::TimeZoneRule* from = trans.getFrom();
80     const icu::TimeZoneRule* to = trans.getTo();
81     if (from == nullptr || to == nullptr) {
82         return std::make_unique<ZoneOffsetTransition>();
83     }
84     double time = trans.getTime();
85     int32_t offsetBefore = from->getRawOffset() + from->getDSTSavings();
86     int32_t offsetAfter = to->getRawOffset() + to->getDSTSavings();
87     return std::make_unique<ZoneOffsetTransition>(time, offsetBefore, offsetAfter);
88 }
89 } // namespace I18n
90 } // namespace Global
91 } // namespace OHOS
92