从time_t转换为tm然后返回time_t时出现问题

时间:2018-11-08 20:51:20

标签: c++ mktime time.h time-t

我有一个time_t的{​​{1}}值,代表1530173696

我想将时间四舍五入到最接近的小时。具体来说,下降到Thursday, June 28, 2018 8:14:56 AM,代表1530172800。因此,我的想法是将此Thursday, June 28, 2018 8:00:00 AM转换为time_t结构,然后将其tmsec的值分配给min

但是,在执行此操作之后,以及将修改后的0转换回tm值之后,我得到的值就消失了。我得到的值time_t代表1530158400。这是4个小时的休假。即使检查高达Thursday, June 28, 2018 4:00:00 AM的值,仍会得出8:59:59 AM的四舍五入值。

我写了下面的代码来演示这个问题。我使用VisulStudio 2017。

我不明白我在做什么错。感谢您的帮助。谢谢。

4:00:00 AM

2 个答案:

答案 0 :(得分:3)

gmtime_s()返回以{strong> UTC时间表示的tm。您将其传递给mktime(),后者希望tm LOCAL时间表示。您的StackOverflow个人资料显示您位于阿布扎比,时区为 GMT + 4 。这就是为什么您有4小时的差异。

使用localtime_s()代替gmtime_s()

答案 1 :(得分:0)

由于将1530173696用作Unix Time(UTC,leap秒除外),因此可以解决此问题,而无需涉及时区。

Howard Hinnant's date/time library可用于解决此问题,并检查您是否获得正确的答案。但是,如果您想了解如何非常简单地完全不使用任何库就可以做到这一点。

1530173696是自1970年1月1日UTC以来的秒数。如果要将其转换为人类可以理解的日期/时间,可以:

#include "date/date.h"
#include <iostream>

int
main()
{
    time_t datetime = 1530173696;
    date::sys_seconds tp{std::chrono::seconds{datetime}};
    using date::operator<<;
    std::cout << tp << '\n';
}

输出:

2018-06-28 08:14:56

除了验证输入外,什么都不做。此外,tp只是基于std::chrono::time_point的{​​{1}},而精度为system_clock。您可以使用以下方法将其舍入到小时:

seconds

此处tp = floor<std::chrono::hours>(tp); 可从floor下的"date.h"抓取,或者,如果您具有C ++ 17或更高版本,则可以使用namespace date。您可以使用std::chrono::floor再次打印"date.h",您将得到:

tp

(根据需要)。要将其转换回2018-06-28 08:00:00 ,只需提取time_t,然后提取duration

count

这将具有预期的值time_t myTime_T = tp.time_since_epoch().count();

最后,如果您不需要以易于阅读的形式打印这些时间戳,则可以自己轻松地进行数学运算:

1530172800

这与以下操作基本相同:

time_t myTime_T = datetime / 3600 * 3600;

除了tp = floor<std::chrono::hours>(tp); 版本将在输入为负时(1970年1月1日00:00:00 UTC之前的时间戳)继续得到正确的答案。如果输入为负,则“手动”实施会将向上舍入为下一小时。