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 "date_time_format.h"
17 #include "data_resource.h"
18 #include "date_time_format_impl.h"
19 #include "number_format_impl.h"
20 
21 using namespace OHOS::I18N;
22 using namespace std;
23 
24 /**
25  * construct a DateTimeFormat object with request pattern and locale.
26  * now we only support patterns defined in AvailableDateTimeFormatPatterns.
27  * locale, locale information to retrieve datetime resource form icu data.
28  */
DateTimeFormat(AvailableDateTimeFormatPattern requestPattern,const LocaleInfo & locale)29 DateTimeFormat::DateTimeFormat(AvailableDateTimeFormatPattern requestPattern, const LocaleInfo &locale)
30 {
31     this->locale = locale;
32     this->requestPattern = requestPattern;
33 }
34 
~DateTimeFormat()35 DateTimeFormat::~DateTimeFormat()
36 {
37     if (impl != nullptr) {
38         delete impl;
39         impl = nullptr;
40     }
41 }
42 
Init()43 bool DateTimeFormat::Init()
44 {
45     if (impl != nullptr) {
46         delete impl;
47         impl = nullptr;
48     }
49     impl = new(nothrow) DateTimeFormatImpl(requestPattern, locale);
50     if (impl == nullptr) {
51         return false;
52     }
53     DataResource resource(&locale);
54     bool isSuccess = resource.Init();
55     if (!isSuccess) {
56         return false;
57     }
58     isSuccess = impl->Init(resource);
59     if (!isSuccess) {
60         return false;
61     }
62     int status = I18nStatus::ISUCCESS;
63     NumberFormatImpl *numberFormatter = new(nothrow) NumberFormatImpl(locale, status);
64     if (numberFormatter == nullptr) {
65         delete impl;
66         impl = nullptr;
67         return false;
68     }
69     if (status != I18nStatus::ISUCCESS) {
70         delete numberFormatter;
71         numberFormatter = nullptr;
72         delete impl;
73         impl = nullptr;
74         return false;
75     }
76     isSuccess = numberFormatter->Init(resource);
77     if (!isSuccess) {
78         delete numberFormatter;
79         numberFormatter = nullptr;
80         delete impl;
81         impl = nullptr;
82         return false;
83     }
84     impl->SetNumberFormatter(numberFormatter);
85     return true;
86 }
87 
88 /**
89  * parse a time (represent by the seconds elapsed from UTC 1970, January 1 00:00:00) to its text format.
90  * cal, seconds from from UTC 1970, January 1 00:00:00
91  * zoneInfoOffest, string representation of offset such as "+01:45"
92  * appendTo, output of this method.
93  */
Format(const time_t & cal,const string & zoneInfo,string & appendTo,I18nStatus & status)94 void DateTimeFormat::Format(const time_t &cal, const string &zoneInfo, string &appendTo, I18nStatus &status)
95 {
96     if (impl == nullptr) {
97         bool isSuccess = Init();
98         if (!isSuccess) {
99             status = IERROR;
100             return;
101         }
102     }
103     impl->Format(cal, zoneInfo, appendTo, status);
104 }
105 
ApplyPattern(const AvailableDateTimeFormatPattern & requestPattern)106 void DateTimeFormat::ApplyPattern(const AvailableDateTimeFormatPattern &requestPattern)
107 {
108     if (this->requestPattern == requestPattern) {
109         return;
110     }
111     this->requestPattern = requestPattern;
112     if (this->impl != nullptr) {
113         this->impl->ApplyPattern(requestPattern);
114     } else {
115         Init();
116     }
117 }
118 
GetWeekName(const int32_t & index,DateTimeDataType type)119 std::string DateTimeFormat::GetWeekName(const int32_t &index, DateTimeDataType type)
120 {
121     if (impl == nullptr) {
122         bool isSuccess = Init();
123         if (!isSuccess) {
124             return "";
125         }
126     }
127     return impl->GetWeekName(index, type);
128 }
129 
GetMonthName(const int32_t & index,DateTimeDataType type)130 std::string DateTimeFormat::GetMonthName(const int32_t &index, DateTimeDataType type)
131 {
132     if (impl == nullptr) {
133         bool isSuccess = Init();
134         if (!isSuccess) {
135             return "";
136         }
137     }
138     return impl->GetMonthName(index, type);
139 }
140 
GetAmPmMarker(const int32_t & index,DateTimeDataType type)141 std::string DateTimeFormat::GetAmPmMarker(const int32_t &index, DateTimeDataType type)
142 {
143     if (impl == nullptr) {
144         bool isSuccess = Init();
145         if (!isSuccess) {
146             return "";
147         }
148     }
149     return impl->GetAmPmMarker(index, type);
150 }
151 
Get12HourTimeWithoutAmpm(const time_t & cal,const std::string & zoneInfo,std::string & appendTo,I18nStatus & status)152 int8_t DateTimeFormat::Get12HourTimeWithoutAmpm(const time_t &cal, const std::string &zoneInfo,
153     std::string &appendTo, I18nStatus &status)
154 {
155     if (impl == nullptr) {
156         bool isSuccess = Init();
157         if (!isSuccess) {
158             status = IERROR;
159             return 0;
160         }
161     }
162     return impl->Get12HourTimeWithoutAmpm(cal, zoneInfo, appendTo, status);
163 }
164 
FormatElapsedDuration(int32_t milliseconds,ElapsedPatternType type,I18nStatus & status)165 std::string DateTimeFormat::FormatElapsedDuration(int32_t milliseconds, ElapsedPatternType type,
166     I18nStatus &status)
167 {
168     if (impl == nullptr) {
169         bool isSuccess = Init();
170         if (!isSuccess) {
171             status = IERROR;
172             return "";
173         }
174     }
175     return impl->FormatElapsedDuration(milliseconds, type, status);
176 }
177 
GetTimeSeparator()178 std::string DateTimeFormat::GetTimeSeparator()
179 {
180     if (impl == nullptr) {
181         bool isSuccess = Init();
182         if (!isSuccess) {
183             return "";
184         }
185     }
186     return impl->GetTimeSeparator();
187 }