mktime()给出的结果与Howard Hinnant的日期库(基于std :: chrono)不同

时间:2017-03-25 15:08:32

标签: c++ date chrono mktime

我正在使用Howard Hinnant的约会C ++库(https://howardhinnant.github.io/date/date.html),但我有一些使用它的混淆。以下是我使用此库打印2017年11月第3个星期五的年度月份的程序。date::year_month_weekday类与date::sys_days()一起使用时显示正确的日期(11月17日, 2017),但当我使用struct tm将其转换为std::chrono::system_clock::to_time_t时,此tm中存储的结果将于2017年11月16日结束。我测试了其他案例,似乎struct tm已转换从date::year_month_weekday始终落后一天。我在程序中遗漏了什么吗?该程序如下所示,编译它需要C ++ 11。

#include <iostream>
#include <chrono>
#include <sys/time.h>
#include "date.h"

using namespace std; 
using namespace std::chrono; 
using namespace date;

int main(int argc, char *argv[]) {  
    date::year y(2017);
    date::month m(11);
    date::weekday wd((unsigned)5);
    date::weekday_indexed wi(wd,3);
    date::year_month_weekday dmwd(y, m, wi);
    std::cout <<  date::sys_days(dmwd) << std::endl; //prints 2017-11-17, which is the 3rd Friday of Nov 2017

    time_t tt = std::chrono::system_clock::to_time_t(date::sys_days(dmwd));        
    struct tm tm1;
    localtime_r(&tt, &tm1);
    std::cout << "tm1.tm_year = " << tm1.tm_year << std::endl;
    std::cout << "tm1.tm_mon = " << tm1.tm_mon << std::endl;
    std::cout << "tm1.tm_mday = " << tm1.tm_mday << std::endl;  //prints 16 instead of 17, one day behind. tm.mday is from 1 to 31.

    return 0; 
}

该程序的输出如下

2017-11-17
tm1.tm_year = 117  <-- 117+1900=2017
tm1.tm_mon = 10    <-- tm_mon starts form 0, so 10 means November
tm1.tm_mday = 16  <-- tm_mday starts from 1, so 16 is the 16-th day in a month

1 个答案:

答案 0 :(得分:2)

Howard Hinnant's date.h跟踪Unix Time,其中大多数实际用途是UTC。如果您需要处理当地时间或UTC以外的任何时区,则同样GitHub repository还有timezone library

所以是的,正如Freddie Chopin在评论中指出的那样,你会看到localtime_r考虑计算机当地时区的影响。

您可以在sys_days添加所需的任何时间。 sys_daysstd::chrono::time_point,但精度为days。所以,一旦你有sys_days,你现在实际上在<chrono>库中,而不是日期库:

system_clock::time_point t = date::sys_days(dmwd) + 6h + 53min + 4s + 123us: