Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/143.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/57.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++ 转换为unix时间戳不正确_C++_C_Unix Timestamp_Gmt_Mktime - Fatal编程技术网

C++ 转换为unix时间戳不正确

C++ 转换为unix时间戳不正确,c++,c,unix-timestamp,gmt,mktime,C++,C,Unix Timestamp,Gmt,Mktime,我有一个我写的函数(如果有一个好的标准替代品,请让我知道…) time\u-t-get\u-unix\u-time(字符串时间){ 时间与地点时间; 时间(&loctime); 结构tm*给定时间; time_str=time_str.substr(0,time_str.find_first_of('.'); 替换(time_str.begin(),time_str.end(),':',','); 替换(time_str.begin(),time_str.end(),“-”,“,”); 替换(t

我有一个我写的函数(如果有一个好的标准替代品,请让我知道…)

time\u-t-get\u-unix\u-time(字符串时间){
时间与地点时间;
时间(&loctime);
结构tm*给定时间;
time_str=time_str.substr(0,time_str.find_first_of('.');
替换(time_str.begin(),time_str.end(),':',',');
替换(time_str.begin(),time_str.end(),“-”,“,”);
替换(time_str.begin(),time_str.end(),“/”,“,”);
替换(time_str.begin(),time_str.end(),“,”);
给定时间=本地时间(&loctime);
vector trecord=拆分字符串(时间字符串',');
给定时间->tm\u year=atoi(trecord.at(0.c\u str())-1900;
给定时间->tm\u mon=atoi(trecord.at(1).c\u str())-1;
给定时间->tm_mday=atoi(trecord.at(2.c_str());
给定时间->tm_hour=atoi(trecord.at(3.c_str());
给定时间->tm_min=atoi(trecord.at(4.c_str());
给定时间->tm_sec=atoi(trecord.at(5.c_str());
返回mktime(给定的时间);
}
函数的输入(time_str)格式为1970-01-01 00:00:00.0。函数的作用是:将字符串
time\u str
拆分为包含以下内容的向量:

{1970,01,01,00,00,00}

用于填充给定的时间结构

我编写了一个函数来测试它,并准确地传递了该输入(新纪元的开始)。但是,它返回给我的时间是21600,即1970-01-01 06:00:00,或者UTC+6。预期输出为0(纪元开始)

注意:我在美国中部时区,即UTC-6。1970年1月1日午夜,UTC时间为1970年1月1日06:00:00


我的函数中是否有任何东西使其特定于我的时区?我是否在这个函数中做了一些错误的事情,或者我可以做一些不同的事情来使它独立于时区,或者至少总是UTC。

也许你应该使用
gmtime
而不是
time
,来摆脱时区问题

编辑: 我真的不明白为什么要用当前时间填充结构,然后覆盖它的所有组件。为什么不只是:

time_t get_unix_time(const string& time_str)
{
    vector<string> trecord = split_string(time_str, ',');

    tm given_time;
    given_time.tm_year = atoi(trecord.at(0).c_str()) - 1900;
    given_time.tm_mon  = atoi(trecord.at(1).c_str()) - 1;
    given_time.tm_mday = atoi(trecord.at(2).c_str());
    given_time.tm_hour = atoi(trecord.at(3).c_str());
    given_time.tm_min  = atoi(trecord.at(4).c_str());
    given_time.tm_sec  = atoi(trecord.at(5).c_str());

    return mktime(&given_time);
}
time\u t get\u unix\u time(常量字符串和时间字符串)
{
vector trecord=拆分字符串(时间字符串',');
给定的时间;
给定_time.tm_year=atoi(trecord.at(0.c_str())-1900;
给定_time.tm_mon=atoi(trecord.at(1.c_str())-1;
给定_time.tm_mday=atoi(trecord.at(2.c_str());
给定_time.tm_hour=atoi(trecord.at(3.c_str());
给定_time.tm_min=atoi(trecord.at(4.c_str());
给定_time.tm_sec=atoi(trecord.at(5.c_str());
返回mktime(给定时间(&U);
}
另一次编辑:


呃,
mktime
也考虑当地时间。除了将时区区域设置设置为UTC之外,我真的不知道如何解决这个问题。

调用mktime时,它会将参数解释为本地时间。
您还使用了类似“localtime”的函数,这似乎是无用的,我认为您可以放弃它们。

如果您正在使用,您可以使用
timegm
函数,它是
mktime
的一个版本,总是将时间解释为在
GMT
时区中。不幸的是,该函数的文档基本上说明了它不能用标准库调用来实现。因此,除非你拥有它,否则你会有点运气不佳。

mktime
在本地时区内花费一段时间。因此,如果您将其传递给当地时间1970-01-01 00:00:00,它将返回UTC时间1970-01-01 06:00:00,这是它应该返回的

另一种选择是,如果您使用glibc,您可以调用。如果您没有使用glibc,则在调用mktime时,通过使用TZ环境变量临时将本地时间更改为UTC,如timegm手册页所述:

time_t my_timegm (struct tm *tm) {
    time_t ret;
    char *tz;
    tz = getenv("TZ");
    setenv("TZ", "", 1);
    tzset();
    ret = mktime(tm);
    if (tz)
        setenv("TZ", tz, 1);
    else
        unsetenv("TZ");
    tzset();
    return ret;
}


另外,您对
localtime
的调用是不必要的,您可能应该设置
gived\u time->tm\u isdst
,以避免可能的夏令时问题。

您可以围绕
strtime
编写一个包装来进行解析

struct tm given_time;

strptime(time_str.c_str(), "%Y-%m-%d %H:%M:%S", &given_time);

return mktime(&given_time);

@Josh Kelley的回答彻底解释了时区问题。

只要避免这些笨拙的函数,自己计算就行了。POSIX指定
time\u t
是一种自“大纪元”(1970-01-01 00:00:00 GMT)以来以秒为单位的算术类型,没有任何闰秒的废话(所有的日子都是86400日历秒,与SI秒相差很小),因此除了一点闰年逻辑之外,计算非常简单

像这样的日历计算是一个标准的编程入门练习,所以我相信你可以在网上找到解决方案


另一方面,ISO C和POSIX省略此函数的原因可能是,与涉及时区的转换不同,时区可以任意复杂,并且只有主机库才能在不同的应用程序之间可靠且一致地执行转换,GMT转换是纯算术的,没有外部参数。

,我不能使用boost库或任何其他库。我只能使用标准C++的东西。C++库中的时区处理是相当模糊的。如果您在启动程序时将环境变量
TZ
设置为
UTC
的值,则此代码段将起作用。mktime将给定时间解释为本地时间。因此,如果您给出1970-01-01 00:00:00,它将在您的本地时间,因此mktime将返回UTC-0时间,即1970-01-01 06:00:00-替换当前时间并替换为我需要的时间并不是真正的问题。我尝试了你的函数,它仍然给我21600而不是0。21600 is=UTC+6。@Sagar:“呃,mktime也考虑本地时间。除了将时区区域设置为UTC之外,我真的不知道如何解决这个问题。”你这样做了吗?还是你只是把代码放进去,不做任何改变,然后抱着最好的希望?不幸的是
struct tm given_time;

strptime(time_str.c_str(), "%Y-%m-%d %H:%M:%S", &given_time);

return mktime(&given_time);