我需要一個能夠以 UTC 存盤日期和時間資訊的類(不需要時區/語言環境),我還需要對這些日期/時間(加法、減法)和比較執行基本的算術運算。理想情況下,如果可能的話,我想使用 C 11 標準庫。
std::chrono對于我的目的來說,這似乎是一個很好的候選人。我的DateTime類可以像chrono::time_point具有所需精度的別名一樣簡單。例如
using UTCTime = std::chrono::time_point<SomeClock>;
定義自定義時鐘 ( SomeClock) 允許我的類是型別安全的,而chrono::time_point類提供計算要求。
缺少的部分是轉換日期和時間資訊的函式。chrono::system_clock提供了方法to_time_t和from_time_t,它們受秒精度的限制,這對我來說還不夠好。
有人有解決方案嗎?
uj5u.com熱心網友回復:
僅供參考,這是在 C 20 中的外觀...
using UTCTime = std::chrono::time_point<UTCClock, std::chrono::microseconds>;
變成:
using UTCTime = std::chrono::sys_time<std::chrono::microseconds>;
這:
//
// use UTCClock::fromDate to generate a UTCTime
//
UTCTime t1 = UTCClock::fromDate(1901, 1, 1, 0, 0, 0, 0);
UTCTime t2 = UTCClock::fromDate(1901, 1, 1, 1, 0, 0, 0);
變成:
UTCTime t1 = sys_days{1901y/1/1};
UTCTime t2 = sys_days{1901y/1/1} 1h;
這:
//
// Then we can make use of std::chrono algebra like
// subtracting time_point
//
microseconds timeDiff = t2 -t1;
std::cout << "t2-t1 difference in microseconds " << timeDiff.count() << std::endl;
std::cout << "t2-t1 difference in hours " << duration_cast<hours>(timeDiff).count() << std::endl;
變成:
//
// Then we can make use of std::chrono algebra like
// subtracting time_point
//
microseconds timeDiff = t2 - t1;
std::cout << "t2-t1 difference in microseconds " << timeDiff << '\n';
std::cout << "t2-t1 difference in hours " << duration_cast<hours>(timeDiff) << '\n';
這:
//
// ...or adding/subtracting a duration to a time_point
//
UTCTime t3 = t1 - minutes{3};
std::cout << "t3-t1 difference in minutes " << duration_cast<minutes>(t3-t1).count() << std::endl;
t3 = t1 milliseconds{123};
std::cout << "t3-t1 difference in milliseconds "
<< duration_cast<milliseconds>(t3-t1).count() << std::endl;
變成:
//
// ...or adding/subtracting a duration to a time_point
//
UTCTime t3 = t1 - 3min;
std::cout << "t3-t1 difference in minutes " << duration_cast<minutes>(t3-t1) << '\n';
t3 = t1 123ms;
std::cout << "t3-t1 difference in milliseconds "
<< duration_cast<milliseconds>(t3-t1) << '\n';
這:
//
// ...we can also compare time_points
//
if ( t3 > t1 ) std::cout << "t3 is greater than t1" << std::endl;
保持不變。
這:
//
// We can get a date/time back from a time_point with UTCClock::toDate
//
int year, month, day, hour, min, sec, usec;
UTCClock::toDate(t3, year, month, day, hour, min, sec, usec);
變成:
//
// We can get a date/time back from a time_point with UTCClock::toDate
//
auto td = floor<days>(t3);
year_month_day ymd = td;
hh_mm_ss hms{t3-td};
ymd具有年、月和日的hms吸氣劑,并具有小時、分鐘、秒和微秒的吸氣劑。
輸出從以下變化:
t2-t1 difference in microseconds 3600000000
t2-t1 difference in hours 1
t3-t1 difference in minutes -3
t3-t1 difference in milliseconds 123
t3 is greater than t1
到:
t2-t1 difference in microseconds 3600000000μs
t2-t1 difference in hours 1h
t3-t1 difference in minutes -3min
t3-t1 difference in milliseconds 123ms
t3 is greater than t1
uj5u.com熱心網友回復:
假設您以毫秒精度存盤日期和時間資訊,那么您可以隨時執行以下操作:
time_point<system_clock, milliseconds> epoch_milli{};
auto one_million_millisecond_from_epoch = epoch_milli milliseconds(1'000'000);
uj5u.com熱心網友回復:
我最終得到了這個std::chrono基于最小的實作:
utctime.h
#include <chrono>
#include <string>
struct UTCClock
{
typedef std::chrono::microseconds duration;
typedef duration::rep rep;
typedef duration::period period;
typedef std::chrono::time_point<UTCClock, duration> time_point;
static const bool is_steady = true;
//
// every time_point will be generated from here
//
static time_point fromDate(int year= 0, int month= 0, int day= 0,
int hour= 0, int min = 0, int sec= 0,
int usec= 0);
//
// convert time_point to a date/time representation
//
static void toDate(const time_point &tp,
int &year, int &month, int &day,
int &hour, int &min, int &sec,
int &usec);
// NOT Supported, we don't need current time. We only
// want to represent UTC DateTime
// static time_point now();
};
using UTCTime = std::chrono::time_point<UTCClock, std::chrono::microseconds>;
utctime.cpp
#include "utctime.h"
#include <ctime>
namespace chrono = std::chrono;
using chrono::duration_cast;
using chrono::time_point_cast;
namespace {
std::time_t to_time_t(const UTCClock::time_point &tp) noexcept
{
return std::time_t(
duration_cast<chrono::seconds>(tp.time_since_epoch()).count());
}
UTCClock::time_point from_time_t(std::time_t tt) noexcept
{
return time_point_cast<UTCClock::duration>(
chrono::time_point<UTCClock,chrono::seconds>(chrono::seconds(tt)));
}
} // namespace
UTCClock::time_point UTCClock::fromDate(
int year, int month, int day, int hour, int min, int sec, int usec)
{
std::tm tm = {0};
tm.tm_year = year - 1900;
tm.tm_mon = month - 1;
tm.tm_mday = day;
tm.tm_hour = hour;
tm.tm_min = min;
tm.tm_sec = sec;
tm.tm_isdst = -1;
std::time_t tt = timegm(&tm);
return from_time_t(tt) chrono::microseconds(usec);
}
void UTCClock::toDate(const UTCClock::time_point &tp,
int &year,
int &month,
int &day,
int &hour,
int &min,
int &sec,
int &usec)
{
std::time_t tt = to_time_t(tp);
std::tm tm;
gmtime_r(&tt, &tm);
year = tm.tm_year 1900;
month = tm.tm_mon 1;
day = tm.tm_mday;
hour = tm.tm_hour;
min = tm.tm_min;
chrono::microseconds leftover =
tp - from_time_t(tt) chrono::seconds(tm.tm_sec);
sec = duration_cast<chrono::seconds>(leftover).count();
usec = (leftover-chrono::seconds(sec)).count();
}
它可以這樣使用:
#include "utctime.h"
#include <iostream>
using namespace std::chrono;
int main(int argc, char* argv[])
{
//
// use UTCClock::fromDate to generate a UTCTime
//
UTCTime t1 = UTCClock::fromDate(1901, 1, 1, 0, 0, 0, 0);
UTCTime t2 = UTCClock::fromDate(1901, 1, 1, 1, 0, 0, 0);
//
// Then we can make use of std::chrono algebra like
// subtracting time_point
//
microseconds timeDiff = t2 -t1;
std::cout << "t2-t1 difference in microseconds " <<
timeDiff.count() << std::endl;
std::cout << "t2-t1 difference in hours " <<
duration_cast<hours>(timeDiff).count() << std::endl;
//
// ...or adding/subtracting a duration to a time_point
//
UTCTime t3 = t1 - minutes{3};
std::cout << "t3-t1 difference in minutes " <<
duration_cast<minutes>(t3-t1).count() << std::endl;
t3 = t1 milliseconds{123};
std::cout << "t3-t1 difference in milliseconds " <<
duration_cast<milliseconds>(t3-t1).count() << std::endl;
//
// ...we can also compare time_points
//
if ( t3 > t1 ) std::cout << "t3 is greater than t1" << std::endl;
//
// We can get a date/time back from a time_point with UTCClock::toDate
//
int year, month, day, hour, min, sec, usec;
UTCClock::toDate(t3, year, month, day, hour, min, sec, usec);
//
// std::chrono is also type safe and doesn't allow to
// mix dates generated by different clocks
//
system_clock::time_point systp = system_clock::now();
// NO: doesn't compile
// auto tx = t1 - systp;
// NO: doesn't compile
// if (t1 < systp);
// NO: doesn't compile
// UTCClock::toDate(systp, year, month, day, hour, min, sec, usec);
return 0;
}
輸出:
t2-t1 difference in microseconds 3600000000 t2-t1 difference in hours 1 t3-t1 difference in minutes -3 t3-t1 difference in milliseconds 123 t3 is greater than t1
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/409551.html
標籤:
上一篇:在M1macOS上安裝Hive
