/*** Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: Time.hpp Date: 2021-6-17 Author: Reece ***/ #pragma once #if defined(AURORA_IS_POSIX_DERIVED) #include #endif namespace Aurora::Time { #if defined(AURORA_PLATFORM_WIN32) static AuInt64 ConvertTimestamp(const FILETIME &ft) { ULARGE_INTEGER ull; ull.LowPart = ft.dwLowDateTime; ull.HighPart = ft.dwHighDateTime; return (ull.QuadPart - 126'435'537'000'000'000ull) / 10'000ULL; } static AuInt64 ConvertTimestamp(AuUInt64 timeIn) { return (126'435'537'000'000'000ull) + (AuUInt64(timeIn) * 10000ULL); } static AuInt64 ConvertTimestampNs(AuUInt64 timeIn) { return (126'435'537'000'000'000ull) + (AuUInt64(timeIn) / 100ULL); } #elif defined(AURORA_IS_POSIX_DERIVED) static AuInt64 ConvertUnixTimespecToMs(const struct timespec &spec) { return ConvertUnixToAuroraMS(spec.tv_sec * 1000ULL + spec.tv_nsec / 1000000ULL); } static void ms2ts(struct timespec *ts, AuUInt64 ms) { ts->tv_sec = ms / 1000; ts->tv_nsec = (ms % 1000) * 1000000; } static void ns2ts(struct timespec *ts, AuUInt64 ns) { ts->tv_sec = ns / 1'000'000'000ull; ts->tv_nsec = ns % 1'000'000'000ull; } static void ms2tsabs(struct timespec *ts, unsigned long ms) { ::clock_gettime(CLOCK_MONOTONIC, ts); auto baseNS = ((AuUInt64)ms * (AuUInt64)1'000'000) + (AuUInt64)ts->tv_nsec; auto remainderNS = (AuUInt64)baseNS % (AuUInt64)1'000'000'000; ts->tv_sec += baseNS / 1'000'000'000ull; ts->tv_nsec = remainderNS; } static void ms2tsabsRealtime(struct timespec *ts, unsigned long ms) { ::clock_gettime(CLOCK_REALTIME, ts); auto baseNS = ((AuUInt64)ms * (AuUInt64)1'000'000) + (AuUInt64)ts->tv_nsec; auto remainderNS = (AuUInt64)baseNS % (AuUInt64)1'000'000'000; ts->tv_sec += baseNS / 1'000'000'000ull; ts->tv_nsec = remainderNS; } static void auabsns2ts(struct timespec *ts, unsigned long long ns) { auto baseNS = ns + AuMSToNS(999'080'100'000); auto remainderNS = (AuUInt64)baseNS % (AuUInt64)1'000'000'000; ts->tv_sec += baseNS / 1'000'000'000ull; ts->tv_nsec = remainderNS; } static void auabsms2ts(struct timespec *ts, unsigned long ms) { auabsns2ts(ts, AuMSToNS(ms)); } static void ms2tvabs(struct timeval *tv, unsigned long ms) { timespec ts; ::clock_gettime(CLOCK_REALTIME, &ts); auto baseNS = ((AuUInt64)ms * (AuUInt64)1'000'000) + (AuUInt64)ts.tv_nsec; auto remainderNS = (AuUInt64)baseNS % (AuUInt64)1'000'000'000; tv->tv_sec = ts.tv_sec; tv->tv_sec += baseNS / 1'000'000'000ull; tv->tv_usec = remainderNS / 1'000ull; } static void ms2tv(struct timeval *tv, unsigned long ms) { tv->tv_sec = ms / 1'000ull; tv->tv_usec = (ms % 1'000ull) * 1'000ull; } static void ms2tsabsmono(struct timespec *ts, unsigned long ms) { clock_gettime(CLOCK_MONOTONIC, ts); auto baseNS = ((AuUInt64)ms * (AuUInt64)1'000'000) + (AuUInt64)ts->tv_nsec; auto remainderNS = (AuUInt64)baseNS % (AuUInt64)1'000'000'000; ts->tv_sec += baseNS / 1'000'000'000ull; ts->tv_nsec = remainderNS; } #endif }