Files
ternfs-XTXMarkets/cpp/core/Time.cpp
Francesco Mazzoli 0f114623f3 Just use unix nanos for eggs times
This was bugging me for a while, but the final straw was that if
one wants to use the max time (for example to look backwards when
traversing edges), you cannot trivially convert from one to the
other, since you'd overflow. So you can't (for instance) trivially
convert from eggs time to `time.Time` in go.

The main disadvantage is that we lose ~50 of the ~600 years
representable with nanoseconds. But I think that's fine.
2023-07-04 08:05:42 +00:00

61 lines
1.9 KiB
C++

// #include <bits/types/struct_timespec.h>
#include <cstdio>
#include <time.h>
#include "Exception.hpp"
#include "Time.hpp"
#include "Assert.hpp"
std::ostream& operator<<(std::ostream& out, Duration d) {
if (d.ns < 1'000) {
out << d.ns << "ns";
} else if (d.ns < 1'000'000) {
out << d.ns/1'000 << "." << d.ns%1'000 << "us";
} else if (d.ns < 1'000'000'000) {
out << d.ns/1'000'000 << "." << d.ns%1'000'000 << "ms";
} else if (d.ns < 1'000'000'000ull*60) {
out << d.ns/1'000'000'000 << "." << d.ns%1'000'000'000 << "s";
} else if (d.ns < 1'000'000'000ull*60*60) {
out << d.ns/(1'000'000'000ull*60) << "." << d.ns%(1'000'000'000ull*60) << "m";
} else {
out << d.ns/(1'000'000'000ull*60*60) << "." << d.ns%(1'000'000'000ull*60*60) << "h";
}
return out;
}
__attribute__((constructor))
static void checkClockRes() {
struct timespec ts;
if (clock_getres(CLOCK_REALTIME, &ts) != 0) {
throw SYSCALL_EXCEPTION("clock_getres");
}
if (ts.tv_sec != 0 || ts.tv_nsec != 1) {
throw EGGS_EXCEPTION("expected nanosecond precisions, got %s,%s", ts.tv_sec, ts.tv_nsec);
}
}
EggsTime eggsNow() {
struct timespec now;
if (clock_gettime(CLOCK_REALTIME, &now) != 0) {
throw SYSCALL_EXCEPTION("clock_gettime");
}
return EggsTime(((uint64_t)now.tv_nsec + ((uint64_t)now.tv_sec * 1'000'000'000ull)));
}
std::ostream& operator<<(std::ostream& out, EggsTime eggst) {
time_t secs = eggst.ns / 1'000'000'000ull;
uint64_t nsecs = eggst.ns % 1'000'000'000ull;
struct tm tm;
if (gmtime_r(&secs, &tm) == nullptr) {
throw SYSCALL_EXCEPTION("gmtime_r");
}
// "2006-01-02T15:04:05.999999999"
char buf[31];
ALWAYS_ASSERT(strftime(buf, 29, "%Y-%m-%dT%H:%M:%S.", &tm) == 20);
ALWAYS_ASSERT(snprintf(buf+20, 10, "%09lu", nsecs) == 9);
buf[30] = '\0';
out << buf;
return out;
}