如何在C ++中查找上周一的日期

时间:2019-06-08 09:15:41

标签: c++ date chrono

我想制作一个不输入任何内容并返回上一个星期一的日期的程序。 (我不在乎时区。我只担心公历)。我正在使用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。我只是想知道是否有可能)

1 个答案:

答案 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 = ...