Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 20 additions & 5 deletions strings/base_chrono.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,12 @@ WINRT_EXPORT namespace winrt

static time_t to_time_t(time_point const& time) noexcept
{
return std::chrono::duration_cast<time_t_duration>(time - time_t_epoch).count();
return std::chrono::system_clock::to_time_t(to_sys(time));
}

static time_point from_time_t(time_t time) noexcept
{
return time_t_epoch + time_t_duration{ time };
return from_sys(std::chrono::system_clock::from_time_t(time));
}

static file_time to_file_time(time_point const& time) noexcept
Expand All @@ -70,10 +70,25 @@ WINRT_EXPORT namespace winrt
return from_file_time(time);
}

template <typename Duration>
static std::chrono::time_point<std::chrono::system_clock, std::common_type_t<Duration, std::chrono::seconds>>
to_sys(std::chrono::time_point<clock, Duration> const& tp)
{
return epoch + tp.time_since_epoch();
}

template <typename Duration>
static std::chrono::time_point<clock, std::common_type_t<Duration, std::chrono::seconds>>
from_sys(std::chrono::time_point<std::chrono::system_clock, Duration> const& tp)
{
using result_t = std::chrono::time_point<clock, std::common_type_t<Duration, std::chrono::seconds>>;
return result_t{ tp - epoch };
}

private:

// Define 00:00:00, Jan 1 1970 UTC in FILETIME units.
static constexpr time_point time_t_epoch{ duration{ 0x019DB1DED53E8000 } };
using time_t_duration = std::chrono::duration<time_t>;
// system_clock epoch is 00:00:00, Jan 1 1970.
// This is 11644473600 seconds after Windows FILETIME epoch of 00:00:00, Jan 1 1601.
static constexpr std::chrono::time_point<std::chrono::system_clock, std::chrono::seconds> epoch{ std::chrono::seconds{ -11644473600 } };
};
}
40 changes: 40 additions & 0 deletions test/old_tests/UnitTests/clock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,3 +95,43 @@ TEST_CASE("clock, FILETIME")
const auto diff = abs(clock::now() - clock::from_file_time(now_ft));
REQUIRE(diff < milliseconds{ 100 });
}

TEST_CASE("clock, system_clock")
{
DateTime const now_dt = clock::now();
auto const now_sys = system_clock::now();

// Round trip DateTime to std::chrono::system_clock::time_point and back
REQUIRE(clock::from_sys(clock::to_sys(now_dt)) == now_dt);

// Round trip other direction
REQUIRE(clock::to_sys(clock::from_sys(now_sys)) == now_sys);

// Round trip with custom resolution
{
auto const now_dt_sec = time_point_cast<seconds>(now_dt);
REQUIRE(clock::from_sys(clock::to_sys(now_dt_sec)) == now_dt_sec);
}
{
auto const now_dt_mins = time_point_cast<minutes>(now_dt);
REQUIRE(clock::from_sys(clock::to_sys(now_dt_mins)) == now_dt_mins);
}
{
auto const now_sys_sec = time_point_cast<seconds>(now_sys);
REQUIRE(clock::to_sys(clock::from_sys(now_sys_sec)) == now_sys_sec);
}
{
auto const now_sys_mins = time_point_cast<seconds>(now_sys);
REQUIRE(clock::to_sys(clock::from_sys(now_sys_mins)) == now_sys_mins);
}

// Verify that the epoch calculations are correct.
{
auto const diff = now_dt - clock::from_sys(now_sys);
REQUIRE(abs(diff) < milliseconds{ 100 });
}
{
auto const diff = now_sys - clock::to_sys(now_dt);
REQUIRE(abs(diff) < milliseconds{ 100 });
}
}