Common/Timer: Fix integer underflow in Timer::GetDoubleTime for dates before ~2008.
This commit is contained in:
parent
ed32a2a1fe
commit
eab07866a3
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
#include "Common/Timer.h"
|
#include "Common/Timer.h"
|
||||||
|
|
||||||
#include <ctime>
|
#include <chrono>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
@ -233,37 +233,17 @@ std::string Timer::GetTimeFormatted()
|
||||||
// Returns a timestamp with decimals for precise time comparisons
|
// Returns a timestamp with decimals for precise time comparisons
|
||||||
double Timer::GetDoubleTime()
|
double Timer::GetDoubleTime()
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
// FYI: std::chrono::system_clock epoch is not required to be 1970 until c++20.
|
||||||
struct timeb tp;
|
// We will however assume time_t IS unix time.
|
||||||
(void)::ftime(&tp);
|
using Clock = std::chrono::system_clock;
|
||||||
#elif defined __APPLE__
|
|
||||||
struct timeval t;
|
|
||||||
(void)gettimeofday(&t, nullptr);
|
|
||||||
#else
|
|
||||||
struct timespec t;
|
|
||||||
(void)clock_gettime(CLOCK_MONOTONIC, &t);
|
|
||||||
#endif
|
|
||||||
// Get continuous timestamp
|
|
||||||
u64 TmpSeconds = Common::Timer::GetTimeSinceJan1970();
|
|
||||||
|
|
||||||
// Remove a few years. We only really want enough seconds to make
|
// TODO: Use this on switch to c++20:
|
||||||
// sure that we are detecting actual actions, perhaps 60 seconds is
|
// const auto since_epoch = Clock::now().time_since_epoch();
|
||||||
// enough really, but I leave a year of seconds anyway, in case the
|
const auto unix_epoch = Clock::from_time_t({});
|
||||||
// user's clock is incorrect or something like that.
|
const auto since_epoch = Clock::now() - unix_epoch;
|
||||||
TmpSeconds = TmpSeconds - DOUBLE_TIME_OFFSET;
|
|
||||||
|
|
||||||
// Make a smaller integer that fits in the double
|
const auto since_double_time_epoch = since_epoch - std::chrono::seconds(DOUBLE_TIME_OFFSET);
|
||||||
u32 Seconds = (u32)TmpSeconds;
|
return std::chrono::duration_cast<std::chrono::duration<double>>(since_double_time_epoch).count();
|
||||||
#ifdef _WIN32
|
|
||||||
double ms = tp.millitm / 1000.0 / 1000.0;
|
|
||||||
#elif defined __APPLE__
|
|
||||||
double ms = t.tv_usec / 1000000.0;
|
|
||||||
#else
|
|
||||||
double ms = t.tv_nsec / 1000000000.0;
|
|
||||||
#endif
|
|
||||||
double TmpTime = Seconds + ms;
|
|
||||||
|
|
||||||
return TmpTime;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Formats a timestamp from GetDoubleTime() into a date and time string
|
// Formats a timestamp from GetDoubleTime() into a date and time string
|
||||||
|
|
|
@ -41,7 +41,7 @@ public:
|
||||||
|
|
||||||
// Arbitrarily chosen value (38 years) that is subtracted in GetDoubleTime()
|
// Arbitrarily chosen value (38 years) that is subtracted in GetDoubleTime()
|
||||||
// to increase sub-second precision of the resulting double timestamp
|
// to increase sub-second precision of the resulting double timestamp
|
||||||
static const int DOUBLE_TIME_OFFSET = (38 * 365 * 24 * 60 * 60);
|
static constexpr int DOUBLE_TIME_OFFSET = (38 * 365 * 24 * 60 * 60);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
u64 m_LastTime;
|
u64 m_LastTime;
|
||||||
|
|
Loading…
Reference in New Issue