This答案显示如何将字符串解析为std::chrono::time_point
,如下所示:
std::tm tm = {};
std::stringstream ss("Jan 9 2014 12:35:34");
ss >> std::get_time(&tm, "%b %d %Y %H:%M:%S");
auto tp = std::chrono::system_clock::from_time_t(std::mktime(&tm));
如果我想从一个(格里高利历)日历日期创建一个std::chrono::time_point
,该日历日期的年,月,日是编译时已知的,那么还有什么比从字符串中解析为更简单的方法了:以上建议?
答案 0 :(得分:4)
是的,您可以在编译时进行整个计算,使用Howard Hinnant's date/time library创建一个constexpr system_clock::time_point
。
#include "date/date.h"
#include <chrono>
int
main()
{
using namespace date;
using namespace std::chrono;
constexpr system_clock::time_point tp = sys_days{January/9/2014} + 12h + 35min + 34s;
static_assert(tp == system_clock::time_point{1389270934s}, "");
}
这是假定日期/时间为UTC。如果不是,则必须手动添加/减去UTC偏移量。由于时区规则一直在政治家的追捧下发生变化,因此将其设为constexpr
的希望很小。当误解暴露时,甚至历史时区规则也会更新。
此外,该程序还将通过删除#include "date/date.h"
和using namespace date;
移植到C ++ 20。同样,使用Howard Hinnant's date/time library也需要C ++ 14 constexpr
的肌肉。 C ++ 11 constexpr
是不够的(但是您可以在运行时删除constexpr
和static_assert
来做到这一点。)
答案 1 :(得分:3)
如果您使用的是c ++ 20,或者将使用Howard Hinnant日期/时间库,那么Howard Hannant的答案会更好,因为它为您提供了一个constexpr time_point。
但是,如果还没有c ++ 20并想避免添加更多的外部库,那么此答案仍然有用。
您可以在初始化程序中分别设置std::tm
的成员,以避免解析字符串。
// 9th January, 2014
#define DAY 9
#define MONTH 1
#define YEAR 2014
std::tm tm = { .tm_sec = 0,
.tm_min = 0,
.tm_hour = 0,
.tm_mday = (DAY),
.tm_mon = (MONTH) - 1,
.tm_year = (YEAR) - 1900,
};
tm.tm_isdst = -1; // Use DST value from local time zone
auto tp = std::chrono::system_clock::from_time_t(std::mktime(&tm));
仅由于gcc对C ++代码中非平凡指定的初始化程序的限制,才对一天中的零字段进行初始化,并且如果希望在已编译日期的午夜进行,则可以省略。
请注意,mktime
会将tm
解释为当地时间,而不是GMT或UTC。如果tm_isdst
未设置为-1,则它将是本地标准时间,即使在本地时区中指定的时间使用夏令时(夏季时间)。
从std::tm
生成UTC时间点(与您的示例共享的一个问题)在其他问题中得到了解决,例如Easy way to convert a struct tm (expressed in UTC) to time_t type
答案 2 :(得分:0)
这适用于C ++ 11及更高版本:
#include <chrono>
std::chrono::system_clock::time_point
createDateTime(int year,
int month,
int day,
int hour,
int minute,
int second) // these are UTC values
{
tm timeinfo1 = tm();
timeinfo1.tm_year = year - 1900;
timeinfo1.tm_mon = month - 1;
timeinfo1.tm_mday = day;
timeinfo1.tm_hour = hour;
timeinfo1.tm_min = minute;
timeinfo1.tm_sec = second;
tm timeinfo = timeinfo1;
time_t tt = toUTC(timeinfo);
return std::chrono::system_clock::from_time_t(tt);
}
time_t toUTC(std::tm& timeinfo)
{
#ifdef _WIN32
std::time_t tt = _mkgmtime(&timeinfo);
#else
time_t tt = timegm(&timeinfo);
#endif
return tt;
}