Support micro and milli resolution on timestamps
Supporting higher precision on our timestamps seems worthwhile, and
useful to logging implementations for getting more accurate numbers from
redfish LogService interfaces.
This commit updates the code to add millisecond and microsecond
precision to timestamps.
Tested: Unit tests pass, pretty good coverage here.
Signed-off-by: Ed Tanous <edtanous@google.com>
Change-Id: I0914908966702a6cf1bcb59f22761dc24c46b4c3
diff --git a/http/ut/utility_test.cpp b/http/ut/utility_test.cpp
index a1125b4..8bc122f 100644
--- a/http/ut/utility_test.cpp
+++ b/http/ut/utility_test.cpp
@@ -118,11 +118,24 @@
TEST(Utility, GetDateTimeUintMs)
{
+ EXPECT_EQ(getDateTimeUintMs(uint64_t{1638312095123}),
+ "2021-11-30T22:41:35.123+00:00");
// returns the maximum Redfish date
EXPECT_EQ(getDateTimeUintMs(std::numeric_limits<uint64_t>::max()),
- "9999-12-31T23:59:59+00:00");
+ "9999-12-31T23:59:59.999+00:00");
EXPECT_EQ(getDateTimeUintMs(std::numeric_limits<uint64_t>::min()),
- "1970-01-01T00:00:00+00:00");
+ "1970-01-01T00:00:00.000+00:00");
+}
+
+TEST(Utility, GetDateTimeUintUs)
+{
+ EXPECT_EQ(getDateTimeUintUs(uint64_t{1638312095123456}),
+ "2021-11-30T22:41:35.123456+00:00");
+ // returns the maximum Redfish date
+ EXPECT_EQ(getDateTimeUintUs(std::numeric_limits<uint64_t>::max()),
+ "9999-12-31T23:59:59.999999+00:00");
+ EXPECT_EQ(getDateTimeUintUs(std::numeric_limits<uint64_t>::min()),
+ "1970-01-01T00:00:00.000000+00:00");
}
TEST(Utility, UrlFromPieces)
diff --git a/http/utility.hpp b/http/utility.hpp
index 5ca1dea..c9728f5 100644
--- a/http/utility.hpp
+++ b/http/utility.hpp
@@ -636,6 +636,22 @@
seconds se = duration_cast<seconds>(t);
out += details::padZeros(se.count(), 2);
+ t -= se;
+
+ if constexpr (std::is_same_v<typename decltype(t)::period, std::milli>)
+ {
+ out += '.';
+ using MilliDuration = std::chrono::duration<int, std::milli>;
+ MilliDuration subsec = duration_cast<MilliDuration>(t);
+ out += details::padZeros(subsec.count(), 3);
+ }
+ else if constexpr (std::is_same_v<typename decltype(t)::period, std::micro>)
+ {
+ out += '.';
+ using MicroDuration = std::chrono::duration<int, std::micro>;
+ MicroDuration subsec = duration_cast<MicroDuration>(t);
+ out += details::padZeros(subsec.count(), 6);
+ }
out += "+00:00";
return out;
@@ -653,7 +669,7 @@
return details::toISO8061ExtendedStr(sinceEpoch);
}
-// Returns the formatted date time string.
+// Returns the formatted date time string with millisecond precision
// Note that the maximum supported date is 9999-12-31T23:59:59+00:00, if
// the given |secondsSinceEpoch| is too large, we return the maximum supported
// date.
@@ -664,6 +680,14 @@
return details::toISO8061ExtendedStr(sinceEpoch);
}
+// Returns the formatted date time string with microsecond precision
+inline std::string getDateTimeUintUs(uint64_t microSecondsSinceEpoch)
+{
+ using DurationType = std::chrono::duration<uint64_t, std::micro>;
+ DurationType sinceEpoch(microSecondsSinceEpoch);
+ return details::toISO8061ExtendedStr(sinceEpoch);
+}
+
inline std::string getDateTimeStdtime(std::time_t secondsSinceEpoch)
{
using DurationType = std::chrono::duration<std::time_t>;