1 /*
2 * Copyright (c) 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 "common_components/base/time_utils.h"
17
18 #include <array>
19 #include <chrono>
20 #include <ctime>
21 #include <iomanip>
22 #include <thread>
23
24 #include "securec.h"
25
26 namespace common {
27 namespace TimeUtil {
28 using Sec = std::chrono::seconds;
29 using Ms = std::chrono::milliseconds;
30 using Us = std::chrono::microseconds;
31 using Ns = std::chrono::nanoseconds;
32
33 template<typename Unit>
ClockTime(clockid_t clock)34 uint64_t ClockTime(clockid_t clock)
35 {
36 struct timespec time = { 0, 0 };
37 clock_gettime(clock, &time);
38 auto duration = Sec{ time.tv_sec } + Ns{ time.tv_nsec };
39 return std::chrono::duration_cast<Unit>(duration).count();
40 }
41
NanoSeconds()42 uint64_t NanoSeconds() { return ClockTime<Ns>(CLOCK_MONOTONIC); }
43
MilliSeconds()44 uint64_t MilliSeconds() { return ClockTime<Ms>(CLOCK_MONOTONIC); }
45
MicroSeconds()46 uint64_t MicroSeconds() noexcept { return ClockTime<Us>(CLOCK_MONOTONIC); }
47
SleepForNano(uint64_t ns)48 void SleepForNano(uint64_t ns) { std::this_thread::sleep_for(std::chrono::nanoseconds(ns)); }
49
50 #ifndef NDEBUG
51 // format: yyyy-mm-dd hh:mm::ss
GetDate(const char * format)52 static inline CString GetDate(const char* format)
53 {
54 std::time_t time = std::time(nullptr);
55 std::tm* now = std::localtime(&time);
56 if (UNLIKELY_CC(now == nullptr)) {
57 return CString();
58 }
59
60 std::array<char, 100> buffer; // the array length is 100
61 if (std::strftime(buffer.data(), buffer.size(), format, now)) {
62 return CString(buffer.data());
63 }
64 return CString();
65 }
66
67 // yyymmdd.hhmmss format
GetDigitDate()68 CString GetDigitDate()
69 {
70 CString date = GetDate("%Y%m%d_%H%M%S");
71 return !date.IsEmpty() ? date : "19700101.000000";
72 }
73 #endif
74
GetTimestamp()75 CString GetTimestamp()
76 {
77 // yyyy-mm-dd hh:mm::ss.ms format
78 std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
79 std::chrono::microseconds us = std::chrono::duration_cast<std::chrono::microseconds>(now.time_since_epoch());
80 constexpr size_t microSecondsPerSecond = 1000000;
81 auto rem = us.count() % microSecondsPerSecond;
82
83 time_t time = std::chrono::system_clock::to_time_t(now);
84 struct tm tm;
85 #ifdef _WIN64
86 (void)localtime_s(&tm, &time);
87 #else
88 (void)localtime_r(&time, &tm);
89 #endif
90
91 constexpr int epochYears = 1900;
92 constexpr size_t bufSize = 64;
93 char buf[bufSize];
94 (void)sprintf_s(buf, sizeof(buf), "%04d-%02d-%02d %02d:%02d:%02d.%06zu", tm.tm_year + epochYears,
95 tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, rem);
96 return CString(buf);
97 }
98 } // namespace TimeUtil
99 } // namespace common
100