【问题标题】:std chrono 1 hour wrong when converting with ctime to char*使用 ctime 转换为 char * 时 std chrono 1 小时错误
【发布时间】:2014-10-08 21:48:30
【问题描述】:

我试图在 00:00:00 这样的字符串中显示高分辨率时间点之间的差异。我的问题是我打印的时间是+1小时。

#include <chrono>
#include <ctime>
#include <iostream>
#include <thread>

using namespace std;
using namespace chrono;

int main(int argc, char **argv) {
    auto start = high_resolution_clock::now();
    this_thread::sleep_for(seconds(1));
    auto stop = high_resolution_clock::now();
    auto result = stop - start;
    time_t t = duration_cast<seconds>(result).count();
    cout << ctime(&t) << endl;
    return EXIT_SUCCESS;
}

打印出来

Thu Jan 1 01:00:01 1970

虽然我希望它打印出来

Thu Jan 1 00:00:01 1970

以下打印件 1:

cout << (int) duration_cast<seconds>(result).count() << endl;

也许它与时区有关?任何帮助表示赞赏!

【问题讨论】:

  • 好久没用ctime了,不过the documentation好像表示时间是用localtime换算的。
  • localtime 返回一个结构体 tm*。我可以编辑时间,但我认为它应该是正确的,而不是像现在这样增加 1 小时。
  • 如果您不想使用时区,请使用不使用时区的函数执行转换,可能是gmtime 或任何其他替代方法。跨度>
  • @RetiredNinja 哇,gmtime 救了我!我尝试并获得了预期的输出,非常感谢。用它写一个答案并且不接受它。
  • 嘿@fonZ,我更新了我的答案。你应该可以通过这个走得更远。

标签: c++ c++11 chrono ctime


【解决方案1】:

在 cmets 中讨论了你到底想要什么之后,我想出了this

size_t MkTimestamp(char *output, size_t size)
{
    milliseconds ms = duration_cast<milliseconds>(system_clock::now().time_since_epoch());
    seconds s = duration_cast<seconds>(ms);
    time_t ctime = (time_t) s.count();
    tm components;
    size_t return_value = 0;

    if (!localtime_r(&ctime, &components)) return 0;
    if ((return_value = strftime(output, size, "%F %T:XXX", &components)) == 0) return 0;

    int ms_d1 = ms.count() / 100 % 10, ms_d2 = ms.count() / 10 % 10, ms_d3 = ms.count() % 10;
    output[return_value - 3] = ms_d1 + '0';
    output[return_value - 2] = ms_d2 + '0';
    output[return_value - 1] = ms_d3 + '0';
    return return_value;
}

简而言之,你给它一个字符缓冲区和它的大小,它会向它写入一个时间戳(如果缓冲区太小,它返回零,否则它返回它写入的字符总数,包括空终止符)。如果您希望将此时间戳作为std::string,您可以使用std::string 切片构造函数:

char buffer[64];
string timestamp(buffer, MkTimestamp(buffer, sizeof buffer));

如果 MkTimestamp 成功,字符串构造函数将一直读取到空终止符,如果失败,则生成一个空字符串。如果您愿意,您可以将此步骤合并到MkTimestamp

这与您第一次尝试的不同之处在于:

  • 由于您尝试生成时间戳,因此最好使用绝对时间而不是相对时间。
  • 由于我们要使用绝对时间,我们必须使用system_clock,因为这是唯一一个实际给出time_point 值的时钟,可以有意义地转换为旧C 系列函数将接受的time_t 值。 (有时,这两个时钟具有相同的历元,甚至是相同的时钟。但并非总是如此。)
  • 我选择了不同的时间格式。如果你愿意,你可以改变它,这并不难。我强烈建议您将毫秒占位符保留在格式字符串中,这样只要strftime 成功,您就不必进行任何长度测试。

信用到期(我在撰写此答案时引用的其他 stackoverflow 答案)

原答案:

Here's an ideone with your code.(请注意,您描述的问题不会发生。)另外,您缺少#include &lt;thread&gt;

除此之外,documentation for ctime() 表示它的参数应该是一个日历日期。您将其传递一秒钟的间隔,这本身或多或少毫无意义。您可能是对的,因为时区解释问题,它显示正好休息一小时。

如果没有更多关于您实际尝试做什么的详细信息,我无法做出更好的回答。

【讨论】:

  • 当我开始写答案时,编辑之前没有。
  • 我知道......但我认为阅读这篇文章的人会明白这属于一个有 main 的程序......所以我添加了它。
  • 至于我想要做什么,我试图打印一个经过时间的字符串表示。 00:00:01 而不是 01:00:01。 1 小时困扰着我,因为它只过去了 1 秒,据我所知,转换为 time_t 是合法的。
  • 如果您想要的只是经过时间,那么您不应该尝试使用不处理经过时间的函数来打印它。使用第二种方法。
  • 所以对你来说它打印的是 00:00:00?在那个ideone上,我看到它打印正确?
猜你喜欢
  • 1970-01-01
  • 2017-06-02
  • 2013-01-08
  • 2021-10-13
  • 1970-01-01
  • 2019-10-30
  • 1970-01-01
  • 2015-10-03
  • 2017-03-10
相关资源
最近更新 更多