我想制作一个不输入任何内容并返回上一个星期一的日期的程序。 (我不在乎时区。我只担心公历)。我正在使用date by Howard Hinnant。这是我目前的操作方式:
#include <iostream>
#include <date/date.h>
int main() {
auto todays_day = date::year_month_weekday(date::floor<date::days>(std::chrono::system_clock::now()));
auto todays_date = date::floor<date::days>(std::chrono::system_clock::now());
int offset = 0;
auto weekday = todays_day.weekday();
if(weekday == date::Tuesday)
offset = 1;
else if (weekday == date::Wednesday)
offset = 2;
else if (weekday == date::Thursday)
offset = 3;
else if (weekday == date::Friday)
offset = 4;
else if (weekday == date::Saturday)
offset = 5;
else if (weekday == date::Sunday)
offset = 6;
auto lastMonday = date::year_month_day(todays_date - date::days(offset));
std::cout << lastMonday;
}
如果没有boost::previous_weekday,还有更好的方法吗? (不要求不使用boost。我只是想知道是否有可能)
答案 0 :(得分:5)
更简单地了解如何执行此操作的关键是了解有关Howard Hinnant's date library的这一事实:
weekday
的区别是圆形的(如果愿意,可以取模7)。也就是说,从任何weekday
减去任何weekday
都会导致days
的数量在[0,6]范围内。这样可以有效地隐藏weekday
的基础编码。
因此,无需将[周一,周日]转换为[0、6](或其他任何编码):
#include "date/date.h"
#include <iostream>
int
main()
{
auto todays_date = date::floor<date::days>(std::chrono::system_clock::now());
date::year_month_day lastMonday = todays_date -
(date::weekday{todays_date} - date::Monday);
std::cout << lastMonday << '\n';
}
相反,您只需要确定需要从sys_days
(在此示例中为todays_date
)中减去多少天。该天数是今天的weekday
减去Monday
。如果今天是Monday
,则结果是days{0}
。如果今天是Sunday
,则结果是days{6}
。我们也可以谈论寻找上一个星期五。逻辑不会改变。
此外,人们可以直接将sys_days
转换为weekday
。无需经过year_month_weekday
。
如果今天恰好是星期一,则OP的问题中的代码将“上一个星期一”视为今天。那很好。这是许多“以前的工作日”算法所需要的。这就是我上面编码的逻辑。
但是,如果您要查找的工作日是今天,则通常希望上一个工作日算法在上周产生。即如果今天是星期一,请计算一周前而不是今天。通过几乎相同的算法,这也很容易实现。如果您想要这种行为,只需在算法开始时减去一天:
auto todays_date = ...
todays_date -= date::days{1};
date::year_month_day lastMonday = ...