如何在C++中找到上一个星期一的日期

How to find the date of the previous monday in C++

本文关键字:上一个 星期一 日期 C++      更新时间:2023-10-16

我想制作一个不需要输入并返回上周一日期的程序。(我不在乎时区。而且我只担心公历)。我正在使用霍华德·欣南特的日期。这就是我目前的做法:

#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::p revious_weekday 的情况下做到这一点?(这不是不使用提升的要求。我只是想知道是否有可能)

理解如何更简单地做到这一点的关键是了解关于 Howard Hinnant 日期库的一个事实:

weekday区别是圆形的(如果您愿意,也可以使用模 7)。 也就是说,从任何weekday中减去任何weekday都会得到 [0, 6] 范围内的许多days。 这有效地隐藏了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 = ...