[llvm] 1c9035d - [SystemZ][z/OS] Add UtcClock extension to chrono.h/.cpp (#67846)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 12 12:43:00 PDT 2023
Author: Yusra Syeda
Date: 2023-10-12T15:42:56-04:00
New Revision: 1c9035d1b5a9af89fccf06fa0c45f0096b063983
URL: https://github.com/llvm/llvm-project/commit/1c9035d1b5a9af89fccf06fa0c45f0096b063983
DIFF: https://github.com/llvm/llvm-project/commit/1c9035d1b5a9af89fccf06fa0c45f0096b063983.diff
LOG: [SystemZ][z/OS] Add UtcClock extension to chrono.h/.cpp (#67846)
This PR adds handling for UtcClock to chrono.h/.cpp.
---------
Co-authored-by: Yusra Syeda <yusra.syeda at ibm.com>
Added:
llvm/unittests/Support/UTCTimeTest.cpp
Modified:
llvm/include/llvm/Support/Chrono.h
llvm/lib/Support/Chrono.cpp
llvm/unittests/Support/CMakeLists.txt
Removed:
################################################################################
diff --git a/llvm/include/llvm/Support/Chrono.h b/llvm/include/llvm/Support/Chrono.h
index 9c2bd45d2803e56..71859af7c7e4a59 100644
--- a/llvm/include/llvm/Support/Chrono.h
+++ b/llvm/include/llvm/Support/Chrono.h
@@ -33,6 +33,19 @@ namespace sys {
template <typename D = std::chrono::nanoseconds>
using TimePoint = std::chrono::time_point<std::chrono::system_clock, D>;
+// utc_clock and utc_time are only available since C++20. Add enough code to
+// support formatting date/time in UTC.
+class UtcClock : public std::chrono::system_clock {};
+
+template <typename D = std::chrono::nanoseconds>
+using UtcTime = std::chrono::time_point<UtcClock, D>;
+
+/// Convert a std::time_t to a UtcTime
+inline UtcTime<std::chrono::seconds> toUtcTime(std::time_t T) {
+ using namespace std::chrono;
+ return UtcTime<seconds>(seconds(T));
+}
+
/// Convert a TimePoint to std::time_t
inline std::time_t toTimeT(TimePoint<> TP) {
using namespace std::chrono;
@@ -40,6 +53,13 @@ inline std::time_t toTimeT(TimePoint<> TP) {
time_point_cast<system_clock::time_point::duration>(TP));
}
+/// Convert a UtcTime to std::time_t
+inline std::time_t toTimeT(UtcTime<> TP) {
+ using namespace std::chrono;
+ return system_clock::to_time_t(time_point<system_clock, seconds>(
+ duration_cast<seconds>(TP.time_since_epoch())));
+}
+
/// Convert a std::time_t to a TimePoint
inline TimePoint<std::chrono::seconds>
toTimePoint(std::time_t T) {
@@ -58,6 +78,7 @@ toTimePoint(std::time_t T, uint32_t nsec) {
} // namespace sys
raw_ostream &operator<<(raw_ostream &OS, sys::TimePoint<> TP);
+raw_ostream &operator<<(raw_ostream &OS, sys::UtcTime<> TP);
/// Format provider for TimePoint<>
///
@@ -73,6 +94,11 @@ struct format_provider<sys::TimePoint<>> {
StringRef Style);
};
+template <> struct format_provider<sys::UtcTime<std::chrono::seconds>> {
+ static void format(const sys::UtcTime<std::chrono::seconds> &TP,
+ llvm::raw_ostream &OS, StringRef Style);
+};
+
namespace detail {
template <typename Period> struct unit { static const char value[]; };
template <typename Period> const char unit<Period>::value[] = "";
diff --git a/llvm/lib/Support/Chrono.cpp b/llvm/lib/Support/Chrono.cpp
index 859ece8f550080c..993d200675fe572 100644
--- a/llvm/lib/Support/Chrono.cpp
+++ b/llvm/lib/Support/Chrono.cpp
@@ -40,6 +40,24 @@ static inline struct tm getStructTM(TimePoint<> TP) {
return Storage;
}
+static inline struct tm getStructTMUtc(UtcTime<> TP) {
+ struct tm Storage;
+ std::time_t OurTime = toTimeT(TP);
+
+#if defined(LLVM_ON_UNIX)
+ struct tm *LT = ::gmtime_r(&OurTime, &Storage);
+ assert(LT);
+ (void)LT;
+#endif
+#if defined(_WIN32)
+ int Error = ::gmtime_s(&Storage, &OurTime);
+ assert(!Error);
+ (void)Error;
+#endif
+
+ return Storage;
+}
+
raw_ostream &operator<<(raw_ostream &OS, TimePoint<> TP) {
struct tm LT = getStructTM(TP);
char Buffer[sizeof("YYYY-MM-DD HH:MM:SS")];
@@ -50,12 +68,10 @@ raw_ostream &operator<<(raw_ostream &OS, TimePoint<> TP) {
.count()));
}
-void format_provider<TimePoint<>>::format(const TimePoint<> &T, raw_ostream &OS,
- StringRef Style) {
+template <class T>
+static void format(const T &Fractional, struct tm <, raw_ostream &OS,
+ StringRef Style) {
using namespace std::chrono;
- TimePoint<seconds> Truncated = time_point_cast<seconds>(T);
- auto Fractional = T - Truncated;
- struct tm LT = getStructTM(Truncated);
// Handle extensions first. strftime mangles unknown %x on some platforms.
if (Style.empty()) Style = "%Y-%m-%d %H:%M:%S.%N";
std::string Format;
@@ -90,4 +106,23 @@ void format_provider<TimePoint<>>::format(const TimePoint<> &T, raw_ostream &OS,
OS << (Len ? Buffer : "BAD-DATE-FORMAT");
}
+void format_provider<UtcTime<std::chrono::seconds>>::format(
+ const UtcTime<std::chrono::seconds> &T, raw_ostream &OS, StringRef Style) {
+ using namespace std::chrono;
+ UtcTime<seconds> Truncated =
+ UtcTime<seconds>(duration_cast<seconds>(T.time_since_epoch()));
+ auto Fractional = T - Truncated;
+ struct tm LT = getStructTMUtc(Truncated);
+ llvm::format(Fractional, LT, OS, Style);
+}
+
+void format_provider<TimePoint<>>::format(const TimePoint<> &T, raw_ostream &OS,
+ StringRef Style) {
+ using namespace std::chrono;
+ TimePoint<seconds> Truncated = time_point_cast<seconds>(T);
+ auto Fractional = T - Truncated;
+ struct tm LT = getStructTM(Truncated);
+ llvm::format(Fractional, LT, OS, Style);
+}
+
} // namespace llvm
diff --git a/llvm/unittests/Support/CMakeLists.txt b/llvm/unittests/Support/CMakeLists.txt
index dfd55b228900d8e..e1bf793536b6862 100644
--- a/llvm/unittests/Support/CMakeLists.txt
+++ b/llvm/unittests/Support/CMakeLists.txt
@@ -91,6 +91,7 @@ add_llvm_unittest(SupportTests
TypeTraitsTest.cpp
TrailingObjectsTest.cpp
UnicodeTest.cpp
+ UTCTimeTest.cpp
VersionTupleTest.cpp
VirtualFileSystemTest.cpp
WithColorTest.cpp
diff --git a/llvm/unittests/Support/UTCTimeTest.cpp b/llvm/unittests/Support/UTCTimeTest.cpp
new file mode 100644
index 000000000000000..64e04d29376c3af
--- /dev/null
+++ b/llvm/unittests/Support/UTCTimeTest.cpp
@@ -0,0 +1,41 @@
+//===- unittests/Support/UTCTimeTest.cpp ----------------- ----------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/Chrono.h"
+#include "gtest/gtest.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/FormatProviders.h"
+#include "llvm/Support/FormatVariadic.h"
+
+namespace llvm {
+namespace sys {
+namespace {
+
+TEST(UTCTime, convertutc) {
+ // Get the current time.
+ time_t currentTime;
+ time(¤tTime);
+
+ // Convert with toUtcTime.
+ SmallString<15> customResultString;
+ raw_svector_ostream T(customResultString);
+ T << formatv("{0:%Y-%m-%d %H:%M:%S}", llvm::sys::toUtcTime(currentTime));
+
+ // Convert with gmtime.
+ char gmtimeResultString[20];
+ std::tm *gmtimeResult = std::gmtime(¤tTime);
+ assert(gmtimeResult != NULL);
+ std::strftime(gmtimeResultString, 20, "%Y-%m-%d %H:%M:%S", gmtimeResult);
+
+ // Compare the formatted strings.
+ EXPECT_EQ(customResultString, StringRef(gmtimeResultString, 19));
+
+}
+} // namespace
+} // namespace sys
+} // namespace llvm
More information about the llvm-commits
mailing list