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

vxWorks RTP中获取微秒级时间戳异常问题求助

问题描述

我们编写了一段获取微秒级当前时间戳的代码,在搭配Clang16的Ubuntu系统C++环境下运行正常,但在采用CMake构建系统的vxWorks RTP中测试时得到错误值,需要实现与Ubuntu一致的预期输出。

输出对比

  • Ubuntu终端输出:正常的微秒级时间戳与格式化时间
  • VxWorks终端输出:错误的时间数值(与实际时间严重不符)

原代码

#include <iostream>
#include <chrono>
#include <string>
namespace bhavik{
    typedef char CHAR;
    std::string epochToTime(void){
        try{
            const std::uint64_t epochTimeInMicroseconds = (std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch()).count());
            std::cout << epochTimeInMicroseconds << std::endl;
            std::string timeT;
            const std::uint64_t microsecond = epochTimeInMicroseconds % 1000000U;
            const time_t epochTimeInSec = (epochTimeInMicroseconds - microsecond) / 1000000U;
            CHAR charTimeT[21];
            (void)strftime(charTimeT, 20, "%d-%m-%Y %H:%M:%S", localtime(&epochTimeInSec));
            timeT = charTimeT;
            timeT = timeT + ":" + std::to_string(microsecond);
            return timeT;
        }
        catch(const std::exception& ex){
            std::cout << ex.what() << std::endl;
            return "";
        }
    }
}
int main() {
    std::string str=bhavik::epochToTime();
    std::cout << str<< std::endl;
    return 0;
}

问题分析与解决方案

核心问题

vxWorks的std::chrono::system_clock实现与Linux存在差异:

  1. 纪元(epoch)不同:vxWorks默认纪元为1980-01-01,而非Unix标准的1970-01-01,直接使用会导致时间戳偏移。
  2. RTP环境限制:部分C++标准库的时间接口在vxWorks RTP中可能未完全实现或需要特殊配置。
  3. 数据类型兼容:vxWorks的time_t可能为32位,处理大时间戳时易溢出。

方案1:使用vxWorks原生高精度时间API替代std::chrono

直接调用vxWorks原生的clock_gettime接口获取符合Unix纪元的时间,兼容性更可靠:

#include <iostream>
#include <string>
#include <time.h>
#include <stdexcept>

namespace bhavik{
    typedef char CHAR;
    std::string epochToTime(void){
        try{
            struct timespec ts;
            // 获取Unix纪元的实时时钟(秒+纳秒)
            if (clock_gettime(CLOCK_REALTIME, &ts) != 0) {
                throw std::runtime_error("Failed to retrieve realtime clock");
            }
            // 转换为微秒级时间戳
            std::uint64_t epochTimeInMicroseconds = static_cast<std::uint64_t>(ts.tv_sec) * 1000000 + ts.tv_nsec / 1000;
            std::cout << epochTimeInMicroseconds << std::endl;
            
            std::string timeT;
            const std::uint64_t microsecond = epochTimeInMicroseconds % 1000000U;
            const time_t epochTimeInSec = static_cast<time_t>(ts.tv_sec);
            
            CHAR charTimeT[21];
            // 确保时区配置正确,提前调用tzset()可修正localtime输出
            tzset();
            (void)strftime(charTimeT, 20, "%d-%m-%Y %H:%M:%S", localtime(&epochTimeInSec));
            timeT = charTimeT;
            timeT = timeT + ":" + std::to_string(microsecond);
            return timeT;
        }
        catch(const std::exception& ex){
            std::cout << ex.what() << std::endl;
            return "";
        }
    }
}

int main() {
    std::string str=bhavik::epochToTime();
    std::cout << str<< std::endl;
    return 0;
}

方案2:修正std::chrono的纪元偏移

若必须保留C++标准库接口,需手动添加vxWorks与Unix纪元的偏移量(1970到1980的秒数为315532800):

// 在原代码的时间戳计算处添加偏移
const std::uint64_t VXWORKS_EPOCH_OFFSET = 315532800ULL * 1000000ULL;
const std::uint64_t epochTimeInMicroseconds = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch()).count() + VXWORKS_EPOCH_OFFSET;

额外注意事项

  1. RTP权限:确保vxWorks RTP程序拥有访问系统时钟的权限,可在CMake配置中添加对应编译选项。
  2. 时区配置:通过tzset()或系统环境变量设置正确时区,避免localtime输出错误时区时间。
  3. 数据类型:涉及时间戳转换时,强制使用64位类型(如std::uint64_t),避免32位time_t溢出问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 01:53:16