• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 "holiday_manager.h"
16 #include "hilog/log.h"
17 #include <algorithm>
18 #include <climits>
19 #include <ctime>
20 #include <filesystem>
21 #include <format>
22 #include <fstream>
23 #include <iostream>
24 #include <regex>
25 #include "map"
26 
27 namespace OHOS {
28 namespace Global {
29 namespace I18n {
30 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, 0xD001E00, "HolidayManager" };
31 using namespace OHOS::HiviewDFX;
32 
33 const char* HolidayManager::ITEM_BEGIN_TAG = "BEGIN:VEVENT";
34 const char* HolidayManager::ITEM_END_TAG = "END:VEVENT";
35 const char* HolidayManager::ITEM_DTSTART_TAG = "DTSTART";
36 const char* HolidayManager::ITEM_DTEND_TAG = "DTEND";
37 const char* HolidayManager::ITEM_SUMMARY_TAG = "SUMMARY";
38 const char* HolidayManager::ITEM_RESOURCES_TAG = "RESOURCES";
39 
HolidayManager(const char * path)40 HolidayManager::HolidayManager(const char* path)
41 {
42     if (path == nullptr) {
43         HiLog::Error(LABEL, "Failed: parameter path is NULL.");
44         return;
45     }
46     std::string msg = ValidateHolidayFilePath(path);
47     if (msg.length() != 0) {
48         HiLog::Error(LABEL, "Failed: %{public}s .", msg.c_str());
49         return;
50     }
51     std::vector<HolidayInfoItem> items = ReadHolidayFile(path);
52     for (size_t i = 0; i < items.size(); i++) {
53         struct tm tmObj = {.tm_mday = items[i].day, .tm_mon = items[i].month, .tm_year = items[i].year};
54         char strDate[10];
55         size_t resCode = strftime(strDate, sizeof(strDate), "%Y%m%d", &tmObj);
56         if (resCode == 0) {
57             HiLog::Error(LABEL, "Failed: strftime error:%{public}d .", resCode);
58             return;
59         }
60         std::string startDate(strDate);
61         items[i].year += YEAR_START;
62         items[i].month += MONTH_GREATER_ONE;
63         if (holidayItemMap.find(startDate) != holidayItemMap.end()) {
64             std::vector<HolidayInfoItem> *vetor = &(holidayItemMap.find(startDate)->second);
65             vetor->push_back(items[i]);
66         } else {
67             std::vector<HolidayInfoItem> vetor;
68             vetor.push_back(items[i]);
69             holidayItemMap.insert(std::pair<std::string, std::vector<HolidayInfoItem>>(startDate, vetor));
70         }
71     }
72 }
73 
~HolidayManager()74 HolidayManager::~HolidayManager()
75 {
76 }
77 
SetHolidayData(std::map<std::string,std::vector<HolidayInfoItem>> holidayDataMap)78 void HolidayManager::SetHolidayData(std::map<std::string, std::vector<HolidayInfoItem>> holidayDataMap)
79 {
80     holidayItemMap = holidayDataMap;
81 }
82 
IsHoliday()83 bool HolidayManager::IsHoliday()
84 {
85     time_t timeStamp = time(NULL);
86     struct tm timObj = *localtime(&timeStamp);
87     int32_t year = timObj.tm_year + YEAR_START;
88     int32_t month = timObj.tm_mon + MONTH_GREATER_ONE;
89     return IsHoliday(year, month, timObj.tm_mday);
90 }
91 
IsHoliday(int32_t year,int32_t month,int32_t day)92 bool HolidayManager::IsHoliday(int32_t year, int32_t month, int32_t day)
93 {
94     std::string startDate = Format(year, month, day);
95     if (holidayItemMap.find(startDate) != holidayItemMap.end()) {
96         std::vector<HolidayInfoItem> list = holidayItemMap.find(startDate)->second;
97         return list.size() > 0;
98     }
99     return false;
100 }
101 
Format(int32_t year,int32_t month,int32_t day)102 std::string HolidayManager::Format(int32_t year, int32_t month, int32_t day)
103 {
104     std::string formated;
105     formated += std::to_string(year);
106     // Numbers less than 10 are one digit
107     formated += month < 10 ? ("0" + std::to_string(month)) : std::to_string(month);
108     // Numbers less than 10 are one digit
109     formated += day < 10 ? ("0" + std::to_string(day)) : std::to_string(day);
110     return formated;
111 }
112 
GetHolidayInfoItemArray()113 std::vector<HolidayInfoItem> HolidayManager::GetHolidayInfoItemArray()
114 {
115     time_t timeStamp = time(NULL);
116     struct tm timObj = *localtime(&timeStamp);
117     int32_t realYear = timObj.tm_year + YEAR_START;
118     return GetHolidayInfoItemArray(realYear);
119 }
120 
GetHolidayInfoItemArray(int32_t year)121 std::vector<HolidayInfoItem> HolidayManager::GetHolidayInfoItemArray(int32_t year)
122 {
123     std::vector<HolidayInfoItem> vetor;
124     std::string formatedYear = std::to_string(year);
125     std::map<std::string, std::vector<HolidayInfoItem>>::iterator iter;
126     for (iter = holidayItemMap.begin(); iter != holidayItemMap.end(); ++iter) {
127         std::string key = iter->first;
128         if (formatedYear == key.substr(0, 4)) { // 4 is the length of full year
129             std::vector<HolidayInfoItem> temp = iter->second;
130             for (size_t i = 0; i < temp.size(); i++) {
131                 vetor.push_back(temp[i]);
132             }
133         }
134     }
135     return vetor;
136 }
137 
ValidateHolidayFilePath(const char * path)138 std::string HolidayManager::ValidateHolidayFilePath(const char* path)
139 {
140     char *realpathRes = realpath(path, nullptr);
141     if (realpathRes == NULL) {
142         free(realpathRes);
143         return "the holiday resource file not exists.";
144     }
145     std::ifstream file(path);
146     if (!file.good()) {
147         file.close();
148         return "the holiday resource file can't read.";
149     }
150     file.close();
151     free(realpathRes);
152     realpathRes = NULL;
153     return "";
154 }
155 
ReadHolidayFile(const char * path)156 std::vector<HolidayInfoItem> HolidayManager::ReadHolidayFile(const char* path)
157 {
158     std::vector<HolidayInfoItem> items;
159     if (path == nullptr) {
160         return items;
161     }
162     std::ifstream fin;
163     fin.open(path, std::ios::in);
164     std::string line;
165     while (getline(fin, line)) {
166         line = Trim(line);
167         if (line.compare(ITEM_BEGIN_TAG) != 0) {
168             continue;
169         }
170         struct HolidayInfoItem holidayItem;
171         while (getline(fin, line)) {
172             line = Trim(line);
173             ParseFileLine(line, &(holidayItem));
174             if (line.compare(ITEM_END_TAG) == 0) {
175                 items.push_back(holidayItem);
176                 break;
177             }
178         }
179     }
180     fin.close();
181     return items;
182 }
183 
ParseFileLine(const std::string & line,HolidayInfoItem * holidayItem)184 void HolidayManager::ParseFileLine(const std::string &line, HolidayInfoItem *holidayItem)
185 {
186     if (holidayItem == nullptr) {
187         return;
188     }
189     std::regex reg("([A-Z]+)[:;](.+)");
190     std::smatch match;
191     bool found = std::regex_search(line, match, reg);
192     if (found) {
193         std::string tag = match[1].str();
194         std::string value = line.substr(line.find_last_of(":") + 1, line.length());
195         if (tag.compare(ITEM_DTSTART_TAG) == 0) {
196             std::string startDate = value.size() >= 8 ? value.substr(0, 8) : ""; // 8 is date formarted string length
197             if (startDate.size() == 8) {
198                 struct tm timeObj;
199                 strptime(startDate.c_str(), "%Y%m%d", &timeObj);
200                 holidayItem->year = timeObj.tm_year;
201                 holidayItem->month = timeObj.tm_mon;
202                 holidayItem->day = timeObj.tm_mday;
203             }
204         } else if (tag.compare(ITEM_SUMMARY_TAG) == 0) {
205             holidayItem->baseName = value;
206         } else if (tag.compare(ITEM_RESOURCES_TAG) == 0) {
207             std::string displayName = line.substr(line.find_last_of("=") + 1, line.length());
208             std::string language = displayName.substr(0, displayName.find_first_of(":"));
209             std::string localName = displayName.substr(displayName.find_first_of(":") + 1, displayName.length());
210             transform(language.begin(), language.end(), language.begin(), ::tolower);
211             HolidayLocalName localeName = {language, localName};
212             holidayItem->localNames.push_back(localeName);
213         }
214     }
215 }
216 
Trim(std::string & str)217 std::string& HolidayManager::Trim(std::string &str)
218 {
219     if (str.empty()) {
220         return str;
221     }
222     str.erase(0, str.find_first_not_of(" \t"));
223     str.erase(str.find_last_not_of("\r\n\t") + 1);
224     return str;
225 }
226 } // namespace I18n
227 } // namespace Global
228 } // namespace OHOS
229