1020a203aSopenharmony_ci/*
2020a203aSopenharmony_ci * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3020a203aSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4020a203aSopenharmony_ci * you may not use this file except in compliance with the License.
5020a203aSopenharmony_ci * You may obtain a copy of the License at
6020a203aSopenharmony_ci *
7020a203aSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8020a203aSopenharmony_ci *
9020a203aSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10020a203aSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11020a203aSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12020a203aSopenharmony_ci * See the License for the specific language governing permissions and
13020a203aSopenharmony_ci * limitations under the License.
14020a203aSopenharmony_ci */
15020a203aSopenharmony_ci
16020a203aSopenharmony_ci#include "time_util.h"
17020a203aSopenharmony_ci
18020a203aSopenharmony_ci#include <chrono>
19020a203aSopenharmony_ci#include <iomanip>
20020a203aSopenharmony_ci#include <sstream>
21020a203aSopenharmony_ci#include <sys/time.h>
22020a203aSopenharmony_ci#include <unistd.h>
23020a203aSopenharmony_ci
24020a203aSopenharmony_cinamespace OHOS {
25020a203aSopenharmony_cinamespace HiviewDFX {
26020a203aSopenharmony_cinamespace TimeUtil {
27020a203aSopenharmony_cinamespace {
28020a203aSopenharmony_ciconstexpr int8_t MILLISECONDS_LENGTH = 3;
29020a203aSopenharmony_ci}
30020a203aSopenharmony_citime_t StrToTimeStamp(const std::string& tmStr, const std::string& format)
31020a203aSopenharmony_ci{
32020a203aSopenharmony_ci    std::string stTime = tmStr;
33020a203aSopenharmony_ci    struct tm tmFormat { 0 };
34020a203aSopenharmony_ci    strptime(stTime.c_str(), format.c_str(), &tmFormat);
35020a203aSopenharmony_ci    tmFormat.tm_isdst = -1;
36020a203aSopenharmony_ci    return mktime(&tmFormat);
37020a203aSopenharmony_ci}
38020a203aSopenharmony_ci
39020a203aSopenharmony_ciuint64_t GenerateTimestamp()
40020a203aSopenharmony_ci{
41020a203aSopenharmony_ci    struct timeval now;
42020a203aSopenharmony_ci    if (gettimeofday(&now, nullptr) == -1) {
43020a203aSopenharmony_ci        return 0;
44020a203aSopenharmony_ci    }
45020a203aSopenharmony_ci    return (now.tv_sec * SEC_TO_MICROSEC + now.tv_usec);
46020a203aSopenharmony_ci}
47020a203aSopenharmony_ci
48020a203aSopenharmony_civoid Sleep(unsigned int seconds)
49020a203aSopenharmony_ci{
50020a203aSopenharmony_ci    sleep(seconds);
51020a203aSopenharmony_ci}
52020a203aSopenharmony_ci
53020a203aSopenharmony_ciint64_t GetSeconds()
54020a203aSopenharmony_ci{
55020a203aSopenharmony_ci    auto now = std::chrono::system_clock::now();
56020a203aSopenharmony_ci    auto secs = std::chrono::duration_cast<std::chrono::seconds>(now.time_since_epoch());
57020a203aSopenharmony_ci    return secs.count();
58020a203aSopenharmony_ci}
59020a203aSopenharmony_ci
60020a203aSopenharmony_ciuint64_t GetMilliseconds()
61020a203aSopenharmony_ci{
62020a203aSopenharmony_ci    auto now = std::chrono::system_clock::now();
63020a203aSopenharmony_ci    auto millisecs = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch());
64020a203aSopenharmony_ci    return millisecs.count();
65020a203aSopenharmony_ci}
66020a203aSopenharmony_ci
67020a203aSopenharmony_cistd::string TimestampFormatToDate(time_t timeStamp, const std::string& format)
68020a203aSopenharmony_ci{
69020a203aSopenharmony_ci    char date[MAX_TIME_BUFF] = {0};
70020a203aSopenharmony_ci    struct tm result {};
71020a203aSopenharmony_ci    if (localtime_r(&timeStamp, &result) != nullptr) {
72020a203aSopenharmony_ci        strftime(date, MAX_TIME_BUFF, format.c_str(), &result);
73020a203aSopenharmony_ci    }
74020a203aSopenharmony_ci    return std::string(date);
75020a203aSopenharmony_ci}
76020a203aSopenharmony_ci
77020a203aSopenharmony_cistd::string GetTimeZone()
78020a203aSopenharmony_ci{
79020a203aSopenharmony_ci    struct timeval currentTime;
80020a203aSopenharmony_ci    if (gettimeofday(&currentTime, nullptr) != 0) {
81020a203aSopenharmony_ci        return "";
82020a203aSopenharmony_ci    }
83020a203aSopenharmony_ci    time_t systemSeconds = currentTime.tv_sec;
84020a203aSopenharmony_ci    struct tm tmLocal;
85020a203aSopenharmony_ci    if (localtime_r(&systemSeconds, &tmLocal) == nullptr) {
86020a203aSopenharmony_ci        return "";
87020a203aSopenharmony_ci    }
88020a203aSopenharmony_ci    int tzBufSize = 20;
89020a203aSopenharmony_ci    char tz[tzBufSize];
90020a203aSopenharmony_ci    auto ret = strftime(tz, tzBufSize, "%z", &tmLocal);
91020a203aSopenharmony_ci    if (ret > 0) {
92020a203aSopenharmony_ci        return std::string(tz);
93020a203aSopenharmony_ci    }
94020a203aSopenharmony_ci    return std::string("+0000");
95020a203aSopenharmony_ci}
96020a203aSopenharmony_ci
97020a203aSopenharmony_ciint64_t Get0ClockStampMs()
98020a203aSopenharmony_ci{
99020a203aSopenharmony_ci    time_t now = std::time(nullptr);
100020a203aSopenharmony_ci    int64_t zero = now;
101020a203aSopenharmony_ci    struct tm *l = std::localtime(&now);
102020a203aSopenharmony_ci    if (l != nullptr) {
103020a203aSopenharmony_ci        l->tm_hour = 0;
104020a203aSopenharmony_ci        l->tm_min = 0;
105020a203aSopenharmony_ci        l->tm_sec = 0;
106020a203aSopenharmony_ci        zero = std::mktime(l) * SEC_TO_MILLISEC;  // time is 00:00:00
107020a203aSopenharmony_ci    }
108020a203aSopenharmony_ci    return zero > 0 ? zero : 0; // result of mktime is negative, when the date is 19700101
109020a203aSopenharmony_ci}
110020a203aSopenharmony_ci
111020a203aSopenharmony_ciuint64_t GetSteadyClockTimeMs()
112020a203aSopenharmony_ci{
113020a203aSopenharmony_ci    auto now = std::chrono::steady_clock::now();
114020a203aSopenharmony_ci    auto millisecs = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch());
115020a203aSopenharmony_ci    return millisecs.count();
116020a203aSopenharmony_ci}
117020a203aSopenharmony_ci
118020a203aSopenharmony_ciTimeCalculator::TimeCalculator(std::shared_ptr<uint64_t>& timePtr)
119020a203aSopenharmony_ci{
120020a203aSopenharmony_ci    this->time_ = timePtr;
121020a203aSopenharmony_ci    this->startTime_ = GenerateTimestamp();
122020a203aSopenharmony_ci    this->endTime_ = 0;
123020a203aSopenharmony_ci}
124020a203aSopenharmony_ci
125020a203aSopenharmony_ciTimeCalculator::~TimeCalculator()
126020a203aSopenharmony_ci{
127020a203aSopenharmony_ci    this->endTime_ = GenerateTimestamp();
128020a203aSopenharmony_ci    if (this->time_ != nullptr && this->endTime_ > this->startTime_) {
129020a203aSopenharmony_ci        *(this->time_) += this->endTime_ - this->startTime_;
130020a203aSopenharmony_ci    }
131020a203aSopenharmony_ci}
132020a203aSopenharmony_ci
133020a203aSopenharmony_cistd::string FormatTime(const int64_t timestamp, const std::string &format)
134020a203aSopenharmony_ci{
135020a203aSopenharmony_ci    std::time_t tt = static_cast<std::time_t>(timestamp / SEC_TO_MILLISEC);
136020a203aSopenharmony_ci    std::tm t = *std::localtime(&tt);
137020a203aSopenharmony_ci    char buffer[MAX_BUFFER_SIZE] = {0};
138020a203aSopenharmony_ci    std::strftime(buffer, sizeof(buffer), format.c_str(), &t);
139020a203aSopenharmony_ci    return std::string(buffer);
140020a203aSopenharmony_ci}
141020a203aSopenharmony_ci
142020a203aSopenharmony_ciuint64_t GetNanoTime()
143020a203aSopenharmony_ci{
144020a203aSopenharmony_ci    auto nanoNow = std::chrono::steady_clock::now().time_since_epoch();
145020a203aSopenharmony_ci    return nanoNow.count();
146020a203aSopenharmony_ci}
147020a203aSopenharmony_ci
148020a203aSopenharmony_ciuint64_t GetBootTimeMs()
149020a203aSopenharmony_ci{
150020a203aSopenharmony_ci    struct timespec ts;
151020a203aSopenharmony_ci    if (clock_gettime(CLOCK_BOOTTIME, &ts) == 0) {
152020a203aSopenharmony_ci        return static_cast<uint64_t>(ts.tv_sec * SEC_TO_MILLISEC + ts.tv_nsec / MILLISEC_TO_NANOSEC);
153020a203aSopenharmony_ci    }
154020a203aSopenharmony_ci    return 0;
155020a203aSopenharmony_ci}
156020a203aSopenharmony_ci
157020a203aSopenharmony_cistd::string GetFormattedTimestampEndWithMilli()
158020a203aSopenharmony_ci{
159020a203aSopenharmony_ci    auto milliSeconds = GetMilliseconds();
160020a203aSopenharmony_ci    auto seconds = milliSeconds / SEC_TO_MILLISEC;
161020a203aSopenharmony_ci    std::string formattedTimeStamp = TimestampFormatToDate(seconds, "%Y%m%d%H%M%S");
162020a203aSopenharmony_ci    std::stringstream ss;
163020a203aSopenharmony_ci    ss << formattedTimeStamp;
164020a203aSopenharmony_ci    milliSeconds = milliSeconds % SEC_TO_MILLISEC;
165020a203aSopenharmony_ci    ss << std::setfill('0') << std::setw(MILLISECONDS_LENGTH) << milliSeconds;
166020a203aSopenharmony_ci    return ss.str();
167020a203aSopenharmony_ci}
168020a203aSopenharmony_ci} // namespace TimeUtil
169020a203aSopenharmony_ci} // namespace HiviewDFX
170020a203aSopenharmony_ci} // namespace OHOS
171