【问题标题】:Convert date to unix time stamp in c++在 C++ 中将日期转换为 unix 时间戳
【发布时间】:2014-03-07 21:26:33
【问题描述】:

正如一些转换这些 un​​ix 时间戳的网站所说,

2013/05/07 05:01:00 (yyyy/mm/dd, hh:mm:ss) is 1367902860.

我在 C++ 中执行此操作的方式,印章与日期不同。 代码如下:

time_t rawtime;
struct tm * timeinfo;

int year=2013, month=5, day=7, hour = 5, min = 1, sec = 0;

/* get current timeinfo: */
time ( &rawtime ); //or: rawtime = time(0);
/* convert to struct: */
timeinfo = localtime ( &rawtime ); 

/* now modify the timeinfo to the given date: */
timeinfo->tm_year   = year - 1900;
timeinfo->tm_mon    = month - 1;    //months since January - [0,11]
timeinfo->tm_mday   = day;          //day of the month - [1,31] 
timeinfo->tm_hour   = hour;         //hours since midnight - [0,23]
timeinfo->tm_min    = min;          //minutes after the hour - [0,59]
timeinfo->tm_sec    = sec;          //seconds after the minute - [0,59]

/* call mktime: create unix time stamp from timeinfo struct */
date = mktime ( timeinfo );

printf ("Until the given date, since 1970/01/01 %i seconds have passed.\n", date);

生成的时间戳是

1367899260, but not 1367902860.

这里有什么问题?即使我更改为小时-1 或小时+1,它也不匹配。编辑:是的,如果我将 1 添加到小时,它会起作用。之前也加了 1 到分钟。

【问题讨论】:

    标签: c++ unix timestamp


    【解决方案1】:

    您必须使用 timegm() 而不是 mktime(),仅此而已。因为 mktime 是本地时间,timegm 是 UTC/GMT 时间。

    Converting Between Local Times and GMT/UTC in C/C++

    【讨论】:

    • C++ STL中没有timegm。
    • @mxmlnkn C++ STL 中有mktime(),有吗?!
    • @AlexisWilke 是的:mktimegmtimelocaltimectime,...当心 timegmgmtime
    【解决方案2】:

    你从哪里来有夏令时吗? tm::tm_isdst 参数是夏令时标志。这将根据您所在的位置和一年中的时间由本地时间调用填充,并且您不会重置它。因此,即使您和网页使用相同的时间,如果您设置了夏令时标志而网页没有设置,那么您最终会相差 1 小时。

    请注意,您实际上并不需要本地时间调用。您可以手动填写所有部分,因为 tm::tm_wday 和 tm::tm_yday 会被 mktime 忽略。查看http://www.cplusplus.com/reference/ctime/tm/http://www.cplusplus.com/reference/ctime/mktime/

    【讨论】:

      【解决方案3】:

      mktime()本地 日历时间转换为自纪元以来的时间作为 time_t 对象,因此如果您在不同的时区,您的结果将与网站的不同。该网站将2013/05/07 05:01:00 作为UTC 时间。我机器上的相同代码的结果为1367874060,距离网站价值有8小时的路程。我在 UTC+8:00 时区,所以我机器上的 mktime() 将输入 2013/05/07 05:01:00 作为 UTC+8:00 时间,从而导致差异。

      PS:localtime() 返回一个指向静态内部 struct tm 对象的指针。该结构可以在gmtime()localtime()ctime() 之间共享,并且可以在每次调用时被覆盖。因此,最好拥有自己的 struct tm 对象的本地副本。

      【讨论】:

        【解决方案4】:

        网站似乎假设时间是 UTC 时区,而您的计算机设置为其他时区。

        您可以调用gmtime 而不是localtime 来使用UTC;但我刚刚注意到,除了获取指向tm 的指针之外,您实际上并没有使用localtime 来做任何事情。你最好声明一个本地的tmlocaltime 使用的那个可以在你调用另一个时间库函数时被重用。

        很遗憾,mktime 没有使用 UTC 的标准变体。如果你想要 UTC,你的选择是:

        • 使用setenv("TZ", "", 1); 设置时区。请注意,这会影响整个程序,因此如果您还需要处理本地时间,可能会很尴尬。
        • 使用像 Boost.DateTime 这样的库,它在处理日期和时区方面比 C 库稍好。

        【讨论】:

        • 我已经改成timeinfo = gmtime ( &rawtime);,结果还是一样。
        • @user2366975:哦,是的,mktime 仍将假定为当地时间,并且它没有 UTC 版本。
        【解决方案5】:

        不要使用指向本地时间的指针。保存实际值

        struct tm timeinfo;
        ...
        timeinfo = *localtime(&rawtime);
        ...
        date = mktime(&timeinfo);
        

        您不知道使用本地时间返回的指针还有什么可能。 mktime 可能正在使用它。

        【讨论】:

        • 好主意,但它不会改变任何东西。
        猜你喜欢
        • 2019-04-24
        • 1970-01-01
        • 2020-10-19
        • 2020-12-23
        • 2016-04-24
        • 2012-07-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多