簡體   English   中英

將std :: chrono :: system_clock :: time_point轉換為struct timeval並返回

[英]Convert std::chrono::system_clock::time_point to struct timeval and back

我正在編寫一個需要訪問舊C庫的C ++代碼,該庫使用timeval作為當前時間的表示。

在舊包中獲取我們使用的當前日期/時間:

struct timeval dateTime;
gettimeofday(&dateTime, NULL);

function(dateTime); // The function will do its task

現在我需要使用C ++ chrono,例如:

    system_clock::time_point now = system_clock::now();
    struct timeval dateTime;

    dateTime.tv_sec = ???? // Help appreaciated here
    dateTime.tv_usec = ???? // Help appreaciated here

    function(dateTime);

稍后在代碼中我需要返回的方法,從返回的struct timeval構建一個time_point變量:

    struct timeval dateTime;
    function(&dateTime);

    system_clock::time_point returnedDateTime = ?? // Help appreacited

我在使用C ++ 11。

[編輯使用time_val而不是free vars]

假設您信任system_clock ,精確度為毫秒,您可以這樣:

  struct timeval dest;
  auto now=std::chrono::system_clock::now();
  auto millisecs=
    std::chrono::duration_cast<std::chrono::milliseconds>(
        now.time_since_epoch()
    );;
  dest.tv_sec=millisecs.count()/1000;
  dest.tv_usec=(millisecs.count()%1000)*1000;

  std::cout << "s:" << dest.tv_sec << " usec:" << dest.tv_usec << std::endl;

duration_cast使用std::chrono::microseconds並相應地調整您的(div / mod)代碼以獲得更高的精度 - 注意您對所獲得的值的准確性的信任程度。

轉換回來是:

  timeval src;

  // again, trusting the value with only milliseconds accuracy
  using dest_timepoint_type=std::chrono::time_point<
    std::chrono::system_clock, std::chrono::milliseconds
  >;
  dest_timepoint_type converted{
    std::chrono::milliseconds{
      src.tv_sec*1000+src.tv_usec/1000
    }
  };

  // this is to make sure the converted timepoint is indistinguishable by one
  // issued by the system_clock
  std::chrono::system_clock::time_point recovered =
      std::chrono::time_point_cast<std::chrono::system_clock::duration>(converted)
  ;

請參閱std::chrono::system_clock::to_time_t() ,它將time_point轉換為time_t ,后者將成為您的tv_sec 你沒有得到tv_usec ,你可以設置0; 或者你可以擺弄一些其他的東西,包括duration_cast ,以便從你的time_point提取一秒的分數。

from_time_t ()反過來。

以下是如何在不使用手動轉換因子的情況下進行轉換,或者根據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表示在epoch之前的時間點,具有負的tv_sec值,然后是正的tv_usec值。 然后,這是一個簡單的操作,可以找到自上secondmicroseconds

如果我對我的假設不正確(並且可以找到更精確的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}});
}

這都是基於timevalsystem_clock的紀元相同的假設。 這沒有指定,但對於所有現有實現都是如此。 運氣好的話,我們可以在不久的將來標准化現有的做法。

請注意,在POSIX中, timeval既可用作time_point ,也可用作duration 因此,如果timeval當前表示持續時間,則to_time_point可能導致運行時錯誤。 如果客戶端將結果解釋為持續時間,則to_timeval可能會導致運行時錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM