Skip to content

Commit

Permalink
Specify duration type for std::chrono::time_point
Browse files Browse the repository at this point in the history
To make sure that all of the platforms use the same representation, tests modified accordingly

Signed-off-by: Martynas Gurskas <[email protected]>
  • Loading branch information
Lipt0nas committed Mar 21, 2024
1 parent 496ddf2 commit f4fc89b
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 11 deletions.
2 changes: 1 addition & 1 deletion bindgen/src/bindings/cpp/gen_cpp/miscellany.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ macro_rules! impl_code_type_for_miscellany {

impl_code_type_for_miscellany!(
TimestampCodeType,
"std::chrono::time_point<std::chrono::system_clock>",
"std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds>",
"Timestamp"
);
impl_code_type_for_miscellany!(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ chronological::duration chronological::return_duration(chronological::duration a
}

std::string chronological::to_string_timestamp(chronological::timestamp a) {
std::time_t time = std::chrono::system_clock::to_time_t(a);
using time_point = std::chrono::system_clock::time_point;
std::time_t time = std::chrono::system_clock::to_time_t(time_point {std::chrono::duration_cast<time_point::duration>(a.time_since_epoch())});
auto ns = std::chrono::duration_cast<std::chrono::nanoseconds>(a.time_since_epoch()).count() % 1000000000;
if (ns < 0) {
ns += 1000000000;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace {
namespace chronological {
typedef std::chrono::time_point<std::chrono::system_clock> timestamp;
typedef std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds> timestamp;
typedef std::chrono::duration<int64_t, std::nano> duration;

namespace chronological_error {
Expand Down
2 changes: 1 addition & 1 deletion cpp-tests/scaffolding_tests/coverall/lib_coverall.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

namespace {
namespace coverall {
typedef std::chrono::time_point<std::chrono::system_clock> timestamp;
typedef std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds> timestamp;

class IFirst {
public:
Expand Down
57 changes: 50 additions & 7 deletions cpp-tests/tests/chronological/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,55 @@ std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds> epo


std::chrono::duration<int64_t, std::nano> time_span_seconds(int seconds, int nanoseconds) {
return std::chrono::nanoseconds(std::chrono::seconds(seconds) + std::chrono::nanoseconds(nanoseconds));
return std::chrono::seconds(seconds) + std::chrono::nanoseconds(nanoseconds);
}

std::chrono::time_point<std::chrono::system_clock> time_from_string(const std::string& time) {
std::tm tm = {};
auto ss = std::stringstream(time);
ss >> std::get_time(&tm, "%Y-%m-%dT%H:%M:%S");

#ifdef _WIN32
return std::chrono::system_clock::from_time_t(_mkgmtime(&tm));
#else
return std::chrono::system_clock::from_time_t(timegm(&tm));
#endif
}

void test_string_timestamps() {
// Test post-epoch timestamps
{
auto time_str = "1970-12-12T00:00:00.000000000Z";
auto time = time_from_string(time_str);

ASSERT_EQ(time_str, chronological::to_string_timestamp(time));
}

{
// get_time doesn't support nanoseconds, so we have to add them manually
auto time_str = "1970-12-31T23:59:58.999999900Z";
auto time = time_from_string(time_str) + 999999900ns;

ASSERT_EQ(time_str, chronological::to_string_timestamp(time));
}

{
// get_time doesn't support nanoseconds, so we have to add them manually
auto time = time_from_string("2024-11-05T00:06:01.283000200Z") + 283000200ns;
auto time2 = time_from_string("2024-11-05T00:06:00.283000100Z") + 283000100ns;

ASSERT_EQ(
time,
chronological::add(time2, time_span_seconds(1, 100))
);
}

#ifdef _WIN32
// _mkgmtime doesn't support dates before 1970, so we skip these tests
return;
#endif

// Test pre-epoch timestamps
{
auto time_str = "1969-12-12T00:00:00.000000000Z";
auto time = time_from_string(time_str);
Expand Down Expand Up @@ -55,8 +92,8 @@ void test_string_timestamps() {

int main() {
ASSERT_EQ(
epoch_second(101, 110),
chronological::add(epoch_second(100, 100), time_span_seconds(1, 10))
epoch_second(101, 200),
chronological::add(epoch_second(100, 100), time_span_seconds(1, 100))
);

ASSERT_EQ(
Expand All @@ -69,14 +106,20 @@ int main() {
chronological::ChronologicalError
);


// When testing the min and max values, we need to round them to the nearest 100 ns, as on Windows one tick is 100 ns
auto min = std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds>::min().time_since_epoch().count() / 100 * 100;
auto min_timepoint = std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds>(std::chrono::nanoseconds(min));
ASSERT_EQ(
std::chrono::time_point<std::chrono::system_clock>::min(),
chronological::return_timestamp(std::chrono::time_point<std::chrono::system_clock>::min())
min_timepoint,
chronological::return_timestamp(min_timepoint)
);

auto max = std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds>::max().time_since_epoch().count() / 100 * 100;
auto max_timepoint = std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds>(std::chrono::nanoseconds(max));
ASSERT_EQ(
std::chrono::time_point<std::chrono::system_clock>::max(),
chronological::return_timestamp(std::chrono::time_point<std::chrono::system_clock>::max())
max_timepoint,
chronological::return_timestamp(max_timepoint)
);

ASSERT_EQ(
Expand Down

0 comments on commit f4fc89b

Please sign in to comment.