• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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