forked from cheng/wallet
93 lines
2.9 KiB
C++
93 lines
2.9 KiB
C++
|
// Since I need my own time and duration types,
|
|||
|
// that have the same binary representation on all
|
|||
|
// operating systems and environmens
|
|||
|
|
|||
|
#include "stdafx.h"
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/*I have spent far, far too much time trying to get overly clever layers that supposedly provide OS independence to work.
|
|||
|
*/
|
|||
|
|
|||
|
|
|||
|
|
|||
|
#ifdef _MSC_VER
|
|||
|
// compiling under Microsoft Visual Studio.
|
|||
|
#include <time.h>
|
|||
|
#endif
|
|||
|
|
|||
|
|
|||
|
namespace ro {
|
|||
|
// need to define my own time types:
|
|||
|
// typedef time_t time_t; // is signed time in seconds past the epoch modulo 2 ^ 64
|
|||
|
// because in some environments, time_t is seconds past the epoch modulo 2 ^ 32
|
|||
|
// and if time_t is not 64 bits, ro:time_t is a typedef of bint_fast64_t
|
|||
|
|
|||
|
ro::time_t time() { return ::time(nullptr); }
|
|||
|
// equivalent to regular old time(nullptr) except in environments where time_t
|
|||
|
// except in environments where time_t is seconds past the epoch modulo 2 ^ 32
|
|||
|
|
|||
|
ro::sec_t system_time_now() {
|
|||
|
ro::sec_t uu;
|
|||
|
return uu + (ro::sec)(::time(nullptr));
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
// duration past startup time modulo 2^32 Rolls over every forty eight days, making durations longer than twenty four days of unclear sign
|
|||
|
msec msec_since_epoch(void){
|
|||
|
return std::chrono::duration_cast<ro::msec> (std::chrono::steady_clock::now().time_since_epoch());
|
|||
|
}
|
|||
|
|
|||
|
// date and time as utc time in human readable form
|
|||
|
std::string iso_utc_time(ro::time_t t) {
|
|||
|
std::array<char, 20> retval{ "0000-00-00t00:00:00" };
|
|||
|
std::tm tm_t;
|
|||
|
if (0 == _gmtime64_s(&tm_t, &t)) {
|
|||
|
strftime(retval.data(), 20, "%Y-%m-%dt%H:%M:%S", &tm_t);
|
|||
|
}
|
|||
|
return retval.data();
|
|||
|
}// which is a string expressing the utc time in human readable form
|
|||
|
|
|||
|
// local date and time in human readable form
|
|||
|
std::string iso_local_time(ro::time_t t) {
|
|||
|
std::array<char, 26> retval{ "0000-00-00t00:00:00-00:00" };
|
|||
|
std::tm tm_t;
|
|||
|
if (0 == _localtime64_s(&tm_t, &t)) {
|
|||
|
strftime(retval.data(), 20, "%Y-%m-%dt%H:%M:%S", &tm_t);
|
|||
|
long timezone;
|
|||
|
if (0 == _get_timezone(&timezone)) {
|
|||
|
if (timezone <= 0) {
|
|||
|
retval.data()[19] = '+';
|
|||
|
timezone = -timezone;
|
|||
|
}
|
|||
|
sprintf_s(retval.data() + 20, 6, "%2.2d:%2.2d", (timezone / 3600) % 24, ((timezone+30) / 60) % 60);
|
|||
|
}
|
|||
|
}
|
|||
|
return retval.data();
|
|||
|
}
|
|||
|
|
|||
|
// string expressing the current utc time
|
|||
|
std::string iso_utc_time(ro::sec_t t) {
|
|||
|
return ro::iso_utc_time((t.time_since_epoch()).count());
|
|||
|
}
|
|||
|
// string expressing the current local time
|
|||
|
std::string iso_local_time(ro::sec_t t) {
|
|||
|
return ro::iso_local_time((t.time_since_epoch()).count());
|
|||
|
}
|
|||
|
|
|||
|
// String expressing steady system time interval
|
|||
|
// Typical usage steady_clock(msec_time_now() - start_time);
|
|||
|
// Always outputs eleven characters plus a null terminator.
|
|||
|
std::string duration_as_string(msec t) {
|
|||
|
std::array<char, 12> retval{ " .000" };
|
|||
|
uint_fast32_t t_as_int{ t.count() };
|
|||
|
uint_fast32_t milliseconds{ t_as_int % 1000 };
|
|||
|
uint_fast32_t seconds{ t_as_int / 1000 };
|
|||
|
snprintf(&retval[0], retval.size(), "%7u.%03u", seconds, milliseconds);
|
|||
|
return retval.data();
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
|