Path: blob/main/contrib/llvm-project/llvm/lib/Support/Chrono.cpp
35233 views
//===- Support/Chrono.cpp - Utilities for Timing Manipulation ---*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "llvm/Support/Chrono.h"9#include "llvm/Config/llvm-config.h"10#include "llvm/Support/Format.h"11#include "llvm/Support/raw_ostream.h"1213namespace llvm {1415using namespace sys;1617const char llvm::detail::unit<std::ratio<3600>>::value[] = "h";18const char llvm::detail::unit<std::ratio<60>>::value[] = "m";19const char llvm::detail::unit<std::ratio<1>>::value[] = "s";20const char llvm::detail::unit<std::milli>::value[] = "ms";21const char llvm::detail::unit<std::micro>::value[] = "us";22const char llvm::detail::unit<std::nano>::value[] = "ns";2324static inline struct tm getStructTM(TimePoint<> TP) {25struct tm Storage;26std::time_t OurTime = toTimeT(TP);2728#if defined(LLVM_ON_UNIX)29struct tm *LT = ::localtime_r(&OurTime, &Storage);30assert(LT);31(void)LT;32#endif33#if defined(_WIN32)34int Error = ::localtime_s(&Storage, &OurTime);35assert(!Error);36(void)Error;37#endif3839return Storage;40}4142static inline struct tm getStructTMUtc(UtcTime<> TP) {43struct tm Storage;44std::time_t OurTime = toTimeT(TP);4546#if defined(LLVM_ON_UNIX)47struct tm *LT = ::gmtime_r(&OurTime, &Storage);48assert(LT);49(void)LT;50#endif51#if defined(_WIN32)52int Error = ::gmtime_s(&Storage, &OurTime);53assert(!Error);54(void)Error;55#endif5657return Storage;58}5960raw_ostream &operator<<(raw_ostream &OS, TimePoint<> TP) {61struct tm LT = getStructTM(TP);62char Buffer[sizeof("YYYY-MM-DD HH:MM:SS")];63strftime(Buffer, sizeof(Buffer), "%Y-%m-%d %H:%M:%S", <);64return OS << Buffer << '.'65<< format("%.9lu",66long((TP.time_since_epoch() % std::chrono::seconds(1))67.count()));68}6970template <class T>71static void format(const T &Fractional, struct tm <, raw_ostream &OS,72StringRef Style) {73using namespace std::chrono;74// Handle extensions first. strftime mangles unknown %x on some platforms.75if (Style.empty()) Style = "%Y-%m-%d %H:%M:%S.%N";76std::string Format;77raw_string_ostream FStream(Format);78for (unsigned I = 0; I < Style.size(); ++I) {79if (Style[I] == '%' && Style.size() > I + 1) switch (Style[I + 1]) {80case 'L': // Milliseconds, from Ruby.81FStream << llvm::format(82"%.3lu", (long)duration_cast<milliseconds>(Fractional).count());83++I;84continue;85case 'f': // Microseconds, from Python.86FStream << llvm::format(87"%.6lu", (long)duration_cast<microseconds>(Fractional).count());88++I;89continue;90case 'N': // Nanoseconds, from date(1).91FStream << llvm::format(92"%.9lu", (long)duration_cast<nanoseconds>(Fractional).count());93++I;94continue;95case '%': // Consume %%, so %%f parses as (%%)f not %(%f)96FStream << "%%";97++I;98continue;99}100FStream << Style[I];101}102FStream.flush();103char Buffer[256]; // Should be enough for anywhen.104size_t Len = strftime(Buffer, sizeof(Buffer), Format.c_str(), <);105OS << (Len ? Buffer : "BAD-DATE-FORMAT");106}107108void format_provider<UtcTime<std::chrono::seconds>>::format(109const UtcTime<std::chrono::seconds> &T, raw_ostream &OS, StringRef Style) {110using namespace std::chrono;111UtcTime<seconds> Truncated =112UtcTime<seconds>(duration_cast<seconds>(T.time_since_epoch()));113auto Fractional = T - Truncated;114struct tm LT = getStructTMUtc(Truncated);115llvm::format(Fractional, LT, OS, Style);116}117118void format_provider<TimePoint<>>::format(const TimePoint<> &T, raw_ostream &OS,119StringRef Style) {120using namespace std::chrono;121TimePoint<seconds> Truncated = time_point_cast<seconds>(T);122auto Fractional = T - Truncated;123struct tm LT = getStructTM(Truncated);124llvm::format(Fractional, LT, OS, Style);125}126127} // namespace llvm128129130