1 //===- Support/Chrono.cpp - Utilities for Timing Manipulation ---*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "llvm/Support/Chrono.h"
10 #include "llvm/Config/llvm-config.h"
11 #include "llvm/Support/Format.h"
12 #include "llvm/Support/raw_ostream.h"
18 const char llvm::detail::unit
<std::ratio
<3600>>::value
[] = "h";
19 const char llvm::detail::unit
<std::ratio
<60>>::value
[] = "m";
20 const char llvm::detail::unit
<std::ratio
<1>>::value
[] = "s";
21 const char llvm::detail::unit
<std::milli
>::value
[] = "ms";
22 const char llvm::detail::unit
<std::micro
>::value
[] = "us";
23 const char llvm::detail::unit
<std::nano
>::value
[] = "ns";
25 static inline struct tm
getStructTM(TimePoint
<> TP
) {
27 std::time_t OurTime
= toTimeT(TP
);
29 #if defined(LLVM_ON_UNIX)
30 struct tm
*LT
= ::localtime_r(&OurTime
, &Storage
);
35 int Error
= ::localtime_s(&Storage
, &OurTime
);
43 raw_ostream
&operator<<(raw_ostream
&OS
, TimePoint
<> TP
) {
44 struct tm LT
= getStructTM(TP
);
45 char Buffer
[sizeof("YYYY-MM-DD HH:MM:SS")];
46 strftime(Buffer
, sizeof(Buffer
), "%Y-%m-%d %H:%M:%S", <
);
47 return OS
<< Buffer
<< '.'
49 long((TP
.time_since_epoch() % std::chrono::seconds(1))
53 void format_provider
<TimePoint
<>>::format(const TimePoint
<> &T
, raw_ostream
&OS
,
55 using namespace std::chrono
;
56 TimePoint
<seconds
> Truncated
= time_point_cast
<seconds
>(T
);
57 auto Fractional
= T
- Truncated
;
58 struct tm LT
= getStructTM(Truncated
);
59 // Handle extensions first. strftime mangles unknown %x on some platforms.
60 if (Style
.empty()) Style
= "%Y-%m-%d %H:%M:%S.%N";
62 raw_string_ostream
FStream(Format
);
63 for (unsigned I
= 0; I
< Style
.size(); ++I
) {
64 if (Style
[I
] == '%' && Style
.size() > I
+ 1) switch (Style
[I
+ 1]) {
65 case 'L': // Milliseconds, from Ruby.
66 FStream
<< llvm::format(
67 "%.3lu", (long)duration_cast
<milliseconds
>(Fractional
).count());
70 case 'f': // Microseconds, from Python.
71 FStream
<< llvm::format(
72 "%.6lu", (long)duration_cast
<microseconds
>(Fractional
).count());
75 case 'N': // Nanoseconds, from date(1).
76 FStream
<< llvm::format(
77 "%.6lu", (long)duration_cast
<nanoseconds
>(Fractional
).count());
80 case '%': // Consume %%, so %%f parses as (%%)f not %(%f)
88 char Buffer
[256]; // Should be enough for anywhen.
89 size_t Len
= strftime(Buffer
, sizeof(Buffer
), Format
.c_str(), <
);
90 OS
<< (Len
? Buffer
: "BAD-DATE-FORMAT");