c++ - 如何在给定时钟偏移的情况下正确获取时间

标签 c++

我想根据系统时间和时钟偏移(从 NTP 服务器找到)创建一个时间戳 (HHMMSSmmm)。我遇到的问题是有时时间戳设置不正确,例如当时间戳为 112400023 且偏移量为 -500 时,将其设置为 112359523 而不是 112359523。

如果发生这种情况,我想将结果减去 40 秒,但我想知道是否有更好的方法来处理所有情况,而不管偏移量如何?

这些是我的案例中使用的函数(其中 GetMillisecondsTs() 是返回时间戳的函数)。

void
Timestamp::gettimeofday(struct timeval* tp)
{
    // Note: some broken versions only have 8 trailing zero's, the correct epoch has 9 trailing zero's
    // This magic number is the number of 100 nanosecond intervals since January 1, 1601 (UTC)
    // until 00:00:00 January 1, 1970 
    static const uint64_t EPOCH = ((uint64_t)116444736000000000ULL);

    SYSTEMTIME  system_time;
    FILETIME    file_time;
    uint64_t    time;

    GetSystemTime(&system_time);
    SystemTimeToFileTime(&system_time, &file_time);
    time = ((uint64_t)file_time.dwLowDateTime);
    time += ((uint64_t)file_time.dwHighDateTime) << 32;

    tp->tv_sec = (long)((time - EPOCH) / 10000000L);
    tp->tv_usec = (long)(system_time.wMilliseconds * 1000);
}

uint32_t
Timestamp::GetMillisecondsTs(int offset)
{
    struct timeval unix;
    gettimeofday(&unix);

    int hour = (unix.tv_sec % 86400L) / 3600;
    int minute = (unix.tv_sec % 3600) / 60;
    int second = (unix.tv_sec % 60);
    int millisecond = (unix.tv_usec) / 1000; //keep only the first three decimals (since offset is 3 decimals)

    ostringstream _ss;
    _ss << std::internal << std::setfill('0') << std::setw(2) << hour << std::internal << std::setfill('0') << std::setw(2) << minute
        << std::internal << std::setfill('0') << std::setw(2) << second << std::internal << std::setfill('0') << std::setw(3) << millisecond;

    std::string _s = _ss.str();
    uint32_t _milliseconds = stoul(_s);
    _milliseconds += offset;

    return _milliseconds;
}

最佳答案

这个怎么样。在转换时间之前添加偏移量

uint32_t
Timestamp::GetMillisecondsTs(int offset)
{
    struct timeval unix;
    gettimeofday(&unix);

    unix.tv_sec += offset / 1000;
    unix.tv_usec += (offset % 1000) * 1000;
    if (unix.tv_usec < 0) {
        unix.tv_sec--;
        unix.tv_usec += 1000000;
    }
    if (unix.tv_usec >= 1000000) {
        unix.tv_sec++;
        unix.tv_usec -= 1000000;
    }

    int hour = (unix.tv_sec % 86400L) / 3600;
    int minute = (unix.tv_sec % 3600) / 60;
    int second = (unix.tv_sec % 60);
    int millisecond = unix.tv_usec / 1000;

    return hour * 10000000 + minute * 100000 + second * 1000 + millisecond;
}

另请注意,您不需要转换为字符串并返回。

关于c++ - 如何在给定时钟偏移的情况下正确获取时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58710984/

相关文章:

c++ - 索引和替换的计算成本

C++ 运算符重载流需要转换

c++ - 如何在QML 的RichText 中使用html 源将图片居中?

c++ - C++插件中的Node.js缓冲区是否终止为空?

c++ - 为什么 `SFINAE` (std::enable_if) 使用 bool 文字而不是 `true_t`/`false_t` 标记类?

c++ - 连接/合并/加入两个 AVL 树

c++ - 如何将 std::copy 输出与 std::distance 一起用于 C 样式数组类型

c++ - btree 程序可能因指针而崩溃

c++ - C++14 中的依赖限定名查找

c++ - 自定义 WinCE 6.0 对话框中的标题栏(颜色、文本、图标等)