mirror of
https://github.com/XTXMarkets/ternfs.git
synced 2026-01-07 11:30:49 -06:00
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.
61 lines
1.9 KiB
C++
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;
|
|
} |