123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- #pragma once
- #include <nall/function.hpp>
- #include <nall/string.hpp>
- namespace nall::chrono {
- //passage of time functions (from unknown epoch)
- inline auto nanosecond() -> uint64_t {
- timespec tv;
- clock_gettime(CLOCK_MONOTONIC, &tv);
- return tv.tv_sec * 1'000'000'000 + tv.tv_nsec;
- }
- inline auto microsecond() -> uint64_t { return nanosecond() / 1'000; }
- inline auto millisecond() -> uint64_t { return nanosecond() / 1'000'000; }
- inline auto second() -> uint64_t { return nanosecond() / 1'000'000'000; }
- inline auto benchmark(const function<void ()>& f, uint64_t times = 1) -> void {
- auto start = nanosecond();
- while(times--) f();
- auto end = nanosecond();
- print("[chrono::benchmark] ", (double)(end - start) / 1'000'000'000.0, "s\n");
- }
- //exact date/time functions (from system epoch)
- struct timeinfo {
- timeinfo(
- uint year = 0, uint month = 0, uint day = 0,
- uint hour = 0, uint minute = 0, uint second = 0, uint weekday = 0
- ) : year(year), month(month), day(day),
- hour(hour), minute(minute), second(second), weekday(weekday) {
- }
- inline explicit operator bool() const { return month; }
- uint year; //...
- uint month; //1 - 12
- uint day; //1 - 31
- uint hour; //0 - 23
- uint minute; //0 - 59
- uint second; //0 - 60
- uint weekday; //0 - 6
- };
- inline auto timestamp() -> uint64_t {
- return ::time(nullptr);
- }
- //0 = failure condition
- inline auto timestamp(const string& datetime) -> uint64_t {
- static const uint monthDays[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
- uint64_t timestamp = 0;
- if(datetime.match("??????????")) {
- return datetime.natural();
- }
- if(datetime.match("????*")) {
- uint year = datetime.slice(0, 4).natural();
- if(year < 1970 || year > 2199) return 0;
- for(uint y = 1970; y < year && y < 2999; y++) {
- uint daysInYear = 365;
- if(y % 4 == 0 && (y % 100 != 0 || y % 400 == 0)) daysInYear++;
- timestamp += daysInYear * 24 * 60 * 60;
- }
- }
- if(datetime.match("????-??*")) {
- uint y = datetime.slice(0, 4).natural();
- uint month = datetime.slice(5, 2).natural();
- if(month < 1 || month > 12) return 0;
- for(uint m = 1; m < month && m < 12; m++) {
- uint daysInMonth = monthDays[m - 1];
- if(m == 2 && y % 4 == 0 && (y % 100 != 0 || y % 400 == 0)) daysInMonth++;
- timestamp += daysInMonth * 24 * 60 * 60;
- }
- }
- if(datetime.match("????-??-??*")) {
- uint day = datetime.slice(8, 2).natural();
- if(day < 1 || day > 31) return 0;
- timestamp += (day - 1) * 24 * 60 * 60;
- }
- if(datetime.match("????-??-?? ??*")) {
- uint hour = datetime.slice(11, 2).natural();
- if(hour > 23) return 0;
- timestamp += hour * 60 * 60;
- }
- if(datetime.match("????-??-?? ??:??*")) {
- uint minute = datetime.slice(14, 2).natural();
- if(minute > 59) return 0;
- timestamp += minute * 60;
- }
- if(datetime.match("????-??-?? ??:??:??*")) {
- uint second = datetime.slice(17, 2).natural();
- if(second > 59) return 0;
- timestamp += second;
- }
- return timestamp;
- }
- namespace utc {
- inline auto timeinfo(uint64_t time = 0) -> chrono::timeinfo {
- auto stamp = time ? (time_t)time : (time_t)timestamp();
- auto info = gmtime(&stamp);
- return {
- (uint)info->tm_year + 1900,
- (uint)info->tm_mon + 1,
- (uint)info->tm_mday,
- (uint)info->tm_hour,
- (uint)info->tm_min,
- (uint)info->tm_sec,
- (uint)info->tm_wday
- };
- }
- inline auto year(uint64_t timestamp = 0) -> string { return pad(timeinfo(timestamp).year, 4, '0'); }
- inline auto month(uint64_t timestamp = 0) -> string { return pad(timeinfo(timestamp).month, 2, '0'); }
- inline auto day(uint64_t timestamp = 0) -> string { return pad(timeinfo(timestamp).day, 2, '0'); }
- inline auto hour(uint64_t timestamp = 0) -> string { return pad(timeinfo(timestamp).hour, 2, '0'); }
- inline auto minute(uint64_t timestamp = 0) -> string { return pad(timeinfo(timestamp).minute, 2, '0'); }
- inline auto second(uint64_t timestamp = 0) -> string { return pad(timeinfo(timestamp).second, 2, '0'); }
- inline auto date(uint64_t timestamp = 0) -> string {
- auto t = timeinfo(timestamp);
- return {pad(t.year, 4, '0'), "-", pad(t.month, 2, '0'), "-", pad(t.day, 2, '0')};
- }
- inline auto time(uint64_t timestamp = 0) -> string {
- auto t = timeinfo(timestamp);
- return {pad(t.hour, 2, '0'), ":", pad(t.minute, 2, '0'), ":", pad(t.second, 2, '0')};
- }
- inline auto datetime(uint64_t timestamp = 0) -> string {
- auto t = timeinfo(timestamp);
- return {
- pad(t.year, 4, '0'), "-", pad(t.month, 2, '0'), "-", pad(t.day, 2, '0'), " ",
- pad(t.hour, 2, '0'), ":", pad(t.minute, 2, '0'), ":", pad(t.second, 2, '0')
- };
- }
- }
- namespace local {
- inline auto timeinfo(uint64_t time = 0) -> chrono::timeinfo {
- auto stamp = time ? (time_t)time : (time_t)timestamp();
- auto info = localtime(&stamp);
- return {
- (uint)info->tm_year + 1900,
- (uint)info->tm_mon + 1,
- (uint)info->tm_mday,
- (uint)info->tm_hour,
- (uint)info->tm_min,
- (uint)info->tm_sec,
- (uint)info->tm_wday
- };
- }
- inline auto year(uint64_t timestamp = 0) -> string { return pad(timeinfo(timestamp).year, 4, '0'); }
- inline auto month(uint64_t timestamp = 0) -> string { return pad(timeinfo(timestamp).month, 2, '0'); }
- inline auto day(uint64_t timestamp = 0) -> string { return pad(timeinfo(timestamp).day, 2, '0'); }
- inline auto hour(uint64_t timestamp = 0) -> string { return pad(timeinfo(timestamp).hour, 2, '0'); }
- inline auto minute(uint64_t timestamp = 0) -> string { return pad(timeinfo(timestamp).minute, 2, '0'); }
- inline auto second(uint64_t timestamp = 0) -> string { return pad(timeinfo(timestamp).second, 2, '0'); }
- inline auto date(uint64_t timestamp = 0) -> string {
- auto t = timeinfo(timestamp);
- return {pad(t.year, 4, '0'), "-", pad(t.month, 2, '0'), "-", pad(t.day, 2, '0')};
- }
- inline auto time(uint64_t timestamp = 0) -> string {
- auto t = timeinfo(timestamp);
- return {pad(t.hour, 2, '0'), ":", pad(t.minute, 2, '0'), ":", pad(t.second, 2, '0')};
- }
- inline auto datetime(uint64_t timestamp = 0) -> string {
- auto t = timeinfo(timestamp);
- return {
- pad(t.year, 4, '0'), "-", pad(t.month, 2, '0'), "-", pad(t.day, 2, '0'), " ",
- pad(t.hour, 2, '0'), ":", pad(t.minute, 2, '0'), ":", pad(t.second, 2, '0')
- };
- }
- }
- }
|