1 /*
2 * Copyright (c) 2025-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
16 #include <chrono>
17
18 #include "net_stats_utils.h"
19 #include "net_mgr_log_wrapper.h"
20 #include "cellular_data_client.h"
21 #include "core_service_client.h"
22
23 namespace OHOS {
24 namespace NetManagerStandard {
25
26 const int32_t TM_YEAR_START = 1900;
27 static const int32_t DAYS_IN_MONTH[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
28
GetStartTimestamp(int32_t startdate)29 int32_t NetStatsUtils::GetStartTimestamp(int32_t startdate)
30 {
31 // 获取当前日期和时间
32 auto now = std::chrono::system_clock::now();
33 time_t now_time_t = std::chrono::system_clock::to_time_t(now);
34 tm* now_tm = std::localtime(&now_time_t);
35 if (now_tm == nullptr) {
36 return INT32_MAX;
37 }
38
39 // 获取当前年份和月份
40 int current_year = now_tm->tm_year + TM_YEAR_START;
41 int current_month = now_tm->tm_mon + 1; // tm_mon是0-11,所以需要加1
42 int current_day = now_tm->tm_mday;
43
44 // 计算上个月的年份和月份
45 int previous_month = current_month == 1 ? 12 : current_month - 1;
46 int previous_year = current_month == 1 ? current_year - 1 : current_year;
47
48 // 构建 tm 结构表示上个月的10号
49 tm last_month_xth_tm = {};
50 last_month_xth_tm.tm_year = previous_year - TM_YEAR_START;
51 last_month_xth_tm.tm_mon = previous_month - 1;
52 last_month_xth_tm.tm_mday = startdate;
53
54 int daysInCurrentMonth = NetStatsUtils::GetDaysInMonth(previous_year, previous_month);
55 // 如果上个月没有起始日期这一天,就从上个月的月末一天开始算
56 if (daysInCurrentMonth < startdate) {
57 last_month_xth_tm.tm_year = previous_year - TM_YEAR_START;
58 last_month_xth_tm.tm_mon = previous_month -1 ;
59 last_month_xth_tm.tm_mday = daysInCurrentMonth;
60 }
61 // 如果当前天大于起始日期,则获取本月的时间
62 if (startdate <= current_day) {
63 last_month_xth_tm.tm_year = current_year - TM_YEAR_START;
64 last_month_xth_tm.tm_mon = current_month - 1;
65 last_month_xth_tm.tm_mday = startdate;
66 }
67
68 NETMGR_LOG_I("last year: %{public}d, month: %{public}d, day: %{public}d",
69 last_month_xth_tm.tm_year + TM_YEAR_START, last_month_xth_tm.tm_mon + 1, last_month_xth_tm.tm_mday);
70
71 // 转换为 time_t
72 time_t last_month_xth_time_t = mktime(&last_month_xth_tm);
73 auto last_month_xth = std::chrono::system_clock::from_time_t(last_month_xth_time_t);
74
75 int32_t timestamp = static_cast<int32_t>(std::chrono::system_clock::to_time_t(last_month_xth));
76 NETMGR_LOG_I("timestamp: %{public}d", timestamp);
77
78 return timestamp;
79 }
80
GetTodayStartTimestamp()81 int32_t NetStatsUtils::GetTodayStartTimestamp()
82 {
83 auto now = std::chrono::system_clock::now();
84 time_t now_time_t = std::chrono::system_clock::to_time_t(now);
85 tm* now_tm = std::localtime(&now_time_t);
86 if (now_tm == nullptr) {
87 return INT32_MAX;
88 }
89
90 tm last_month_xth_tm = {};
91 last_month_xth_tm.tm_year = now_tm->tm_year;
92 last_month_xth_tm.tm_mon = now_tm->tm_mon;
93 last_month_xth_tm.tm_mday = now_tm->tm_mday;
94
95 // 转换为 time_t
96 time_t last_month_xth_time_t = mktime(&last_month_xth_tm);
97
98 // 转换为系统时钟时间
99 auto last_month_xth = std::chrono::system_clock::from_time_t(last_month_xth_time_t);
100
101 // 转换为时间戳(通常用于网络传输的秒级时间戳)
102 auto timestamp = std::chrono::system_clock::to_time_t(last_month_xth);
103
104 return timestamp;
105 }
106
GetNowTimestamp()107 int32_t NetStatsUtils::GetNowTimestamp()
108 {
109 auto now = std::chrono::system_clock::now();
110 return std::chrono::system_clock::to_time_t(now);
111 }
112
IsLeapYear(int32_t year)113 bool NetStatsUtils::IsLeapYear(int32_t year)
114 {
115 return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0); // 4: 100/400计算闰年
116 }
117
GetDaysInMonth(int32_t year,int32_t month)118 int32_t NetStatsUtils::GetDaysInMonth(int32_t year, int32_t month)
119 {
120 if (year <= 0 || month <= 0 || month > static_cast<int32_t>(sizeof(DAYS_IN_MONTH) / sizeof(int32_t))) {
121 return -1;
122 }
123
124 if (month == 2 && NetStatsUtils::IsLeapYear(year)) { // 如果是2月并且是闰年
125 return 29; // 则天数为29
126 }
127
128 // 返回对应月份的天数
129 return DAYS_IN_MONTH[month - 1];
130 }
131
IsMobileDataEnabled()132 bool NetStatsUtils::IsMobileDataEnabled()
133 {
134 bool dataEnabled = false;
135 int32_t errorCode =
136 DelayedRefSingleton<Telephony::CellularDataClient>::GetInstance().IsCellularDataEnabled(dataEnabled);
137 NETMGR_LOG_I("errorCode: %{public}d, isEnabled: %{public}d", errorCode, dataEnabled);
138 return dataEnabled;
139 }
140
IsDualCardEnabled()141 int32_t NetStatsUtils::IsDualCardEnabled()
142 {
143 int32_t actualSimNum = 0;
144 int32_t simNum = Telephony::CoreServiceClient::GetInstance().GetMaxSimCount();
145 for (int32_t i = 0; i < simNum; ++i) {
146 bool hasSimCard;
147 Telephony::CoreServiceClient::GetInstance().HasSimCard(i, hasSimCard);
148 if (hasSimCard) {
149 actualSimNum++;
150 }
151 }
152 NETMGR_LOG_I("actualSimNum == %{public}d.", actualSimNum);
153 return actualSimNum;
154 }
155
GetPrimarySlotId()156 int32_t NetStatsUtils::GetPrimarySlotId()
157 {
158 int primarySlotId = -1;
159 int ret = Telephony::CoreServiceClient::GetInstance().GetPrimarySlotId(primarySlotId);
160 if (primarySlotId == -1) {
161 NETMGR_LOG_E("GetPrimarySlotId error, ret: %{public}d", ret);
162 }
163 return primarySlotId;
164 }
165
ConvertToUint64(const std::string & str,uint64_t & value)166 bool NetStatsUtils::ConvertToUint64(const std::string &str, uint64_t &value)
167 {
168 char* end;
169 errno = 0; // 清除 errno
170 if (str.empty()) {
171 NETMGR_LOG_E("string error. str: %{public}s", str.c_str());
172 return false;
173 }
174
175 value = std::strtoull(str.c_str(), &end, 10); // 10:十进制
176
177 // 检查错误:
178 // 1. 若没有数字被转换
179 if (end == str.c_str()) {
180 NETMGR_LOG_E("string error. str: %{public}s", str.c_str());
181 return false;
182 }
183 // 2. 若存在范围错误(过大或过小)
184 if (errno == ERANGE && (value == HUGE_VAL || value == HUGE_VALF || value == HUGE_VALL)) {
185 NETMGR_LOG_E("string error. str: %{public}s", str.c_str());
186 return false;
187 }
188 // 3. 若字符串包含非数字字符
189 if (*end != '\0') {
190 NETMGR_LOG_E("string error. str: %{public}s", str.c_str());
191 return false;
192 }
193
194 return true;
195 }
196
ConvertToInt32(const std::string & str,int32_t & value)197 bool NetStatsUtils::ConvertToInt32(const std::string &str, int32_t &value)
198 {
199 char* end;
200 errno = 0; // 清除 errno
201
202 if (str.empty()) {
203 NETMGR_LOG_E("string error. str: %{public}s", str.c_str());
204 return false;
205 }
206
207 value = std::strtod(str.c_str(), &end);
208
209 // 检查错误:
210 // 1. 若没有数字被转换
211 if (end == str.c_str()) {
212 NETMGR_LOG_E("string error. str: %{public}s", str.c_str());
213 return false;
214 }
215 // 2. 若存在范围错误(过大或过小)
216 if (errno == ERANGE && (value == HUGE_VAL || value == HUGE_VALF || value == HUGE_VALL)) {
217 NETMGR_LOG_E("string error. str: %{public}s", str.c_str());
218 return false;
219 }
220 // 3. 若字符串包含非数字字符
221 if (*end != '\0') {
222 NETMGR_LOG_E("string error. str: %{public}s", str.c_str());
223 return false;
224 }
225
226 return true;
227 }
228 }
229 }
230