You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将libgpiod事件的std::chrono::nanoseconds时间戳转为Linux纪元时间

如何将libgpiod v1事件的单调时间戳转换为Linux纪元时间?

问题根源

libgpiod v1返回的事件时间戳是系统启动以来的单调时间(对应Linux的CLOCK_MONOTONIC时钟),而非Unix纪元(1970-01-01 00:00:00 UTC)时间。你之前的代码仅将单调时间转换为秒数,得到的是系统启动后流逝的时长,自然不是纪元时间。

解决方案思路

要得到事件的纪元时间,需要先计算单调时间与纪元时间的偏移量,再将事件的单调时间加上该偏移量:

  1. 程序运行时,获取当前的单调时间和纪元时间,计算两者差值(偏移量 = 当前纪元时间 - 当前单调时间)
  2. 用事件的单调时间戳加上偏移量,得到事件发生时的纪元时间

代码实现

1. 计算单调时间与纪元时间的偏移量

#include <chrono>
#include <ctime>

// 计算CLOCK_MONOTONIC到Unix纪元的时间偏移(只需初始化一次)
std::chrono::nanoseconds get_monotonic_epoch_offset() {
    // steady_clock对应Linux的CLOCK_MONOTONIC时钟
    auto now_monotonic = std::chrono::steady_clock::now().time_since_epoch();
    // system_clock对应Unix纪元时间
    auto now_epoch = std::chrono::system_clock::now().time_since_epoch();
    // 返回偏移量:纪元时间 - 单调时间
    return now_epoch - now_monotonic;
}

2. 转换事件时间戳为纪元时间

unsigned long State::convert_timestamp_to_epoch(std::chrono::nanoseconds event_timestamp) {
    // 静态存储偏移量,程序启动时计算一次
    static const auto offset = get_monotonic_epoch_offset();
    
    // 事件的纪元时间 = 事件单调时间 + 偏移量
    auto event_epoch_ns = event_timestamp + offset;
    // 转换为秒级纪元时间
    auto event_epoch_sec = std::chrono::duration_cast<std::chrono::seconds>(event_epoch_ns);
    
    return static_cast<unsigned long>(event_epoch_sec.count());
}

注意事项

  • 偏移量默认只需在程序启动时计算一次,因为steady_clock的单调时间不受系统时间修改影响。但如果系统时间可能被手动调整(如NTP校准、手动修改时间),则需要定期重新计算偏移量,否则转换结果会不准确。
  • 如果需要更精确的时间(如毫秒/微秒级),只需将duration_cast的目标类型换成对应的chrono时长即可(例如std::chrono::milliseconds)。

内容的提问来源于stack exchange,提问作者Mendes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 00:22:28