[+] AuCivilTime.cpp
[*] Split AuClock.cpp
This commit is contained in:
parent
e60c891eac
commit
2a0ff9ab0c
183
Source/Time/AuCivilTime.cpp
Normal file
183
Source/Time/AuCivilTime.cpp
Normal file
@ -0,0 +1,183 @@
|
||||
/***
|
||||
Copyright (C) 2021-2023 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: AuCivilTime.cpp
|
||||
File: AuClock.cpp
|
||||
Date: 2023-09-18
|
||||
Date: 2021-6-13
|
||||
Author: Reece
|
||||
***/
|
||||
#include <Source/RuntimeInternal.hpp>
|
||||
#include "AuCivilTime.hpp"
|
||||
#include "Time.hpp"
|
||||
|
||||
#if defined(AURORA_IS_POSIX_DERIVED)
|
||||
|
||||
#include <sys/resource.h>
|
||||
|
||||
#elif defined(AURORA_IS_MODERNNT_DERIVED)
|
||||
|
||||
#define timegm _mkgmtime
|
||||
|
||||
#else
|
||||
|
||||
using steady_clock = std::chrono::steady_clock;
|
||||
|
||||
#endif
|
||||
|
||||
using sys_clock = std::chrono::system_clock; // more stds to remove
|
||||
|
||||
static sys_clock::duration gEpoch;
|
||||
static sys_clock::duration gUnixDelta;
|
||||
|
||||
static auto InitEpoch()
|
||||
{
|
||||
std::tm start{0, 15, 10, 29, 7, 101, 0, 0, 0};
|
||||
auto epoch = sys_clock::from_time_t(timegm(&start)).time_since_epoch();
|
||||
|
||||
std::tm unixStart{};
|
||||
unixStart.tm_mday = 1;
|
||||
unixStart.tm_year = 70;
|
||||
|
||||
// dont care what the spec says, you can't trust some ms stls
|
||||
// sys_clock can have its own epoch for all we care
|
||||
auto nixEpoch = sys_clock::from_time_t(timegm(&unixStart)).time_since_epoch();
|
||||
|
||||
gUnixDelta = epoch - nixEpoch;
|
||||
gEpoch = epoch;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static auto ___ = InitEpoch();
|
||||
|
||||
sys_clock::duration __NormalizeEpoch(sys_clock::duration sysEpoch)
|
||||
{
|
||||
return sysEpoch - gEpoch;
|
||||
}
|
||||
|
||||
sys_clock::duration __DecodeEpoch(sys_clock::duration auroraEpoch)
|
||||
{
|
||||
return auroraEpoch + gEpoch;
|
||||
}
|
||||
|
||||
template <typename Duration_t>
|
||||
static auto TimeFromDurationSinceEpoch(Duration_t in)
|
||||
{
|
||||
auto duration = std::chrono::duration_cast<sys_clock::duration>(in);
|
||||
return std::chrono::time_point<sys_clock>(__DecodeEpoch(duration));
|
||||
}
|
||||
|
||||
template<typename Duration_t>
|
||||
static time_t CalculateTimeT(AuUInt64 in)
|
||||
{
|
||||
return sys_clock::to_time_t(TimeFromDurationSinceEpoch(Duration_t(in)));
|
||||
}
|
||||
|
||||
namespace Aurora::Time
|
||||
{
|
||||
AUKN_SYM time_t SToCTime(AuInt64 time)
|
||||
{
|
||||
return CalculateTimeT<std::chrono::seconds>(time);
|
||||
}
|
||||
|
||||
AUKN_SYM time_t NSToCTime(AuInt64 time)
|
||||
{
|
||||
return CalculateTimeT<std::chrono::nanoseconds>(time);
|
||||
}
|
||||
|
||||
AUKN_SYM time_t MSToCTime(AuInt64 time)
|
||||
{
|
||||
return CalculateTimeT<std::chrono::milliseconds>(time);
|
||||
}
|
||||
|
||||
AUKN_SYM AuInt64 ConvertAuroraToUnixMS(AuInt64 in)
|
||||
{
|
||||
return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::milliseconds(in) + gUnixDelta).count();
|
||||
}
|
||||
|
||||
AUKN_SYM AuInt64 ConvertAuroraToUnixNS(AuInt64 in)
|
||||
{
|
||||
return std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::nanoseconds(in) + gUnixDelta).count();
|
||||
}
|
||||
|
||||
AUKN_SYM AuInt64 ConvertUnixToAuroraMS(AuInt64 in)
|
||||
{
|
||||
return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::milliseconds(in) - gUnixDelta).count();
|
||||
}
|
||||
|
||||
AUKN_SYM AuInt64 ConvertUnixToAuroraNS(AuInt64 in)
|
||||
{
|
||||
return std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::nanoseconds(in) - gUnixDelta).count();
|
||||
}
|
||||
|
||||
AUKN_SYM tm ToCivilTime(AuInt64 time, bool UTC)
|
||||
{
|
||||
std::tm ret {};
|
||||
auto timet = MSToCTime(time);
|
||||
if (UTC)
|
||||
{
|
||||
#if defined(AURORA_COMPILER_MSVC)
|
||||
auto tm = gmtime_s(&ret, &timet);
|
||||
#else
|
||||
auto tm = gmtime_r(&timet, &ret);
|
||||
#endif
|
||||
#if defined(AURORA_COMPILER_MSVC)
|
||||
SysAssert(!tm, "couldn't convert civil time");
|
||||
#else
|
||||
SysAssert(tm, "couldn't convert civil time");
|
||||
#endif
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined(AURORA_COMPILER_MSVC)
|
||||
if (localtime_s(&ret, &timet))
|
||||
#else
|
||||
if (!localtime_r(&timet, &ret))
|
||||
#endif
|
||||
{
|
||||
SysPushErrorGeneric("Couldn't convert local civil time");
|
||||
return ToCivilTime(time, true);
|
||||
}
|
||||
}
|
||||
tm _;
|
||||
_.CopyFrom(ret);
|
||||
return _;
|
||||
}
|
||||
|
||||
AUKN_SYM AuInt64 FromCivilTime(const tm &time, bool UTC)
|
||||
{
|
||||
::tm tm;
|
||||
time_t timet;
|
||||
|
||||
time.CopyTo(tm);
|
||||
|
||||
if (UTC)
|
||||
{
|
||||
tm.tm_isdst = 0;
|
||||
timet = timegm(&tm);
|
||||
}
|
||||
else
|
||||
{
|
||||
tm.tm_isdst = -1; // out of the 2 crts i've bothered to check, out of 3, this is legal
|
||||
timet = mktime(&tm);
|
||||
}
|
||||
|
||||
if ((timet == 0) || (timet == -1))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return std::chrono::duration_cast<std::chrono::milliseconds>(__NormalizeEpoch(std::chrono::system_clock::from_time_t(timet).time_since_epoch())).count();
|
||||
}
|
||||
|
||||
AUKN_SYM tm NormalizeCivilTimezone(const Time::tm &time, ETimezoneShift shift)
|
||||
{
|
||||
if ((time.tm_isdst == 0) && (shift == ETimezoneShift::eUTC))
|
||||
{
|
||||
return time;
|
||||
}
|
||||
|
||||
return ToCivilTime(FromCivilTime(time, shift == ETimezoneShift::eUTC));
|
||||
}
|
||||
}
|
13
Source/Time/AuCivilTime.hpp
Normal file
13
Source/Time/AuCivilTime.hpp
Normal file
@ -0,0 +1,13 @@
|
||||
/***
|
||||
Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: AuCivilTime.cpp
|
||||
Date: 2023-09-18
|
||||
Author: Reece
|
||||
***/
|
||||
#pragma once
|
||||
|
||||
namespace Aurora::Time
|
||||
{
|
||||
|
||||
}
|
@ -15,8 +15,6 @@
|
||||
|
||||
#elif defined(AURORA_IS_MODERNNT_DERIVED)
|
||||
|
||||
#define timegm _mkgmtime
|
||||
|
||||
// benchmarking: https://github.com/microsoft/STL/issues/2085
|
||||
static AuUInt64 _GetSteadyTimeNS()
|
||||
{
|
||||
@ -54,96 +52,42 @@
|
||||
}
|
||||
// ~3.0741 seconds
|
||||
|
||||
// ~6.07 seconds
|
||||
// using high_res_clock = std::chrono::high_resolution_clock;
|
||||
// ~6.07 seconds
|
||||
|
||||
// holy fuck, we're keeping this
|
||||
// ~2x improvement
|
||||
|
||||
#else
|
||||
|
||||
using steady_clock = std::chrono::steady_clock;
|
||||
|
||||
#endif
|
||||
|
||||
using sys_clock = std::chrono::system_clock; // more stds to remove
|
||||
|
||||
static sys_clock::duration gEpoch;
|
||||
static sys_clock::duration gUnixDelta;
|
||||
sys_clock::duration __NormalizeEpoch(sys_clock::duration sysEpoch);
|
||||
|
||||
static auto InitEpoch()
|
||||
static AuInt64 _CurrentClock()
|
||||
{
|
||||
std::tm start{0, 15, 10, 29, 7, 101, 0, 0, 0};
|
||||
auto epoch = sys_clock::from_time_t(timegm(&start)).time_since_epoch();
|
||||
|
||||
std::tm unixStart{};
|
||||
unixStart.tm_mday = 1;
|
||||
unixStart.tm_year = 70;
|
||||
|
||||
// dont care what the spec says, you can't trust some ms stls
|
||||
// sys_clock can have its own epoch for all we care
|
||||
auto nixEpoch = sys_clock::from_time_t(timegm(&unixStart)).time_since_epoch();
|
||||
|
||||
gUnixDelta = epoch - nixEpoch;
|
||||
gEpoch = epoch;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static auto ___ = InitEpoch();
|
||||
|
||||
template<typename T>
|
||||
static inline T NormalizeEpoch(T sysEpoch)
|
||||
{
|
||||
return sysEpoch - gEpoch;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static inline T DecodeEpoch(T auroraEpoch)
|
||||
{
|
||||
return auroraEpoch + gEpoch;
|
||||
}
|
||||
|
||||
template<typename Clock_t, typename Duration_t>
|
||||
static auto TimeFromDurationSinceEpoch(Duration_t in)
|
||||
{
|
||||
auto duration = std::chrono::duration_cast<typename Clock_t::duration>(in);
|
||||
return std::chrono::time_point<Clock_t>(DecodeEpoch(duration));
|
||||
}
|
||||
|
||||
template<typename Duration_t>
|
||||
static time_t CalculateTimeT(AuUInt64 in)
|
||||
{
|
||||
return sys_clock::to_time_t(TimeFromDurationSinceEpoch<sys_clock>(Duration_t(in)));
|
||||
return __NormalizeEpoch(sys_clock::now().time_since_epoch()).count();
|
||||
}
|
||||
|
||||
static AuInt64 _CurrentClockMS()
|
||||
{
|
||||
return std::chrono::duration_cast<std::chrono::milliseconds>(NormalizeEpoch(sys_clock::now().time_since_epoch())).count();
|
||||
return std::chrono::duration_cast<std::chrono::milliseconds>(__NormalizeEpoch(sys_clock::now().time_since_epoch())).count();
|
||||
}
|
||||
|
||||
static AuInt64 _CurrentClockNS()
|
||||
{
|
||||
return std::chrono::duration_cast<std::chrono::nanoseconds>(NormalizeEpoch(sys_clock::now().time_since_epoch())).count();
|
||||
return std::chrono::duration_cast<std::chrono::nanoseconds>(__NormalizeEpoch(sys_clock::now().time_since_epoch())).count();
|
||||
}
|
||||
|
||||
namespace Aurora::Time
|
||||
{
|
||||
AUKN_SYM time_t SToCTime(AuInt64 time)
|
||||
{
|
||||
return CalculateTimeT<std::chrono::seconds>(time);
|
||||
}
|
||||
|
||||
AUKN_SYM time_t NSToCTime(AuInt64 time)
|
||||
{
|
||||
return CalculateTimeT<std::chrono::nanoseconds>(time);
|
||||
}
|
||||
|
||||
AUKN_SYM time_t MSToCTime(AuInt64 time)
|
||||
{
|
||||
return CalculateTimeT<std::chrono::milliseconds>(time);
|
||||
}
|
||||
|
||||
AUKN_SYM AuInt64 CurrentClock()
|
||||
{
|
||||
return NormalizeEpoch(sys_clock::now().time_since_epoch()).count();
|
||||
return _CurrentClock();
|
||||
}
|
||||
|
||||
AUKN_SYM AuInt64 CurrentClockMS()
|
||||
@ -231,12 +175,7 @@ namespace Aurora::Time
|
||||
|
||||
AUKN_SYM AuInt64 CTimeToMS(time_t time)
|
||||
{
|
||||
return std::chrono::duration_cast<std::chrono::milliseconds>(NormalizeEpoch(sys_clock::from_time_t(time).time_since_epoch())).count();
|
||||
}
|
||||
|
||||
AuInt64 CTimeNSNormalize(AuUInt64 time)
|
||||
{
|
||||
return std::chrono::duration_cast<std::chrono::nanoseconds>(NormalizeEpoch(std::chrono::nanoseconds(time))).count();
|
||||
return std::chrono::duration_cast<std::chrono::milliseconds>(__NormalizeEpoch(sys_clock::from_time_t(time).time_since_epoch())).count();
|
||||
}
|
||||
|
||||
#if defined(AURORA_IS_POSIX_DERIVED)
|
||||
@ -453,95 +392,4 @@ namespace Aurora::Time
|
||||
ADD_CLOCK_FAMILY(Thread, Thread, (ullUser.QuadPart + ullKernel.QuadPart), /*CLOCK_THREAD_CPUTIME_ID*/0, (true, EPseudoPosixClock::eAll));
|
||||
ADD_CLOCK_FAMILY(ThreadKernel, Thread, (ullKernel.QuadPart), 0, (true, EPseudoPosixClock::eKernel));
|
||||
ADD_CLOCK_FAMILY(ThreadUser, Thread, (ullUser.QuadPart), /*CLOCK_THREAD_CPUTIME_ID*/0, (true, EPseudoPosixClock::eUser));
|
||||
|
||||
AUKN_SYM AuInt64 ConvertAuroraToUnixMS(AuInt64 in)
|
||||
{
|
||||
return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::milliseconds(in) + gUnixDelta).count();
|
||||
}
|
||||
|
||||
AUKN_SYM AuInt64 ConvertAuroraToUnixNS(AuInt64 in)
|
||||
{
|
||||
return std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::nanoseconds(in) + gUnixDelta).count();
|
||||
}
|
||||
|
||||
AUKN_SYM AuInt64 ConvertUnixToAuroraMS(AuInt64 in)
|
||||
{
|
||||
return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::milliseconds(in) - gUnixDelta).count();
|
||||
}
|
||||
|
||||
AUKN_SYM AuInt64 ConvertUnixToAuroraNS(AuInt64 in)
|
||||
{
|
||||
return std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::nanoseconds(in) - gUnixDelta).count();
|
||||
}
|
||||
|
||||
AUKN_SYM tm ToCivilTime(AuInt64 time, bool UTC)
|
||||
{
|
||||
std::tm ret {};
|
||||
auto timet = MSToCTime(time);
|
||||
if (UTC)
|
||||
{
|
||||
#if defined(AURORA_COMPILER_MSVC)
|
||||
auto tm = gmtime_s(&ret, &timet);
|
||||
#else
|
||||
auto tm = gmtime_r(&timet, &ret);
|
||||
#endif
|
||||
#if defined(AURORA_COMPILER_MSVC)
|
||||
SysAssert(!tm, "couldn't convert civil time");
|
||||
#else
|
||||
SysAssert(tm, "couldn't convert civil time");
|
||||
#endif
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined(AURORA_COMPILER_MSVC)
|
||||
if (localtime_s(&ret, &timet))
|
||||
#else
|
||||
if (!localtime_r(&timet, &ret))
|
||||
#endif
|
||||
{
|
||||
SysPushErrorGeneric("Couldn't convert local civil time");
|
||||
return ToCivilTime(time, true);
|
||||
}
|
||||
}
|
||||
tm _;
|
||||
_.CopyFrom(ret);
|
||||
return _;
|
||||
}
|
||||
|
||||
AUKN_SYM AuInt64 FromCivilTime(const tm &time, bool UTC)
|
||||
{
|
||||
::tm tm;
|
||||
time_t timet;
|
||||
|
||||
time.CopyTo(tm);
|
||||
|
||||
if (UTC)
|
||||
{
|
||||
tm.tm_isdst = 0;
|
||||
timet = timegm(&tm);
|
||||
}
|
||||
else
|
||||
{
|
||||
tm.tm_isdst = -1; // out of the 2 crts i've bothered to check, out of 3, this is legal
|
||||
timet = mktime(&tm);
|
||||
}
|
||||
|
||||
if ((timet == 0) || (timet == -1))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return std::chrono::duration_cast<std::chrono::milliseconds>(NormalizeEpoch(std::chrono::system_clock::from_time_t(timet).time_since_epoch())).count();
|
||||
}
|
||||
|
||||
AUKN_SYM tm NormalizeCivilTimezone(const Time::tm &time, ETimezoneShift shift)
|
||||
{
|
||||
if ((time.tm_isdst == 0) && (shift == ETimezoneShift::eUTC))
|
||||
{
|
||||
return time;
|
||||
}
|
||||
|
||||
return ToCivilTime(FromCivilTime(time, shift == ETimezoneShift::eUTC));
|
||||
}
|
||||
}
|
@ -6,3 +6,8 @@
|
||||
Author: Reece
|
||||
***/
|
||||
#pragma once
|
||||
|
||||
namespace Aurora::Time
|
||||
{
|
||||
|
||||
}
|
@ -13,8 +13,6 @@
|
||||
|
||||
namespace Aurora::Time
|
||||
{
|
||||
AuInt64 CTimeNSNormalize(AuUInt64 time);
|
||||
|
||||
#if defined(AURORA_PLATFORM_WIN32)
|
||||
|
||||
static AuInt64 ConvertTimestamp(const FILETIME &ft)
|
||||
|
Loading…
Reference in New Issue
Block a user