xref: /aosp_15_r20/external/openscreen/platform/impl/time_unittest.cc (revision 3f982cf4871df8771c9d4abe6e9a6f8d829b2736)
1 // Copyright 2019 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "platform/api/time.h"
6 
7 #include <chrono>
8 #include <ctime>
9 
10 #include "gtest/gtest.h"
11 #include "util/chrono_helpers.h"
12 
13 namespace openscreen {
14 
15 #if __cplusplus < 202000L
16 // Before C++20, the standard does not guarantee that time_t is the number of
17 // seconds since the UNIX epoch. It also doesn't guarantee that one tick of
18 // time_t represents one second. However, this is so universally common, it's
19 // worth assuming the platform provides this.
TEST(TimeTest,TimeTMeetsTheCpp20Standard)20 TEST(TimeTest, TimeTMeetsTheCpp20Standard) {
21   // Use the functions the standard *does* provide for calendar time
22   // conversions to determine the value of time_t at the UNIX epoch.
23   std::tm epoch_tm;
24   epoch_tm.tm_sec = 0;
25   epoch_tm.tm_min = 0;
26   epoch_tm.tm_hour = 0;
27   epoch_tm.tm_mday = 1;
28   epoch_tm.tm_mon = 0;
29   epoch_tm.tm_year = 70;  // 1970
30   epoch_tm.tm_isdst = 0;
31   // Note: std::mktime() assumes the translation is in the local time zone.
32   const std::time_t new_year_1970_in_local_tz = std::mktime(&epoch_tm);
33   // Purposely misinterpret |new_year_1970_in_local_tz| as UTC to provide
34   // information as to how to offset |epoch_tm| such that std::mktime() will
35   // be fooled into returning the value in terms of UTC.
36   std::tm* const wrong_tm = std::gmtime(&new_year_1970_in_local_tz);
37   epoch_tm.tm_sec += epoch_tm.tm_sec - wrong_tm->tm_sec;
38   epoch_tm.tm_min += epoch_tm.tm_min - wrong_tm->tm_min;
39   epoch_tm.tm_hour += epoch_tm.tm_hour - wrong_tm->tm_hour;
40   epoch_tm.tm_mday += epoch_tm.tm_mday - wrong_tm->tm_mday;
41   epoch_tm.tm_mon += epoch_tm.tm_mon - wrong_tm->tm_mon;
42   epoch_tm.tm_year += epoch_tm.tm_year - wrong_tm->tm_year;
43 
44   const std::time_t epoch = std::mktime(&epoch_tm);
45   EXPECT_EQ(seconds(0), seconds(epoch));
46 
47   ++epoch_tm.tm_sec;
48   const std::time_t epoch_plus_one_second = std::mktime(&epoch_tm);
49   EXPECT_EQ(seconds(1), seconds(epoch_plus_one_second));
50 }
51 #endif
52 
53 }  // namespace openscreen
54