mirror of
https://github.com/thunderbrewhq/bc.git
synced 2025-12-12 01:52:30 +00:00
feat(bc): implement timekeeping
This commit is contained in:
parent
d31a66b9ca
commit
08ac95300a
8 changed files with 525 additions and 1 deletions
|
|
@ -1,7 +1,8 @@
|
||||||
file(GLOB BC_SOURCES
|
file(GLOB BC_SOURCES
|
||||||
"*.cpp"
|
"*.cpp"
|
||||||
"lock/*.cpp"
|
"lock/*.cpp"
|
||||||
"system/**.cpp"
|
"time/*.cpp"
|
||||||
|
"system/*.cpp"
|
||||||
)
|
)
|
||||||
|
|
||||||
add_library(bc STATIC
|
add_library(bc STATIC
|
||||||
|
|
|
||||||
6
bc/Time.hpp
Normal file
6
bc/Time.hpp
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
#ifndef BC_TIME_HPP
|
||||||
|
#define BC_TIME_HPP
|
||||||
|
|
||||||
|
#include "bc/time/Time.hpp"
|
||||||
|
|
||||||
|
#endif
|
||||||
177
bc/system/System_Time.cpp
Normal file
177
bc/system/System_Time.cpp
Normal file
|
|
@ -0,0 +1,177 @@
|
||||||
|
#include "bc/system/System_Time.hpp"
|
||||||
|
#include "bc/time/Time.hpp"
|
||||||
|
#include "bc/time/TimeConst.hpp"
|
||||||
|
|
||||||
|
#if defined(WHOA_SYSTEM_MAC)
|
||||||
|
#include <mach/mach_time.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(WHOA_SYSTEM_WIN)
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(WHOA_SYSTEM_LINUX)
|
||||||
|
#include <ctime>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "bc/Debug.hpp"
|
||||||
|
|
||||||
|
namespace Blizzard {
|
||||||
|
namespace System_Time {
|
||||||
|
|
||||||
|
// Globals
|
||||||
|
|
||||||
|
// Stores the earliest TSC value
|
||||||
|
static uint64_t s_absBegin = 0;
|
||||||
|
|
||||||
|
// Stores the number of nanoseconds since Jan 1, 2000 00:00 GMT at the raw clock moment of s_absBegin.
|
||||||
|
static Time::Timestamp s_gmBegin = 0;
|
||||||
|
|
||||||
|
// timeScales can be multiplied against number of ticks since s_absBegin to get
|
||||||
|
// meaningful durations in the corresponding format
|
||||||
|
double timeScaleNanoseconds = 0.0;
|
||||||
|
double timeScaleMicroseconds = 0.0;
|
||||||
|
double timeScaleMilliseconds = 0.0;
|
||||||
|
double timeScaleSeconds = 0.0;
|
||||||
|
|
||||||
|
// Functions
|
||||||
|
|
||||||
|
bool ReadTSC(uint64_t& counter) {
|
||||||
|
#if defined(WHOA_SYSTEM_WIN)
|
||||||
|
LARGE_INTEGER li;
|
||||||
|
auto ok = QueryPerformanceCounter(&li);
|
||||||
|
|
||||||
|
if (ok) {
|
||||||
|
counter = static_cast<uint64_t>(li.QuadPart);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
#elif defined(WHOA_SYSTEM_MAC)
|
||||||
|
counter = mach_absolute_time();
|
||||||
|
return true;
|
||||||
|
#elif defined(WHOA_SYSTEM_LINUX)
|
||||||
|
struct timespec ts;
|
||||||
|
auto status = clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
|
||||||
|
if (status == 0) {
|
||||||
|
counter = (static_cast<uint64_t>(ts.tv_sec) * TimeConst::TimestampsPerSecond) + ts.tv_nsec;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns a clock moment, relative to s_absBegin;
|
||||||
|
uint64_t QueryClockMoment() {
|
||||||
|
uint64_t counter = 0;
|
||||||
|
ReadTSC(counter);
|
||||||
|
|
||||||
|
return counter - s_absBegin;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns Y2K-GMT nanosecond time.
|
||||||
|
Time::Timestamp Now() {
|
||||||
|
CheckInit();
|
||||||
|
|
||||||
|
// Record clock moment
|
||||||
|
auto moment = QueryClockMoment();
|
||||||
|
|
||||||
|
// Add moment to GMT
|
||||||
|
return s_gmBegin + static_cast<Time::Timestamp>(timeScaleNanoseconds * static_cast<double>(moment));
|
||||||
|
}
|
||||||
|
|
||||||
|
// this func is run on first use
|
||||||
|
void TimeInit() {
|
||||||
|
// Record absolute clock beginning moment in raw CPU time
|
||||||
|
ReadTSC(s_absBegin);
|
||||||
|
BLIZZARD_ASSERT(s_absBegin != 0);
|
||||||
|
|
||||||
|
// Look at system clock's GMT/UTC time as nanoseconds
|
||||||
|
// This associates a point in GMT with the more precise measurements obtained from reading the timestamp counter
|
||||||
|
#if defined(WHOA_SYSTEM_MAC) || defined(WHOA_SYSTEM_LINUX)
|
||||||
|
// Unix system clock
|
||||||
|
struct timeval tv;
|
||||||
|
gettimeofday(&tv, nullptr);
|
||||||
|
|
||||||
|
s_gmBegin = Time::FromUnixTime(tv.tv_sec) + (tv.tv_usec * 1000ULL);
|
||||||
|
#elif defined(WHOA_SYSTEM_WIN)
|
||||||
|
// Read Win32 system time
|
||||||
|
FILETIME ft;
|
||||||
|
GetSystemTimeAsFileTime(&ft);
|
||||||
|
|
||||||
|
// Convert time into Blizzard timestamp
|
||||||
|
ULARGE_INTEGER ul = {};
|
||||||
|
ul.HighPart = ft.dwHighDateTime;
|
||||||
|
ul.LowPart = ft.dwLowDateTime;
|
||||||
|
s_gmBegin = Time::FromWinFiletime(ul.QuadPart);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Attempt to figure out the scale of TSC durations in real-time
|
||||||
|
#if defined(WHOA_SYSTEM_WIN)
|
||||||
|
// Read frequency with Win32 API
|
||||||
|
LARGE_INTEGER freq;
|
||||||
|
QueryPerformanceFrequency(&freq);
|
||||||
|
|
||||||
|
auto ticksPerSecond = static_cast<uint64_t>(freq.QuadPart);
|
||||||
|
auto ticksPerNanosecond = static_cast<double>(ticksPerSecond) / static_cast<double>(TimeConst::TimestampsPerSecond);
|
||||||
|
|
||||||
|
timeScaleNanoseconds = 1.0 / ticksPerNanosecond;
|
||||||
|
#elif defined(WHOA_SYSTEM_MAC)
|
||||||
|
// Ask Mach what the base time parameters are
|
||||||
|
mach_timebase_info_data_t timebase;
|
||||||
|
mach_timebase_info(&timebase);
|
||||||
|
|
||||||
|
timeScaleNanoseconds = static_cast<double>(timebase.numer) / static_cast<double>(timebase.denom);
|
||||||
|
#elif defined(WHOA_SYSTEM_LINUX)
|
||||||
|
// clock_gettime is already attuned to timestamp counter frequency
|
||||||
|
timeScaleNanoseconds = 1.0;
|
||||||
|
#endif
|
||||||
|
timeScaleMicroseconds = timeScaleNanoseconds / 1000.0;
|
||||||
|
timeScaleMilliseconds = timeScaleNanoseconds / 1000000.0;
|
||||||
|
timeScaleSeconds = timeScaleNanoseconds / 1000000000.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CheckInit() {
|
||||||
|
if (s_absBegin == 0) {
|
||||||
|
TimeInit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wall clock functions. The values returned are of an arbitrary epoch.
|
||||||
|
// The only guarantee is that the values returned will increase monotonically.
|
||||||
|
|
||||||
|
// Get wall clock time in nanoseconds
|
||||||
|
uint64_t Nanoseconds() {
|
||||||
|
CheckInit();
|
||||||
|
uint64_t tsc;
|
||||||
|
ReadTSC(tsc);
|
||||||
|
return static_cast<uint64_t>(static_cast<double>(tsc) * timeScaleNanoseconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get wall clock time in microseconds
|
||||||
|
uint64_t Microseconds() {
|
||||||
|
CheckInit();
|
||||||
|
uint64_t tsc;
|
||||||
|
ReadTSC(tsc);
|
||||||
|
return static_cast<uint64_t>(static_cast<double>(tsc) * timeScaleMicroseconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get wall clock time in milliseconds
|
||||||
|
uint64_t Milliseconds() {
|
||||||
|
CheckInit();
|
||||||
|
uint64_t tsc;
|
||||||
|
ReadTSC(tsc);
|
||||||
|
return static_cast<uint64_t>(static_cast<double>(tsc) * timeScaleMilliseconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get wall clock time in seconds
|
||||||
|
uint64_t Seconds() {
|
||||||
|
CheckInit();
|
||||||
|
uint64_t tsc;
|
||||||
|
ReadTSC(tsc);
|
||||||
|
return static_cast<uint64_t>(static_cast<double>(tsc) * timeScaleSeconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace System_Time
|
||||||
|
} // namespace Blizzard
|
||||||
25
bc/system/System_Time.hpp
Normal file
25
bc/system/System_Time.hpp
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
#ifndef BC_SYSTEM_TIME_HPP
|
||||||
|
#define BC_SYSTEM_TIME_HPP
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
#include "bc/time/Types.hpp"
|
||||||
|
|
||||||
|
namespace Blizzard {
|
||||||
|
namespace System_Time {
|
||||||
|
|
||||||
|
Time::Timestamp Now();
|
||||||
|
|
||||||
|
void CheckInit();
|
||||||
|
|
||||||
|
uint64_t QueryClockMoment();
|
||||||
|
|
||||||
|
uint64_t Nanoseconds();
|
||||||
|
uint64_t Microseconds();
|
||||||
|
uint64_t Milliseconds();
|
||||||
|
uint64_t Seconds();
|
||||||
|
|
||||||
|
} // namespace System_Time
|
||||||
|
} // namespace Blizzard
|
||||||
|
|
||||||
|
#endif
|
||||||
229
bc/time/Time.cpp
Normal file
229
bc/time/Time.cpp
Normal file
|
|
@ -0,0 +1,229 @@
|
||||||
|
#include "bc/time/Time.hpp"
|
||||||
|
#include "bc/time/TimeConst.hpp"
|
||||||
|
#include "bc/system/System_Time.hpp"
|
||||||
|
|
||||||
|
#if defined(WHOA_SYSTEM_WIN)
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(WHOA_SYSTEM_MAC) || defined(WHOA_SYSTEM_LINUX)
|
||||||
|
#include <ctime>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
namespace Blizzard {
|
||||||
|
namespace Time {
|
||||||
|
|
||||||
|
// Global variables
|
||||||
|
|
||||||
|
// Jan = [1],
|
||||||
|
// Feb = [2] and so on
|
||||||
|
static uint32_t s_monthDays[14] = {
|
||||||
|
0x41F00000, // Invalid?
|
||||||
|
0,
|
||||||
|
31,
|
||||||
|
59,
|
||||||
|
90,
|
||||||
|
120,
|
||||||
|
151,
|
||||||
|
182,
|
||||||
|
212,
|
||||||
|
243,
|
||||||
|
273,
|
||||||
|
304,
|
||||||
|
334,
|
||||||
|
365
|
||||||
|
};
|
||||||
|
|
||||||
|
// Functions
|
||||||
|
|
||||||
|
// Convert Blizzard timestamp to UNIX seconds
|
||||||
|
int32_t ToUnixTime(Timestamp timestamp) {
|
||||||
|
// Can't return time prior to 1901
|
||||||
|
// Return minimum time (1901) in case of underflow
|
||||||
|
if (timestamp < -3094168447999999999LL) {
|
||||||
|
return std::numeric_limits<int32_t>::min();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 32-bit UNIX sec time suffers from the Year 2038 problem
|
||||||
|
// Return maximum time (2038) in case of overflow
|
||||||
|
if (timestamp >= 1200798847000000000LL) {
|
||||||
|
return std::numeric_limits<int32_t>::max();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Go back 30 years
|
||||||
|
auto y1970 = timestamp + 946684800000000000LL;
|
||||||
|
// Convert nanoseconds to seconds
|
||||||
|
return static_cast<uint32_t>(y1970 / TimeConst::TimestampsPerSecond);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: look into making this Y2038-aware.
|
||||||
|
// Convert UNIX seconds into Blizzard timestamp
|
||||||
|
Timestamp FromUnixTime(int32_t unixTime) {
|
||||||
|
// Convert seconds to nanoseconds
|
||||||
|
auto unixnano = int64_t(unixTime) * TimeConst::TimestampsPerSecond;
|
||||||
|
// Move forward 30 years
|
||||||
|
auto y2k = unixnano - 946684800000000000LL;
|
||||||
|
|
||||||
|
return static_cast<Timestamp>(y2k);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Win32 FILETIME to y2k
|
||||||
|
Timestamp FromWinFiletime(uint64_t winTime) {
|
||||||
|
if (winTime < 33677863631452242ULL) {
|
||||||
|
return std::numeric_limits<Timestamp>::min();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (winTime >= 218145301729837567ULL) {
|
||||||
|
return std::numeric_limits<Timestamp>::max();;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1601 (Gregorian) 100-nsec
|
||||||
|
auto gregorian = static_cast<int64_t>(winTime);
|
||||||
|
// Convert filetime from 1601 epoch to 2000 epoch.
|
||||||
|
auto y2k = gregorian - TimeConst::WinFiletimeY2kDifference;
|
||||||
|
// Convert 100-nsec intervals into nsec intervals
|
||||||
|
return static_cast<Time::Timestamp>(y2k * 100LL);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t ToWinFiletime(Timestamp y2k) {
|
||||||
|
return (y2k + TimeConst::WinFiletimeY2kDifference) / 100ULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t GetTimeElapsed(uint32_t start, uint32_t end) {
|
||||||
|
if (end < start) {
|
||||||
|
return ~start + end;
|
||||||
|
}
|
||||||
|
return end - start;
|
||||||
|
}
|
||||||
|
|
||||||
|
Timestamp GetTimestamp() {
|
||||||
|
return System_Time::Now();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t Nanoseconds() {
|
||||||
|
return System_Time::Nanoseconds();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t Microseconds() {
|
||||||
|
return System_Time::Microseconds();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t Milliseconds() {
|
||||||
|
return System_Time::Milliseconds();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t Seconds() {
|
||||||
|
return System_Time::Seconds();
|
||||||
|
}
|
||||||
|
|
||||||
|
Timestamp MakeTime(const TimeRec& date) {
|
||||||
|
#if defined(WHOA_SYSTEM_WIN)
|
||||||
|
// Win32 implementation
|
||||||
|
FILETIME fileTime = {};
|
||||||
|
SYSTEMTIME systemTime = {};
|
||||||
|
|
||||||
|
systemTime.wYear = static_cast<WORD>(date.year);
|
||||||
|
systemTime.wMonth = static_cast<WORD>(date.month);
|
||||||
|
systemTime.wDay = static_cast<WORD>(date.day);
|
||||||
|
systemTime.wHour = static_cast<WORD>(date.hour);
|
||||||
|
systemTime.wMinute = static_cast<WORD>(date.min);
|
||||||
|
systemTime.wSecond = static_cast<WORD>(date.sec);
|
||||||
|
systemTime.wMilliseconds = 0;
|
||||||
|
|
||||||
|
::SystemTimeToFileTime(&systemTime, &fileTime);
|
||||||
|
|
||||||
|
ULARGE_INTEGER ul = {};
|
||||||
|
ul.HighPart = fileTime.dwHighDateTime;
|
||||||
|
ul.LowPart = fileTime.dwLowDateTime;
|
||||||
|
|
||||||
|
auto timestamp = FromWinFiletime(ul.QuadPart);
|
||||||
|
if (timestamp == std::numeric_limits<Timestamp>::min()
|
||||||
|
|| timestamp == std::numeric_limits<Timestamp>::max()) {
|
||||||
|
return timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
timestamp += date.nsec;
|
||||||
|
return timestamp;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(WHOA_SYSTEM_MAC) || defined(WHOA_SYSTEM_LINUX)
|
||||||
|
// UNIX implementation
|
||||||
|
struct tm t;
|
||||||
|
|
||||||
|
t.tm_year = date.year - 1900;
|
||||||
|
t.tm_mon = date.month - 1;
|
||||||
|
t.tm_mday = date.day;
|
||||||
|
t.tm_hour = date.hour;
|
||||||
|
t.tm_min = date.min;
|
||||||
|
t.tm_sec = date.sec;
|
||||||
|
|
||||||
|
// Convert date into UNIX timestamp
|
||||||
|
auto unixTime = ::timegm(&t);
|
||||||
|
auto timestamp = FromUnixTime(unixTime);
|
||||||
|
if (timestamp == std::numeric_limits< || timestamp == 2147483647L) {
|
||||||
|
return timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
timestamp += date.nsec;
|
||||||
|
return timestamp;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void BreakTime(Timestamp timestamp, TimeRec& date) {
|
||||||
|
auto nsec = timestamp % TimeConst::TimestampsPerSecond;
|
||||||
|
|
||||||
|
if (nsec < 0) {
|
||||||
|
nsec += TimeConst::TimestampsPerSecond;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(WHOA_SYSTEM_WIN)
|
||||||
|
// Win32 implementation
|
||||||
|
ULARGE_INTEGER ul = {};
|
||||||
|
ul.QuadPart = ToWinFiletime(timestamp);
|
||||||
|
|
||||||
|
FILETIME fileTime = {};
|
||||||
|
fileTime.dwHighDateTime = ul.HighPart;
|
||||||
|
fileTime.dwLowDateTime = ul.LowPart;
|
||||||
|
SYSTEMTIME systemTime = {};
|
||||||
|
::FileTimeToSystemTime(&fileTime, &systemTime);
|
||||||
|
|
||||||
|
date.day = static_cast<uint32_t>(systemTime.wDay);
|
||||||
|
date.hour = static_cast<uint32_t>(systemTime.wHour);
|
||||||
|
date.min = static_cast<uint32_t>(systemTime.wMinute);
|
||||||
|
date.sec = static_cast<uint32_t>(systemTime.wSecond);
|
||||||
|
date.wday = static_cast<uint32_t>(systemTime.wDayOfWeek);
|
||||||
|
date.year = static_cast<uint32_t>(systemTime.wYear);
|
||||||
|
date.nsec = nsec;
|
||||||
|
|
||||||
|
bool leapYear = (date.year % 400 == 0) || (date.year % 100 != 0 && ((systemTime.wYear & 3) == 0));
|
||||||
|
|
||||||
|
auto yearDay = s_monthDays[date.month] + -1 + static_cast<uint32_t>(systemTime.wDay);
|
||||||
|
date.yday = yearDay;
|
||||||
|
if (leapYear && date.month > 2) {
|
||||||
|
date.yday++;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(WHOA_SYSTEM_MAC) || defined(WHOA_SYSTEM_LINUX)
|
||||||
|
// UNIX implementation
|
||||||
|
auto unixTime = static_cast<time_t>(ToUnixTime(timestamp));
|
||||||
|
|
||||||
|
struct tm t;
|
||||||
|
::gmtime_r(&unixTime, &t);
|
||||||
|
|
||||||
|
date.year = t.tm_year + 1900;
|
||||||
|
date.month = t.tm_mon + 1;
|
||||||
|
date.day = t.tm_mday;
|
||||||
|
date.hour = t.tm_hour;
|
||||||
|
date.min = t.tm_min;
|
||||||
|
date.sec = t.tm_sec;
|
||||||
|
date.nsec = nsec;
|
||||||
|
date.wday = t.tm_wday;
|
||||||
|
date.yday = t.tm_yday;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Time
|
||||||
|
} // namespace Blizzard
|
||||||
39
bc/time/Time.hpp
Normal file
39
bc/time/Time.hpp
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
#ifndef BC_TIME_TIME_HPP
|
||||||
|
#define BC_TIME_TIME_HPP
|
||||||
|
|
||||||
|
#include "bc/time/Types.hpp"
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace Blizzard {
|
||||||
|
namespace Time {
|
||||||
|
|
||||||
|
int32_t ToUnixTime(Timestamp timestamp);
|
||||||
|
|
||||||
|
Timestamp FromUnixTime(int32_t unixTime);
|
||||||
|
|
||||||
|
// Win32 FILETIME to y2k
|
||||||
|
Timestamp FromWinFiletime(uint64_t winTime);
|
||||||
|
|
||||||
|
uint64_t ToWinFiletime(Timestamp y2k);
|
||||||
|
|
||||||
|
Timestamp GetTimestamp();
|
||||||
|
|
||||||
|
int32_t GetTimeElapsed(uint32_t start, uint32_t end);
|
||||||
|
|
||||||
|
Timestamp MakeTime(const TimeRec& date);
|
||||||
|
|
||||||
|
void BreakTime(Timestamp timestamp, TimeRec& date);
|
||||||
|
|
||||||
|
uint64_t Nanoseconds();
|
||||||
|
|
||||||
|
uint64_t Microseconds();
|
||||||
|
|
||||||
|
uint32_t Milliseconds();
|
||||||
|
|
||||||
|
uint32_t Seconds();
|
||||||
|
|
||||||
|
} // namespace Time
|
||||||
|
} // namespace Blizzard
|
||||||
|
|
||||||
|
#endif
|
||||||
19
bc/time/TimeConst.hpp
Normal file
19
bc/time/TimeConst.hpp
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
#ifndef BC_TIME_TIME_CONST_HPP
|
||||||
|
#define BC_TIME_TIME_CONST_HPP
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace TimeConst {
|
||||||
|
|
||||||
|
// The number of nanoseconds in a second
|
||||||
|
constexpr int64_t TimestampsPerSecond = 1000000000ULL;
|
||||||
|
|
||||||
|
// amount of win32 filetime units in a second
|
||||||
|
constexpr int64_t WinUnitsPerSecond = (TimestampsPerSecond / 100ULL);
|
||||||
|
|
||||||
|
// the FILETIME value needed to move from 1601 epoch to the Year 2000 epoch that Blizzard prefers
|
||||||
|
constexpr int64_t WinFiletimeY2kDifference = 125911584000000000ULL;
|
||||||
|
|
||||||
|
} // namespace TimeConst
|
||||||
|
|
||||||
|
#endif
|
||||||
28
bc/time/Types.hpp
Normal file
28
bc/time/Types.hpp
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
#ifndef BC_TIME_TYPES_HPP
|
||||||
|
#define BC_TIME_TYPES_HPP
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace Blizzard {
|
||||||
|
namespace Time {
|
||||||
|
|
||||||
|
// Timestamp - nanoseconds starting from 0 == January 1 2000 00:00:00 GMT.
|
||||||
|
typedef int64_t Timestamp;
|
||||||
|
|
||||||
|
class TimeRec {
|
||||||
|
public:
|
||||||
|
int32_t year;
|
||||||
|
uint32_t month;
|
||||||
|
uint32_t day;
|
||||||
|
uint32_t hour;
|
||||||
|
uint32_t min;
|
||||||
|
uint32_t sec;
|
||||||
|
uint32_t nsec;
|
||||||
|
uint32_t wday;
|
||||||
|
uint32_t yday;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Time
|
||||||
|
} // namespace Blizzard
|
||||||
|
|
||||||
|
#endif
|
||||||
Loading…
Add table
Add a link
Reference in a new issue