Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ruby-on-rails-3/4.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++ 如何正确使用localtime()?_C++ - Fatal编程技术网

C++ 如何正确使用localtime()?

C++ 如何正确使用localtime()?,c++,C++,在我的一个实用程序中,localtime()用于将unix时间戳转换为人类可读的日期时间 以下代码用于在VS2010中工作,但在VS2019中无法工作: std::string sec = "1234123456"; int nsec = atoi(sec.c_str()); tm* t = localtime((time_t*)&nsec); // return null pointer std::string sec = "1234123456"; int nsec = atoi(

在我的一个实用程序中,localtime()用于将unix时间戳转换为人类可读的日期时间

以下代码用于在VS2010中工作,但在VS2019中无法工作:

std::string sec = "1234123456";
int nsec = atoi(sec.c_str());
tm* t = localtime((time_t*)&nsec); // return null pointer
std::string sec = "1234123456";
int nsec = atoi(sec.c_str());
time_t tt = nsec;
tm* t = localtime(&tt); // works
如果我以以下方式更改代码,它也将在VS2019中工作:

std::string sec = "1234123456";
int nsec = atoi(sec.c_str());
tm* t = localtime((time_t*)&nsec); // return null pointer
std::string sec = "1234123456";
int nsec = atoi(sec.c_str());
time_t tt = nsec;
tm* t = localtime(&tt); // works
我不知道为什么需要额外的int-to-time转换,如果您有任何建议,我将不胜感激。

在大多数(如果不是所有)现代编译器上
时间现在是64位整数<因此,当您从一种指针类型转换到另一种指针类型时,code>(time_t*)&nsec
是未定义的行为

您的固定版本定义得很好,但您会遇到这样的原因,即
time\u t
现在是64位的,因为32位数字只适用于2038年之前的时间(假设
time\u t
使用Unix纪元)

<> P>不幸的是,C++没有提供一个简单的方法来转换<代码>字符串 >代码> TimeTyt,要正确地处理它,你需要这样的东西:

#include <iostream>
#include <charconv>

time_t str_to_time_t(const std::string& str)
{
    auto begin = str.c_str();
    auto end = begin + str.size();
    time_t time;
    auto result = std::from_chars(begin, end, time);
    if (result.ec != std::errc())
    {
        throw std::system_error(std::make_error_code(result.ec));
    }
    if (result.ptr != end)
    {
        throw std::invalid_argument("invalid time_t string");
    }
    return time;
}

int main()
{
    std::string sec = "1234123456";
    auto nsec = str_to_time_t(sec);
    tm* t = localtime((time_t*)&nsec);
    if (t)
    {
        std::cout << "parsed OK\n";
    }
}
#包括
#包括
时间长度到时间长度(常数标准::字符串和长度)
{
自动开始=str.c_str();
自动结束=开始+长度大小();
时间;
自动结果=std::from_chars(开始、结束、时间);
如果(result.ec!=std::errc())
{
抛出std::系统错误(std::生成错误代码(result.ec));
}
如果(result.ptr!=结束)
{
抛出std::无效的参数(“无效的时间字符串”);
}
返回时间;
}
int main()
{
std::string sec=“1234123456”;
自动nsec=str到时间(秒);
tm*t=localtime((time_t*)和nsec);
if(t)
{

std::cout可能
time\u t
现在是64位类型,因此使用
int
将不起作用。原始代码在不考虑实际类型的情况下使用直接强制转换是危险的。可能是因为
time\u t
实际上大于
int
,因此第一次强制转换将调用未定义的行为。也就是说,如果
time\t
是64位类型,那么在第一个示例中,您(不正确地)告诉C 4字节
int
就是其中之一。请注意,由于使用32位时间戳,您的代码在2038年后将失败。您读取了吗?稍后,您可以正确使用它。在Linux系统上读取并启用编译器中的所有警告