下面是如何做轉換既不使用手動轉換因子,或取決於的time_t
未指定舍入模式:
timeval
to_timeval(std::chrono::system_clock::time_point tp)
{
using namespace std::chrono;
auto s = time_point_cast<seconds>(tp);
if (s > tp)
s = s - seconds{1};
auto us = duration_cast<microseconds>(tp - s);
timeval tv;
tv.tv_sec = s.time_since_epoch().count();
tv.tv_usec = us.count();
return tv;
}
std::chrono::system_clock::time_point
to_time_point(timeval tv)
{
using namespace std::chrono;
return system_clock::time_point{seconds{tv.tv_sec} + microseconds{tv.tv_usec}};
}
to_timeval
照顧向下舍入tp
(萬一它爲負值)。 POSIX規範在這方面有點模糊,但我假設timeval
代表了在時代之前的時間點,其值爲負值tv_sec
,然後爲正值tv_usec
值。然後從上一次second
開始找到microseconds
是一個簡單的操作。
如果我對我的假設不正確(並且可以找到更精確的POSIX規範),<chrono>
有權模擬它所做的任何事情。
假設上述慣例,逆向轉換是難以置信的可讀性。它不需要評論。
這都可以這樣進行測試:
timeval
make_timeval(time_t s, long us)
{
timeval tv;
tv.tv_sec = s;
tv.tv_usec = us;
return tv;
}
bool
operator==(timeval x, timeval y)
{
return x.tv_sec == y.tv_sec && x.tv_usec == y.tv_usec;
}
int
main()
{
using namespace std::chrono;
assert(make_timeval(0, 0) == to_timeval(system_clock::time_point{}));
assert(make_timeval(1, 0) == to_timeval(system_clock::time_point{seconds{1}}));
assert(make_timeval(1, 400000) == to_timeval(system_clock::time_point{seconds{1} + microseconds{400000}}));
assert(make_timeval(-1, 400000) == to_timeval(system_clock::time_point{seconds{-1} + microseconds{400000}}));
assert(to_time_point(make_timeval(0, 0)) == system_clock::time_point{});
assert(to_time_point(make_timeval(1, 0)) == system_clock::time_point{seconds{1}});
assert(to_time_point(make_timeval(1, 400000)) == system_clock::time_point{seconds{1} + microseconds{400000}});
assert(to_time_point(make_timeval(-1, 400000)) == system_clock::time_point{seconds{-1} + microseconds{400000}});
}
這是所有基於這樣的假設,即對於timeval
和system_clock
曆元是相同的。這沒有指定,但對於所有現有的實現都是如此。運氣好的話,我們可以在不久的將來將這種現有的做法標準化。
請注意POSIX中的timeval
既用作time_point
,也用於duration
。如果timeval
當前代表持續時間,那麼to_time_point
可能會導致運行時錯誤。如果客戶端將結果解釋爲持續時間,則to_timeval
可能導致運行時錯誤。
可能應該指定爲'dateTime.tv_sec'和'dateTime.tv_usec',因爲目標是結束一個有效的'timeval'結構。 –
@KyleStrand編輯 –
'millisecs.count()/ 1000l;''''和'dest.tv_usec = millisecs.count()%1000l'中的'l'當然不是必需的。一個小問題。 – chux