1/*
2 * Copyright (c) 2023 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 "time_util.h"
16#include <string>
17#include <stdexcept>
18#include <sstream>
19#include <ctime>
20#include <sys/time.h>
21#include <chrono>
22#include "intell_voice_log.h"
23
24#define LOG_TAG "TimeUtil"
25
26using namespace std;
27static const int INVALID_TIME_T = -1;
28
29namespace OHOS {
30namespace IntellVoiceUtils {
31AutoTimer::AutoTimer()
32{
33    Reset();
34}
35
36AutoTimer::AutoTimer(const std::string &logInfo) : logInfo_(logInfo)
37{
38    Reset();
39}
40
41AutoTimer::~AutoTimer()
42{
43    if (isReset_) {
44        PrintTimeElapse();
45    }
46}
47
48void AutoTimer::PrintTimeElapse()
49{
50    PrintTimeElapse(logInfo_);
51}
52
53void AutoTimer::PrintTimeElapse(const std::string &logInfo)
54{
55    std::string log;
56
57    try {
58        if (!logInfo.empty()) {
59            log += logInfo + " ";
60        } else {
61            log += logInfo_ + " ";
62        }
63
64        std::ostringstream ss;
65        ss << TimeElapseMs();
66        log += "time elapse: " + ss.str() + "ms";
67    } catch (const std::length_error& err) {
68        INTELL_VOICE_LOG_ERROR("length error");
69        return;
70    }
71
72    INTELL_VOICE_LOG_DEBUG("%{public}s", log.c_str());
73
74    isReset_ = false;
75}
76
77void AutoTimer::Reset()
78{
79    TimeUtil::GetTime(timeStart_);
80    isReset_ = true;
81}
82
83long AutoTimer::TimeElapseUs()
84{
85    isReset_ = false;
86
87    timespec timeEnd;
88    TimeUtil::GetTime(timeEnd);
89
90    return TimeUtil::TimeElapseUs(timeStart_, timeEnd);
91}
92
93uint32_t AutoTimer::TimeElapseMs()
94{
95    return TimeElapseUs() / MS_PER_US;
96}
97
98uint32_t AutoTimer::TimeElapseS()
99{
100    return TimeElapseUs() / (S_PER_MS * MS_PER_US);
101}
102
103string TimeUtil::GetCurrTime(TimeFormat format)
104{
105    time_t rawTime;
106    struct tm *timeInfo = nullptr;
107    char buffer[100] = { 0 };
108
109    time(&rawTime);
110    timeInfo = localtime(&rawTime);
111    if (timeInfo != nullptr) {
112        if (format == TIME_FORMAT_DEFAULT) {
113            strftime(buffer, sizeof(buffer), "%Y_%m_%d_%H_%M_%S_", timeInfo);
114        } else if (format == TIME_FORMAT_CONTINOUS) {
115            strftime(buffer, sizeof(buffer), "%Y%m%d%H%M%S", timeInfo);
116        } else if (format == TIME_FORMAT_STANDARD) {
117            strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", timeInfo);
118        } else {
119            INTELL_VOICE_LOG_WARN("invalid format:%{public}d", format);
120        }
121    }
122    std::string str(buffer);
123
124    return str;
125}
126
127string TimeUtil::GetCurrTimeUs()
128{
129    struct timeval tv;
130    char buffer[100] = {0};
131    if (gettimeofday(&tv, nullptr) == -1) {
132        INTELL_VOICE_LOG_ERROR("get time of day error");
133        return "";
134    }
135    struct tm *timeInfo = localtime(&tv.tv_sec);
136    if (timeInfo != nullptr) {
137        strftime(buffer, sizeof(buffer), "%Y%m%d%H%M%S", timeInfo);
138    }
139    string str(buffer);
140    stringstream ss;
141    ss << tv.tv_usec;
142    str += ss.str();
143    return str;
144}
145
146time_t TimeUtil::GetFormatTimeToSec(const string &formatTime)
147{
148    INTELL_VOICE_LOG_DEBUG("GetFormatTimeToSec, formatTime is %{public}s", formatTime.c_str());
149    struct tm s_tm;
150
151    if (!strptime(formatTime.c_str(), "%Y%m%d%H%M%S", &s_tm)) {
152        INTELL_VOICE_LOG_ERROR("get file create time error");
153        return INVALID_TIME_T;
154    }
155
156    return mktime(&s_tm);
157}
158
159bool TimeUtil::IsFormatTimeExpired(const string &formatTime, int maxKeepTime)
160{
161    time_t currentTime;
162    time_t originalTime;
163
164    currentTime = time(nullptr);
165    originalTime = GetFormatTimeToSec(formatTime);
166    if ((originalTime == INVALID_TIME_T) || (currentTime == INVALID_TIME_T)) {
167        INTELL_VOICE_LOG_ERROR("get sys time error");
168        return false;
169    }
170
171    return (currentTime >= originalTime) && (currentTime - originalTime >= maxKeepTime);
172}
173
174uint64_t TimeUtil::GetCurrentTimeMs()
175{
176    return static_cast<uint64_t>(std::chrono::duration_cast<std::chrono::milliseconds>(
177        std::chrono::system_clock::now().time_since_epoch()).count());
178}
179}
180}
181