fix the year 2038 problem in getDateTime

The existing codes cast uint64_t into time_t which is int32_t in
most 32-bit systems. It results overflow if the timestamp is larger
than INT_MAX.
time_t will be 64 bits in future releases of glibc. See
https://sourceware.org/bugzilla/show_bug.cgi?id=28182.

This change workarounds the year 2038 problem via boost's ptime.
std::chrono doesn't help since it is still 32 bits.

Tested on QEMU.
Example output for certificate:
{
  "Name": "HTTPS Certificate",
  "Subject": null,
  "ValidNotAfter": "2106-01-28T20:40:31Z",
  "ValidNotBefore": "2106-02-06T18:28:16Z"
}
Previously, the format is like "1969-12-31T12:00:00+00:00". Note
that the ending "+00:00" is the time zone, not ms.

Tested the schema on QEMU. No new Redfish Service Validator errors.

Signed-off-by: Nan Zhou <nanzhoumails@gmail.com>
Signed-off-by: Ed Tanous <edtanous@google.com>
Change-Id: I8ef0bee3d724184d96253c23f3919447828d3f82
diff --git a/http/ut/utility_test.cpp b/http/ut/utility_test.cpp
index 191a16a..fc8b90e 100644
--- a/http/ut/utility_test.cpp
+++ b/http/ut/utility_test.cpp
@@ -56,3 +56,22 @@
     EXPECT_TRUE(crow::utility::base64Decode(encoded, decoded));
     EXPECT_EQ(data, decoded);
 }
+
+TEST(Utility, GetDateTime)
+{
+    // some time before the epoch
+    EXPECT_EQ(crow::utility::getDateTimeStdtime(std::time_t{-1234567}),
+              "1969-12-17T17:03:53Z");
+    // epoch
+    EXPECT_EQ(crow::utility::getDateTimeStdtime(std::time_t{0}),
+              "1970-01-01T00:00:00Z");
+    // some time in the past after the epoch
+    EXPECT_EQ(crow::utility::getDateTimeUint(uint64_t{1638312095}),
+              "2021-11-30T22:41:35Z");
+    // some time in the future, beyond 2038
+    EXPECT_EQ(crow::utility::getDateTimeUint(uint64_t{41638312095}),
+              "3289-06-18T21:48:15Z");
+    // the maximum time we support
+    EXPECT_EQ(crow::utility::getDateTimeUint(uint64_t{253402300799}),
+              "9999-12-31T23:59:59Z");
+}