需要导入以下头文件
cpp
#include <chrono>
#include <ctime>
#include <iomanip>
#include <iostream>
#include <ratio>
#include <sstream>
1.将日期字符串转换为时间点对象
按 std::get_time 格式串解析本地日期时间,并转换为 system_clock 时间点。
关键代码
std::get_time(&calendar_time, date_format.c_str());
cpp
// 按 std::get_time 格式串解析本地日期时间,并转换为 system_clock 时间点。
std::chrono::system_clock::time_point date_string_to_time_point(
const std::string &date_string, const std::string &date_format) {
// 未指定日期时默认使用每月 1 日,未指定时间时默认为 00:00:00。
std::tm calendar_time = {};
calendar_time.tm_mday = 1;
std::istringstream date_stream{ date_string };
date_stream >> std::get_time(&calendar_time, date_format.c_str());
// 要求格式串成功解析整个输入,避免忽略尾部多余字符。
if (date_stream.fail() || date_stream.peek() != std::char_traits<char>::eof()) {
throw std::invalid_argument("date string does not match the given format");
}
// 保存解析结果;mktime 会规范化 tm,之后用原值检查日期时间是否合法。
const int expected_year = calendar_time.tm_year;
const int expected_month = calendar_time.tm_mon;
const int expected_day = calendar_time.tm_mday;
const int expected_hour = calendar_time.tm_hour;
const int expected_minute = calendar_time.tm_min;
const int expected_second = calendar_time.tm_sec;
// 由运行库根据本地时区确定夏令时状态;日期时间按本地时间解释。
calendar_time.tm_isdst = -1;
const std::time_t timestamp = std::mktime(&calendar_time);
if (timestamp == static_cast<std::time_t>(-1) || calendar_time.tm_year != expected_year ||
calendar_time.tm_mon != expected_month || calendar_time.tm_mday != expected_day ||
calendar_time.tm_hour != expected_hour || calendar_time.tm_min != expected_minute ||
calendar_time.tm_sec != expected_second) {
throw std::invalid_argument("date string is not a valid local date/time");
}
// 将本地日历时间对应的 time_t 转换为 system_clock 时间点。
return std::chrono::system_clock::from_time_t(timestamp);
}
2.将时间点对象转换为日期字符串
按 std::put_time 格式串将 system_clock 时间点转换为本地日期时间字符串。
关键代码
std::put_time(calendar_time, date_format.c_str());
cpp
// 按 std::put_time 格式串将 system_clock 时间点转换为本地日期时间字符串。
std::string time_point_to_date_string(
const std::chrono::system_clock::time_point &time_point, const std::string &date_format) {
const std::time_t timestamp = std::chrono::system_clock::to_time_t(time_point);
const std::tm *calendar_time = std::localtime(×tamp);
if (calendar_time == nullptr) {
throw std::runtime_error("time point cannot be represented as local time");
}
std::ostringstream date_stream;
date_stream << std::put_time(calendar_time, date_format.c_str());
if (date_stream.fail()) {
throw std::runtime_error("date format could not be applied");
}
return date_stream.str();
}
3.计算时间点间隔
cpp
// 将两个同一时钟的时间点之差转换为 Unit;Rep 控制结果类型及小数是否保留。
template <typename Rep, typename Clock, typename Duration1, typename Duration2, typename Unit>
Rep calculate_time_distance(const std::chrono::time_point<Clock, Duration1> &first_time,
const std::chrono::time_point<Clock, Duration2> &second_time, Unit) {
// 使用目标单位的周期和指定的 Rep 构造结果 duration,再读取其计数。
typedef std::chrono::duration<Rep, typename Unit::period> ResultDuration;
return std::chrono::duration_cast<ResultDuration>(second_time - first_time).count();
}
4.测试
cpp
const std::string date1_str = "2026/01/01 00:00:00";
const std::string date2_str = "2026/01/01 01:12:13";
const std::string date_format_str = "%Y/%m/%d %H:%M:%S";
const std::string other_date_format_str = "%Y-%m-%d %H:%M:%S";
// 测试字符串转换为时间点
const std::chrono::system_clock::time_point date1 =
date_string_to_time_point(date1_str, date_format_str);
// 测试时间点转换为字符串
const std::string formated_date1_str =
time_point_to_date_string(date1, other_date_format_str);
std::cout << "Formatted date1: " << formated_date1_str
<< "\n"; // Formatted date1: 2026-01-01 00:00:00
const std::chrono::system_clock::time_point date2 =
date_string_to_time_point(date2_str, date_format_str);
const std::string formated_date2_str =
time_point_to_date_string(date2, other_date_format_str);
std::cout << "Formatted date1: " << formated_date2_str
<< "\n"; // Formatted date1: 2026-01-01 01:12:13
// 测试计算时间点间隔
double distance_hour_float =
calculate_time_distance<double>(date1, date2, std::chrono::hours{ 1 });
std::cout << "Time distance (floating hours): " << distance_hour_float
<< " hours\n"; // Time distance (floating hours): 1.20361 hours
double distance_minute_float =
calculate_time_distance<double>(date1, date2, std::chrono::minutes{ 1 });
std::cout << "Time distance (floating minutes): " << distance_minute_float
<< " minutes\n"; // Time distance (floating minutes): 72.2167 minutes
double distance_second_float =
calculate_time_distance<double>(date1, date2, std::chrono::seconds{ 1 });
std::cout << "Time distance (floating seconds): " << distance_second_float
<< " seconds\n"; // Time distance (floating seconds): 4333 seconds