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