Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/124.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从time\u t转换为tm然后再转换回time\u t时出现问题_C++_Mktime_Time.h_Time T - Fatal编程技术网

C++ 从time\u t转换为tm然后再转换回time\u t时出现问题

C++ 从time\u t转换为tm然后再转换回time\u t时出现问题,c++,mktime,time.h,time-t,C++,Mktime,Time.h,Time T,我的时间\u t值为1530173696,表示2018年6月28日星期四上午8:14:56 我想把时间四舍五入到最近的一小时。具体到1530172800,代表2018年6月28日星期四上午8:00:00。因此,我的想法是将这个time\u t转换为tm结构,然后将其sec和min值分配给0 但是,在我这样做之后,并且在我将修改后的tm转换回time\t值之后,我得到的值是非常不正确的。我得到的值为1530158400,表示2018年6月28日星期四上午4:00:00。休息4小时。即使检查高达8:

我的
时间\u t
值为
1530173696
,表示
2018年6月28日星期四上午8:14:56

我想把时间四舍五入到最近的一小时。具体到
1530172800
,代表
2018年6月28日星期四上午8:00:00
。因此,我的想法是将这个
time\u t
转换为
tm
结构,然后将其
sec
min
值分配给
0

但是,在我这样做之后,并且在我将修改后的
tm
转换回
time\t
值之后,我得到的值是非常不正确的。我得到的值为
1530158400
,表示
2018年6月28日星期四上午4:00:00
。休息4小时。即使检查高达
8:59:59 AM
的值,仍然会给出
4:00:00 AM
的向下舍入值

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

我不明白我做错了什么。谢谢你的帮助。谢谢

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

bool equalTMs(tm& tm1, tm& tm2);
void printTM(tm& myTM);

int main()
{
    tm myTM;
    time_t datetime = 1530173696;
    //datetime = 1530176399; // to check the time_t value of 8:59 AM
    gmtime_s(&myTM, &datetime);
    myTM.tm_sec = 0;
    myTM.tm_min = 0;
    time_t myTime_T = mktime(&myTM);

    tm sanityCheckTM;
    time_t roundedDownToNearestHour = 1530172800;
    gmtime_s(&sanityCheckTM, &roundedDownToNearestHour);
    time_t sanityCheckTimeT = mktime(&sanityCheckTM);

    std::cout << "datetime: " << datetime << std::endl;
    std::cout << "myTime_T: " << myTime_T << std::endl;
    std::cout << std::endl;
    std::cout << "roundedDownToNearestHour: " << roundedDownToNearestHour << std::endl;
    std::cout << "sanityCheckTimeT: " << sanityCheckTimeT << std::endl;
    std::cout << std::endl;
    std::cout << "myTM and sanityCheckTM equal? " << (equalTMs(myTM, sanityCheckTM) ? "true" : "false") << std::endl;

    std::cout << "\nmyTM:-\n\n";
    printTM(myTM);
    std::cout << "\nsanityCheckTM:-\n\n";
    printTM(sanityCheckTM);
    std::cout << "\n";

    time_t _time_t = 1530158400;
    tm _tm;
    gmtime_s(&_tm, &_time_t);
    std::cout << "_time_t: " << _time_t << std::endl;
    std::cout << "_tm and sanityCheckTM equal? " << (equalTMs(_tm, sanityCheckTM) ? "true" : "false") << std::endl;

    std::cout << "\n_tm:-\n\n";
    printTM(_tm);

}

void printTM(tm& myTM)
{
    std::cout << "tm_sec: " << myTM.tm_sec << std::endl;
    std::cout << "tm_min: " << myTM.tm_min << std::endl;
    std::cout << "tm_hour: " << myTM.tm_hour << std::endl;
    std::cout << "tm_mday: " << myTM.tm_mday << std::endl;
    std::cout << "tm_mon: " << myTM.tm_mon << std::endl;
    std::cout << "tm_year: " << myTM.tm_year << std::endl;
    std::cout << "tm_wday: " << myTM.tm_wday << std::endl;
    std::cout << "tm_yday: " << myTM.tm_yday << std::endl;
    std::cout << "tm_isdst: " << myTM.tm_isdst << std::endl;
}

bool equalTMs(tm& tm1, tm& tm2)
{
    return (tm1.tm_sec == tm2.tm_sec)
        && (tm1.tm_min == tm2.tm_min)
        && (tm1.tm_hour == tm2.tm_hour)
        && (tm1.tm_mday == tm2.tm_mday)
        && (tm1.tm_mon == tm2.tm_mon)
        && (tm1.tm_year == tm2.tm_year)
        && (tm1.tm_wday == tm2.tm_wday)
        && (tm1.tm_yday == tm2.tm_yday)
        && (tm1.tm_isdst == tm2.tm_isdst);
}
#包括
#包括
布尔等式(tm&tm1、tm&tm2);
void printTM(tm&myTM);
int main()
{
tm-myTM;
时间=1530173696;
//datetime=1530176399;//检查上午8:59的时间值
gmtime_s(&myTM,&datetime);
myTM.tm_秒=0;
myTM.tm_min=0;
时间\u t我的时间\u t=mktime(&myTM);
tm卫生检查;
四舍五入下至最近一小时的时间=1530172800;
gmtime(和卫生检查,和四舍五入下周一小时);
时间\u t SANITYCHECKTIME=mktime(&sanityCheckTM);
std::cout
gmtime_s()
返回一个
tm
,它以UTC时间表示。您将其传递给
mktime()
,它希望
tm
以当地时间表示。您的StackOverflow档案显示您位于阿布扎比,其时区为GMT+4。这就是您存在4小时差异的原因

使用
localtime\u s()
而不是
gmtime\u s()
gmtime\u s()
返回一个
tm
,该值以UTC时间表示。您将其传递给
mktime()
,它希望
tm
以当地时间表示。您的StackOverflow档案显示您位于阿布扎比,其时区为GMT+4。这就是您存在4小时差异的原因


使用
localtime_s()
而不是
gmtime_s()

因为
1530173696
被用作一个(UTC不包括闰秒),这可以在不涉及时区的情况下解决

可用于解决此问题,并检查您是否得到正确答案。但是,如果您想了解如何在不使用任何库的情况下非常简单地执行此操作,请跳到此答案的末尾

1530173696
是自1970-01-01 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';
}
这只会验证输入。此外,
tp
只不过是一个基于
系统时钟的
std::chrono::time\u点
,但精度为
。您可以通过以下方法将其四舍五入到小时:

tp = floor<std::chrono::hours>(tp);
(根据需要)。要将其转换回时间,只需提取持续时间,然后提取计数:

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

最后,如果您不需要以可读的形式打印这些时间戳,您可以自己轻松计算:

time_t myTime_T = datetime / 3600 * 3600;
这与以下操作基本相同:

tp = floor<std::chrono::hours>(tp);
tp=楼层(tp);

除了当输入为负(UTC 1970-01-01 00:00:00:00之前的时间戳)时,
地板
版本将继续获得正确答案。当输入为负时,“手动”实现将在下一个小时进行取整。

因为
1530173696
被用作一个(UTC不包括闰秒),这可以在不涉及时区的情况下解决

可用于解决此问题,并检查您是否得到正确答案。但是,如果您想了解如何在不使用任何库的情况下非常简单地执行此操作,请跳到此答案的末尾

1530173696
是自1970-01-01 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';
}
这只会验证输入。此外,
tp
只不过是一个基于
系统时钟的
std::chrono::time\u点
,但精度为
。您可以通过以下方法将其四舍五入到小时:

tp = floor<std::chrono::hours>(tp);
(根据需要)。要将其转换回时间,只需提取持续时间,然后提取计数:

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

最后,如果您不需要以可读的形式打印这些时间戳,您可以自己轻松计算:

time_t myTime_T = datetime / 3600 * 3600;
这与以下操作基本相同:

tp = floor<std::chrono::hours>(tp);
tp=楼层(tp);

除了当输入为负数时(
floor
版本将继续获得正确答案(UTC 1970-01-01 00:00:00之前的时间戳)。“手册”当给出否定输入时,执行将在下一个小时结束。

这非常有效,而且很有意义。非常感谢。请对我的问题进行投票。这非常有效,很有意义。非常感谢。请对我的问题进行投票。