c++ - UTC 时间戳比较

标签 c++ linux timestamp utc localtime

我正在开发一个客户端-服务器自定义应用程序(将在 Linux 上运行),我发送的其中一个帧包含时间戳(即发送帧的时间)。

为了使我的应用程序可靠,我使用了gmtime在客户端上生成时间。我在比利时,所以现在客户端 VM 的时间比 UTC 时间晚 2 小时(因为夏令时)。

在服务器端,我首先将接收到的字符串转换为time_t 类型。我这样做是为了使用 difftime函数来查看时间戳是否不太旧。 然后,我再次使用 gmtime 生成时间戳(UTC 时间),并将其转换为 time_t

然后我比较两个 time_t 以查看时差。

服务器端的时间转换有问题。 我使用与客户端相同的代码,但输出的gmtime 不同...


客户端:生成时间戳的函数,并将其导出为字符串(time_str):

    std::string getTime()
    {
    time_t rawtime;
    struct tm * timeinfo;
    char buffer[80];

    time (&rawtime);              // Get time of the system
    timeinfo = gmtime(&rawtime);  // Convert it to UTC time

    strftime(buffer,80,"%d-%m-%Y %H:%M:%S",timeinfo);
    std::string time_str(buffer); // Cast it into a string
    cout<<"Time Stamp now (client) : "<<time_str<<endl;

    return time_str;
    }

它产生了这个(本地时间 9 点 33 分):

Time Stamp now : 06-04-2016 07:33:30


服务器端:检索时间戳、生成新的时间戳并进行比较的函数:

bool checkTimeStamp(std::string TimsStamp_str, double delay)
{
    cout<<"TimeStamp recieved: "<<TimsStamp_str<<endl;
    /* Construct tm from string */
    struct tm TimeStampRecu;
    strptime(TimsStamp_str.c_str(), "%d-%m-%Y %I:%M:%S", &TimeStampRecu);
    time_t t_old = mktime(&TimeStampRecu);

    /* Generate New TimeStamp */
    time_t rawtime;
    struct tm * timeinfo;
    time (&rawtime);  // Get time of the system
    timeinfo = gmtime(&rawtime);  // convert it to UTC time_t
    time_t t2 = mktime(timeinfo);  // Re-Cast it to timt_t struct
    /* Convert it into string (for output) */
        char buffer[80];
        strftime(buffer,80,"%d-%m-%Y %H:%M:%S",timeinfo);
        std::string time_str(buffer); // Cast it into a string
        cout<<"Time Stamp now (server) : "<<time_str<<endl;

    /* Comparison */
    double diffSecs = difftime(t2, t_old);
    cout<<diffSecs<<endl;
    bool isTimeStampOK;
    if (diffSecs < delay)
        isTimeStampOK = true;
    else
        isTimeStampOK = false;

return isTimeStampOK;
}

它产生这个(在比利时的 9h33):

TimeStamp recieved : 06-04-2016 07:33:30

Time Stamp now (server) : 06-04-2016 08:33:31


为什么服务器时间 (8h33) 既不是本地时间 (9h33) 也不是 UTC 时间 (7h33)?

我在生成它时犯了错误吗?我不明白在哪里,因为这些是与客户端完全相同的代码...

最佳答案

您的代码中有几个错误,有些是您的错,有些不是。这里最大的问题是 C <time.h> API 是如此糟糕、令人困惑、不完整且容易出错,以至于像这样的错误几乎是强制性的。稍后会详细介绍。

第一个问题是这一行:

struct tm TimeStampRecu;

它创建一个未初始化的 tm然后将其传递给 strptime . strptime可能不会填写 TimeStampRecu 的所有字段.您应该对 TimeStampRecu 进行零初始化像这样:

struct tm TimeStampRecu{};

下一个问题:

strptime(TimsStamp_str.c_str(), "%d-%m-%Y %I:%M:%S", &TimeStampRecu);

%I 表示的 12 小时时间没有 AM/PM 说明符是不明确的。我怀疑这只是一个 type-o,因为它是您唯一使用它的地方。

下一个问题:

gmtime  time_t -> tm  UTC to UTC
mktime  tm -> time_t  local to UTC

mtkime解释输入 tm根据运行它的计算机的本地时间。你需要的是:

timegm  tm -> time_t  UTC to UTC

不幸的是timegm不是标准的 C(或 C++)。幸运的是,它可能无论如何都存在于您的系统上。

通过这些更改,我认为您的代码将按预期运行。


如果您使用的是 C++11,这里有一个更安全的日期/时间库(免费/开源):

https://github.com/HowardHinnant/date

这是为使用这个高级库而翻译的代码:

std::string getTime()
{
    using namespace std::chrono;
    auto rawtime = time_point_cast<seconds>(system_clock::now());
    auto time_str = date::format("%d-%m-%Y %H:%M:%S", rawTime);
    std::cout<<"Time Stamp now (client) : "<<time_str<< '\n';

    return time_str;
}

bool checkTimeStamp(std::string TimsStamp_str, std::chrono::seconds delay)
{
    using namespace std::chrono;
    std::cout<<"TimeStamp recieved:       "<<TimsStamp_str<< '\n';
    /* Construct tm from string */
    std::istringstream in{TimsStamp_str};
    time_point<system_clock, seconds> t_old;
    date::parse(in, "%d-%m-%Y %H:%M:%S", t_old);

    /* Generate New TimeStamp */
    auto rawtime = time_point_cast<seconds>(system_clock::now());
    auto time_str = date::format("%d-%m-%Y %H:%M:%S", rawTime);
    in.str(time_str);
    time_point<system_clock, seconds> t2;
    date::parse(in, "%d-%m-%Y %H:%M:%S", t2);
    cout<<"Time Stamp now (server) : "<<time_str<<endl;

    /* Comparison */
    auto diffSecs = t2 - t_old;
    cout<<diffSecs.count()<<endl;
    bool isTimeStampOK;
    if (diffSecs < delay)
        isTimeStampOK = true;
    else
        isTimeStampOK = false;

    return isTimeStampOK;
}

关于c++ - UTC 时间戳比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36444555/

相关文章:

c++ - 多线程环境下的变量同步

c++ - *&连用是什么意思

c++ - QList 的最大大小是多少?

iphone - nslog时间戳

java - 数据库中的时间戳与文本文件中的时间戳格式不同

PHP - 如何使用 $timestamp 检查今天是星期一还是一个月的第一天?

c++ - C/C++ 位域与按位运算符区分位,哪个更快、更好、更便携?

linux - 结合ccze和grep?

c++ - 调试取决于所选调度程序的奇怪错误

linux - 对脚本中的这一行感到困惑