• 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 
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