mktime() 给出的结果与 Howard Hinnant 的日期库(基于 std::chrono)不同
mktime() gives different results than Howard Hinnant's date library (std::chrono based)
我正在使用 Howard Hinnant 的日期 C++ 库 (https://howardhinnant.github.io/date/date.html),但我在使用它时遇到了一些困惑。下面是我使用此库打印 2017 年 11 月第 3 个星期五的年月日的程序。date::year_month_weekday
class 与 date::sys_days()
一起使用时显示正确的日期(Nov 17, 2017),但是当我用std::chrono::system_clock::to_time_t
转换成struct tm
的时候,这个tm
中存储的结果变成了Nov 16, 2017。我测试了其他情况,好像是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
Howard Hinnant's date.h tracks Unix Time which for most practical purposes is UTC. At this same GitHub repository there is also a timezone library 如果您需要处理本地时间,或 UTC 以外的任何时区。
所以是的,正如 Freddie Chopin 在评论中指出的那样,您正在看到 localtime_r
将计算机的本地时区考虑在内的影响。
您可以根据需要将一天中的任何时间添加到 sys_days
。 sys_days
是 std::chrono::time_point
,但精度为 days
。所以一旦你有了 sys_days
,你现在实际上是在 <chrono>
库中,而不是日期库:
system_clock::time_point t = date::sys_days(dmwd) + 6h + 53min + 4s + 123us:
我正在使用 Howard Hinnant 的日期 C++ 库 (https://howardhinnant.github.io/date/date.html),但我在使用它时遇到了一些困惑。下面是我使用此库打印 2017 年 11 月第 3 个星期五的年月日的程序。date::year_month_weekday
class 与 date::sys_days()
一起使用时显示正确的日期(Nov 17, 2017),但是当我用std::chrono::system_clock::to_time_t
转换成struct tm
的时候,这个tm
中存储的结果变成了Nov 16, 2017。我测试了其他情况,好像是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
Howard Hinnant's date.h tracks Unix Time which for most practical purposes is UTC. At this same GitHub repository there is also a timezone library 如果您需要处理本地时间,或 UTC 以外的任何时区。
所以是的,正如 Freddie Chopin 在评论中指出的那样,您正在看到 localtime_r
将计算机的本地时区考虑在内的影响。
您可以根据需要将一天中的任何时间添加到 sys_days
。 sys_days
是 std::chrono::time_point
,但精度为 days
。所以一旦你有了 sys_days
,你现在实际上是在 <chrono>
库中,而不是日期库:
system_clock::time_point t = date::sys_days(dmwd) + 6h + 53min + 4s + 123us: