你需要初始化你的time:
tm time{}; // zero-initialized
“我只是忘记了 tm 是一个 C 结构。”
这很常见。但是,您可以继承 std::tm 并在代码中使用您自己的类型。
struct tm_ext : std::tm {
tm_ext() : std::tm{} {}; // zero initialize on default construction
};
您现在可以使用tm_ext 而不会错过初始化:
tm_ext time; // now fine
当您使用它时,您甚至可以为其添加一些其他便利功能。
struct tm_ext : std::tm {
tm_ext() : std::tm{} {}; // zero initialize on default construction
explicit tm_ext(int year, int mon = 1, int mday = 1, int hour = 0,
int min = 0, int sec = 0, int isdst = 0) :
tm_ext() // delegate to default constructor
{
tm_year = year - 1900;
tm_mon = mon - 1;
tm_mday = mday;
tm_hour = hour;
tm_min = min;
tm_sec = sec;
// A negative value of tm_isdst causes mktime to attempt to determine if
// Daylight Saving Time was in effect.
tm_isdst = isdst;
errno = 0;
if(std::mktime(this) == -1 && errno != 0) {
throw std::runtime_error("mktime failed");
}
}
tm_ext(const std::tm& t) : std::tm(t) {} // conversion ctor
operator std::time_t () const { // implicit conversion to time_t
tm_ext copy(*this);
errno = 0;
return std::mktime(©);
}
// implicit conversion to a pointer - perhaps an exaggeration
operator const tm_ext* () const { return this; }
bool set_localtime(const std::time_t& t) {
std::tm* tmp = std::localtime(&t);
if(not tmp) return false;
*this = *tmp;
return true;
}
bool set_utc(const std::time_t& t) {
std::tm* tmp = std::gmtime(&t);
if(not tmp) return false;
*this = *tmp;
return true;
}
};
并使用它:
void test_time_t() {
tm_ext time(2004, 12, 5, 12, 2); // use real world values
char buff[25];
// implicit conversion to a const tm_ext* below:
strftime(buff, 20, "%Y %b %d %H:%M", time);
printf("%s\n",buff);
std::time_t t = time; // implicit conversion from tm_ext to time_t
tm_ext tmp;
if(tmp.set_localtime(t)) std::cout << "successfully set localtime\n";
// implicit conversion to a const tm_ext* below:
strftime(buff, 20, "%Y %b %d %H:%M", tmp);
printf("%s\n",buff);
}
不过,在过火之前,不妨先看看 Howard Hinnant 的 date.h。