将持续时间添加到时间点没有效果
adding duration to time point has no effect
我试图解决的问题由 day
、month
和 year
以及 days_to_add
给出了日期,将 days_to_add
添加到给定的日期。
我能够将日期转换为 std::chrono::time_point<system_clock, ...>
。现在我想给它添加给定的天数:
template <typename Clock, typename Duration>
auto add_days(const std::chrono::time_point<Clock, Duration>& timepoint,
int days_to_add)
{
constexpr unsigned int seconds_in_day = 60 * 60 * 24;
// mm hh dd
return timepoint + Duration(seconds_in_day * days_to_add);
}
但结果没有改变timepoint
。这是要重现的完整程序:
#include <iostream>
#include <chrono>
#include <iomanip>
template <typename Clock, typename Duration>
std::ostream& operator<<(std::ostream& os, const std::chrono::time_point<Clock, Duration>& timep)
{
auto converted_timep = Clock::to_time_t(timep);
os << std::put_time(std::localtime(&converted_timep), "%Y %b %d %H:%M:%S");
return os;
}
template <typename Clock, typename Duration>
auto add_days(const std::chrono::time_point<Clock, Duration>& timepoint,
int days_to_add)
{
constexpr unsigned int seconds_in_day = 60 * 60 * 24;
// mm hh dd
return timepoint + Duration(seconds_in_day * days_to_add);
}
int main()
{
auto today = std::chrono::system_clock::now();
auto tomorrow = add_days(today, 1);
std::cout << tomorrow;
return 0;
}
2017 Jun 17 16:23:18
2017 Jun 17 16:23:18
问题是 std::system_clock
不以秒或毫秒为单位存储时间。你认为微秒吗?没有。它以纳秒为单位存储时间(至少在 gcc 上,您似乎也在使用它)!实际上,时间是实现定义的,所以最好使用像这里最后一个这样的便携式解决方案。
你以为时间点没有变化,其实是变化的,只不过时间尺度比毫秒还小
如果你计算一天的纳秒数,你会得到正确答案:
template <typename Clock, typename Duration>
auto add_days(const std::chrono::time_point<Clock, Duration>& timepoint,
int days_to_add)
{
constexpr auto nano_seconds_in_day = 1'000'000'000ul * 60 * 60 * 24;
// (ns in s) mm hh dd
return timepoint + Duration(nano_seconds_in_day * days_to_add);
}
但这只有在您经过 std::system_clock
的时间点时才有效。其他时钟可以有不同的 duration
,因此需要添加不同的值。你应该改用这个版本(也更清晰):
<typename Clock, typename Duration>
auto add_days(const std::chrono::time_point<Clock, Duration>& timepoint,
int days_to_add)
{
return timepoint + 24h * days_to_add;
}
我试图解决的问题由 day
、month
和 year
以及 days_to_add
给出了日期,将 days_to_add
添加到给定的日期。
我能够将日期转换为 std::chrono::time_point<system_clock, ...>
。现在我想给它添加给定的天数:
template <typename Clock, typename Duration>
auto add_days(const std::chrono::time_point<Clock, Duration>& timepoint,
int days_to_add)
{
constexpr unsigned int seconds_in_day = 60 * 60 * 24;
// mm hh dd
return timepoint + Duration(seconds_in_day * days_to_add);
}
但结果没有改变timepoint
。这是要重现的完整程序:
#include <iostream>
#include <chrono>
#include <iomanip>
template <typename Clock, typename Duration>
std::ostream& operator<<(std::ostream& os, const std::chrono::time_point<Clock, Duration>& timep)
{
auto converted_timep = Clock::to_time_t(timep);
os << std::put_time(std::localtime(&converted_timep), "%Y %b %d %H:%M:%S");
return os;
}
template <typename Clock, typename Duration>
auto add_days(const std::chrono::time_point<Clock, Duration>& timepoint,
int days_to_add)
{
constexpr unsigned int seconds_in_day = 60 * 60 * 24;
// mm hh dd
return timepoint + Duration(seconds_in_day * days_to_add);
}
int main()
{
auto today = std::chrono::system_clock::now();
auto tomorrow = add_days(today, 1);
std::cout << tomorrow;
return 0;
}
2017 Jun 17 16:23:18
2017 Jun 17 16:23:18
问题是 std::system_clock
不以秒或毫秒为单位存储时间。你认为微秒吗?没有。它以纳秒为单位存储时间(至少在 gcc 上,您似乎也在使用它)!实际上,时间是实现定义的,所以最好使用像这里最后一个这样的便携式解决方案。
你以为时间点没有变化,其实是变化的,只不过时间尺度比毫秒还小
如果你计算一天的纳秒数,你会得到正确答案:
template <typename Clock, typename Duration>
auto add_days(const std::chrono::time_point<Clock, Duration>& timepoint,
int days_to_add)
{
constexpr auto nano_seconds_in_day = 1'000'000'000ul * 60 * 60 * 24;
// (ns in s) mm hh dd
return timepoint + Duration(nano_seconds_in_day * days_to_add);
}
但这只有在您经过 std::system_clock
的时间点时才有效。其他时钟可以有不同的 duration
,因此需要添加不同的值。你应该改用这个版本(也更清晰):
<typename Clock, typename Duration>
auto add_days(const std::chrono::time_point<Clock, Duration>& timepoint,
int days_to_add)
{
return timepoint + 24h * days_to_add;
}