如何在C++20计时器中向日期添加天数?
给定C++20中的新<chrono>
工具,如何向日期添加某些天数(例如n
)?
当我尝试执行此操作时,出现编译时错误:
auto d = July/4/2020;
auto d2 = d + days{5};
~ ^ ~~~~~~~
error: invalid operands to binary expression
('std::chrono::year_month_day' and 'std::chrono::days')
解决方案
<chrono>
中的日期只是一个以天为单位的时间点。和一个
日期时间仅为chrono::time_point
(通常基于
system_clock
),精度优于days
。和中的规范日期类型
<chrono>
为:
chrono::time_point<chrono::system_clock, chrono::days>
这只是一个days
-精度time_point
基于
system_clock
。这个特殊的time_point
也有一个便利
类型别名:sys_days
。
using sys_days = time_point<system_clock, days>;
因此,向sys_days
添加天数只需:
sys_days tp = ...;
tp += days{n};
// or
auto tp2 = tp + days{n};
如果只有一天,也可以:
++tp;
这是非常高效的,因为在引擎盖下,它只需添加两个
int
s.
如果time_point
具有比days
更精细的精度,则它仍然是
向其添加days
的步骤相同:
auto tp = system_clock::now() + days{n};
当我尝试执行此操作时,出现编译时错误:
上述变量auto d = July/4/2020; auto d2 = d + days{5}; ~ ^ ~~~~~~~ error: invalid operands to binary expression ('std::chrono::year_month_day' and 'std::chrono::days')
d
的类型为year_month_day
。即使year_month_day
在语义上等同于sys_days
,
它不直接支持days
精度运算。
year_month_day
是以天为单位的时间点(但不是
chrono::time_point
)。相反,它是{year, month, day}
数据
结构。您可以通过以下方式轻松地执行天精度算术
首先将其转换为sys_days
:
auto d = July/4/2020;
auto d2 = sys_days{d} + days{5};
在本例中,结果d2
的类型为sys_days
。如果您想要
结果为year_month_day
,然后只需将其转换回:
year_month_day d2 = sys_days{d} + days{5};
此设计的基本原理:
效率。从year_month_day
到sys_days
(和
Back)需要一点数字运算。这不是一个很大的数额。但
与单个整数加法相比,它很大。
<chrono>
库为year_month_day
提供了days
精度算法,
该算法将year_month_day
转换为sys_days
,
进行算术运算,然后将结果转换回
year_month_day
。如果您有很多days
-精度算术要
这样做,最好是只在sys_days
中进行流量,并转换为
year_month_day
仅在必要时(即当您需要获取
year
、month
或day
个字段)。
如果库提供year_month_day
的日精度算法,
客户会盲目使用它,没有意识到year_month_day
是
错误的数据结构,不适合他们的应用。这将类似于给予
std::list
索引运算符(这将非常容易完成):
template <class T, class A>
T&
list<T, A>::operator[](size_type i)
{
return *advance(begin(), i);
}
提供这样的API只会使编写起来过于简单,效率低下
密码。sys_days
是执行days
的首选数据结构
精确算术。
您需要使用它仍然不适用于我:
auto d = July/4/2020; auto d2 = sys_days{d} + day{5}; ~~~~~~~~~~~ ^ ~~~~~~ error: invalid operands to binary expression ('std::chrono::sys_days' and 'std::chrono::day')
days
,而不是day
。day
是日历说明符
用于民用日历中的某一月的某一天。days
是一个
chrono::duration
。有关更深入的信息,请参阅stack overflow Q/A
讨论这两个概念之间的区别。
如果我有一个year_month_day
,我想再增加几天 我知道到不了月底,我能做到吗? 转换为sys_days
,从而提高效率?
是。
auto d = July/4/2020;
auto d2 = d.year()/d.month()/(d.day() + days{5});
以上只是将d
的day
字段加5。没有
检查结果是否超过了这个月的最后一天。如果
它确实超过了该月的最后一天,该结果将被存储
在日期字段中(到第255天),d2.ok()
将返回false
。
year_month_day
适用于检索year
、month
或day
日期中的字段。它也适用于years
和months
精度日历算法。sys_days
适用于days
精度运算,并用于转换为更精细的精度
(a日期-时间)。
sys_days
可以相互转换,不需要
信息丢失。使用任何最有意义的数据结构。
如果您忘记了,编译器会提醒您,就像它为
vector
(否push_front
)、list
(无索引运算符)和
forward_list
(否size
)。
相关文章