【问题标题】:How to properly initialize time with localtime in c++?如何在 C++ 中使用 localtime 正确初始化时间?
【发布时间】:2021-03-01 02:27:12
【问题描述】:

我得到了 Epoch 的开始,我应该得到当前时间:

date.hpp

#ifndef DATE_HPP
#define DATE_HPP

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

class Date
{
    std::stringstream format;
    struct tm *date_tm;
    time_t date;

public:
    Date() : date(time(NULL)), date_tm(localtime(&date)) {}
    Date(std::istream &in);
    Date(std::string str);

    const std::string getDate();
};

#endif //DATE_HPP

日期.cpp

#include "date.hpp"
#include <iostream>
#include <sstream>
#include <iomanip>

Date::Date(std::istream &in)
{
    std::cout << "enter date [mm/dd/yy]: ";
    format.basic_ios::rdbuf(in.rdbuf());
    format >> std::get_time(date_tm, "%m/%d/%y");
}

Date::Date(std::string str)
{
    format << str;
    format >> std::get_time(date_tm, "%m/%d/%y");
}

const std::string Date::getDate()
{
    format << std::put_time(date_tm, "%m/%d/%y");
    return format.str();
}

main.cpp

#include "date.hpp"
#include <iostream>

int main()
{
    Date now;
    std::cout << now.getDate() << std::endl;
}

当我运行它./a.out 时,我得到01/01/70。很明显,我希望当前时间,因为在 localtime(now) 中使用的 time(NULL) 应该包含从 Epoch 的秒数。那么可能出了什么问题呢?

【问题讨论】:

  • 打开编译器警告。此外,如果创建了多个实例,您的类将中断,因为localtime 本质上返回了一个指向全局的指针。
  • 考虑struct tm date_tm;(没有*)和*date_tm(localtime(&amp;date)(添加*
  • C++ 有chrono,这比time(NULL) 好得多。
  • 也许date(time(NULL)), date_tm(localtime(&amp;date)) 没有按顺序计算?
  • 编译器不需要按顺序评估默认 ctor 吗?

标签: c++ datetime localtime


【解决方案1】:

除了 cmets 中提到的缺陷(localtime() 返回指向全局的指针)之外,您还遇到了施工订单问题。

在您的类中,date_tm 被构造/初始化之前 date,无论它们在初始化列表中的顺序如何。

更改您的类定义以查看您期望的结果:

class Date
{
    std::stringstream format;
    time_t date;        // ensure date is constructed/initialized before date_tm
    struct tm *date_tm;

    // ...
}

(见:https://ideone.com/FRJrdB

如 cmets 中所述,如果您启用了适当的警告级别,编译器应该警告您。

【讨论】:

  • 什么是“指向全局的指针”,它与“指向本地的指针”有何不同?
  • 我认为,将指针声明为 inside 的类声明,不会使其成为全局
  • @milanHrabos,全局对象是localtime 的返回值所指向的对象,因此您的类成员也指向该对象。调用localtime 两次(或其他一些共享该状态的函数)可以在您仍然指向它时覆盖对象并返回相同的指针而不是返回指向新对象的指针。如果有帮助,您可以将localtime 实现视为类似于tm g_state; tm* localtime(const time_t* t) { g_state = calculate_local_time(t); return &amp;g_state; }
猜你喜欢
  • 2023-03-21
  • 1970-01-01
  • 1970-01-01
  • 2014-04-26
  • 1970-01-01
  • 1970-01-01
  • 2022-01-01
  • 2010-11-11
  • 1970-01-01
相关资源
最近更新 更多