簡體   English   中英

從 struct tm 轉換為 std::time_t 並轉換回日期將被更改

[英]convert from struct tm to std::time_t and convert back date will be changed

我嘗試使用以下示例代碼從 struct tm 轉換為 std::time_t:

void test_time_t() {
    tm time;
    time.tm_year = 2004-1900;
    time.tm_mon = 11;
    time.tm_mday = 5;
    time.tm_hour = 12;
    time.tm_min = 2;
    char buff[25];
    strftime(buff, 20, "%Y %b %d %H:%M",&time);
    printf("%s\n",buff);
    auto t = std::mktime(&time);
    struct tm *tmp = localtime(&t);
    strftime(buff, 20, "%Y %b %d %H:%M",tmp);
    printf("%s\n",buff);
}

這將是 output:

2004 Dec 05 12:02
2005 Jun 16 22:41

日期已更改,有人可以告訴我我在這里做錯了什么嗎? 我認為時區不會導致日期如此不同

您需要初始化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(&copy);
    }

    // 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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM