how to get the third friday for a month in c++?

Viewed 246

i think date handling is a little complex.

so, i want to know if there is any elegant algorithm that i can get any dates in my condition like the third friday's date in sep 2020?

let's specify two method i want:

int get_date(int month, int weekday, int no) {  // for example: get_date(202009, 3, 3)
     //  should return the third wednesday in sep 2020, it's 20200917
}

int date_sub(int date1, int date2) { // for example:
   // date_sub(20200928, 20200925) should return 3

}

i know boost have some nice things, but i think it may too heavy, is there any better choice?

2 Answers

This is trivial using either the c++20 date support or Howard Hinnants implementation:

#include <chrono>
#include <iostream>

using namespace std::chrono;

int main()
{
    constexpr year_month_day date {year(2020)/September/Friday[3]};
    std::cout << date;
}

or

#include "date.h"
#include <iostream>

using namespace date;

int main()
{
    constexpr year_month_day date {year(2020)/September/Friday[3]};
    std::cout << date;
}

As far as I know, no compiler supports std::chrono Calendar as of now, but they will catchup eventually, so, to be future-proof, here are the functions you asked for expressed using it:

#include <cassert>
#include <chrono>

std::chrono::sys_days get_date(std::chrono::year_month year_month, 
                               std::chrono::weekday weekday,
                               unsigned weekday_index) {
    return std::chrono::year_month_weekday {
        year_month.year(), year_month.month(), 
        std::chrono::weekday_indexed(weekday, weekday_index)
    }
}

std::chrono::duration<std::chrono::days> date_sub(std::chrono::sys_days lhs,
                                                  std::chrono::sys_days rhs) {
    return std::chrono::duration_cast<std::chrono::days>(lhs - rhs);
}

int main() {
    [[maybe_unused]] signed difference = date_sub(
        get_date(2020y / std::chrono::month::September, std::chrono::weekday::Friday, 3),
        get_date(2020y / std::chrono::month::September, std::chrono::weekday::Tuesday, 3)
    ).count();

    assert(difference == 3);
}
Related