Algorithm to find all sundays on given a range year - c++

how to find all sundays from given date between march 2016 - march 2018. with looping, there are 3 loops : looping for year, month, and date, then use if.
But im confuse about looping. can you help me ?

I'd use a good date library like this one. But that's probably not what your mentor is looking for.
#include "date.h"
#include <iostream>
int
main()
{
using namespace date;
for (sys_days start = mar/sun[1]/2016; start <= sys_days{mar/last/2018};
start += weeks{1})
std::cout << start << '\n';
}
2016-03-06
2016-03-13
2016-03-20
...
2018-03-18
2018-03-25

Related

Getting the day info only from a date int C/C++ [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I have a program that is getting a date from some protocol, in format of DD/MM/YYYY.
The Problem is that I need to know the info of that day(day of the week, day in the year...) and I don't know how to do it.
Usually, when I want to get a day info, I am using time(time_t*) and convert the result to tm struct using localltime_r(tm*, time_t*) and then I have everything i need.
But in this case, this is not the current time(so I can not use time(time_t*)) and I don't have nothing except the date.
I can create a new tm struct and fill only tm_year, tm_mon, tm_mday and use mktime(tm*), but I am not sure if this will give me the right detail's of the desired date.
You might consider using Howard Hinnant's free, open-source date/time library. It works with C++11 and later, ported to gcc, clang and VS. It has been accepted into the C++20 draft specification.
Example code:
#include "date/date.h"
#include <iostream>
#include <sstream>
int
main()
{
using namespace std;
using namespace date;
istringstream in{"09/07/2018"};
sys_days sd;
in >> parse("%d/%m/%Y", sd);
cout << "Day of the week is " << weekday{sd} << '\n';
cout << "Day of the year is " << sd - sys_days{year_month_day{sd}.year()/1/0} << '\n';
}
Output:
Day of the week is Mon
Day of the year is 190d
If you would rather do the computations yourself, here are extremely efficient non-iterative public domain algorithms for calendrical computations. The library referenced above is nothing but a type-safe wrapper around these algorithms with more pleasant syntax.
In case you wanted to get write methods which get the day of week/year as opposed to using a library, here's what I would do.
You're going to need to take leap years into account. For any given year, determine whether or not it is a leap year. Something like this would work (using a formula found here: https://en.wikipedia.org/wiki/Leap_year#Algorithm:
bool isLeapYear(short year)
{
bool leapYear = false;
if (((year % 4 == 0 && year % 100 != 0)) || (year % 400 == 0))
leapYear = true;
return leapYear;
}
From this, calculating the day of the year is straightforward. Simply add up all the days for each month, if it is a leap year, add 29 days onto your tally for day of year if you come across February.
As for finding the day of the week, it really helps if you start with some lower bound for the year (in this case LOWYEAR = 1760) and start with the first day of that year (STARTDAYOFWEEK = 2). Each day of the week is corresponds to a number (0-6) where Sunday is 0, Monday is 1, etc.
int DayOfWeek(void)
{
//jan 1 1760 was tuesday (2)
short dayCount = STARTDAYOFWEEK;
for (unsigned i = LOWYEAR; i < year; i++)
{
if (isLeapYear(i))
dayCount += 2;
else
dayCount++;
}
return (dayCount + dayOfYear) - 1) % DAYSINWEEK;
}
Finding the day of week is now really easy, after calculating dayCount, the day of week is found by adding dayCount with dayOfYear and modding by DAYSINWEEK (6).
The resulting number will correspond to the day of week (0-6).

How to find out the date of the first day of week from the week number in C++

Need a C++ function to find out the date of the first day of week from the week number.
Input : year and week number
Output : date [It should be 1st day of that week number]
e.g :
inputs :
year – 2017, week number – 8
Output: 20th Feb 2017
inputs:
year – 2017, week number – 10
Output: `6th March 2017
Using Howard Hinnant's free, open-source, header-only date library, it can look like this:
#include "date.h"
#include "iso_week.h"
#include <iostream>
int
main()
{
using namespace iso_week::literals;
std::cout << date::year_month_day{2017_y/8_w/mon} << '\n';
std::cout << date::year_month_day{2017_y/10_w/mon} << '\n';
}
which outputs:
2017-02-20
2017-03-06
There are also getters for year, month and day on the year_month_day types, and plenty of formatting options.

Method to calculate business days

I have an exercice, which I am having a little trouble with.
I must create a calculator which takes two parameters: Start date and days to add (except saturday and sunday, only business days, from monday to friday). Another thing is that the sum has to include the start date.
E.g. let's take the start day July 12th 2016, and add 8 days, which correspond to July 21th 2016 (Saturday and Sunday excluded, and Tuesday, July 21th 2016 is counted as one day).
I hope I'm clear.
I tried to code something, but it is not working.
// rStringGridEd1->IntCells[3][row] is a custom stringgrid
// and correspond to the number of days to add, j is the
// counter for the loop
while (j < rStringGridEd1->IntCells[3][row])
{
if (DayOfWeek(date) != 1 || DayOfWeek(date) !=7)
{
// if current date (TDate date = "12/07/16") is not Saturday or Sunday increment date by one day
date++;
}
else if(DayOfWeek(date) == 1)
{
//If date correspond to sunday increment the date by one and j the counter by one
date=date+1;
j++;
}
else if(DayOfWeek(date) == 7)
{
//If date correspond to saturday increment the date by two days and j the counter by one
date=date+2;
j++;
}
j++;
}
Can anyone help me, please?
Here is what Lee Painton's excellent (and up-voted) answer would look like using this free, open-source C++11/14 date library which is built on top of <chrono>:
#include "date.h"
#include <iostream>
date::year_month_day
get_end_job_date(date::year_month_day start, date::days length)
{
using namespace date;
--length;
auto w = weeks{length / days{5}};
length %= 5;
auto end = sys_days{start} + w + length;
auto wd = weekday{end};
if (wd == sat)
end += days{2};
else if (wd == sun)
end += days{1};
return end;
}
You could exercise it like this:
int
main()
{
using namespace date::literals;
std::cout << get_end_job_date(12_d/jul/2016, date::days{8}) << '\n';
}
Which outputs:
2016-07-21
This simplistic calculator has a precondition that start is not on a weekend. If that is not a desirable precondition then you could detect that prior to the computation and increment start internally by a day or two.
The date library takes care of things like the relationship between days and weeks, and how to add days to a date. It is based on very efficient (non-iterative) algorithms shown and described here.
If you aren't required to use a loop then you might want to consider refactoring your solution with a simpler calculation. Consider, for example, that every five business days automatically adds seven days to the date. Thus using the quotient and remainder of the days to add should tell you how many total days to add to your date variable without resorting to a brute force loop.
Since it's an exercise I won't get into specifics of code, but a few things to consider might be how you can figure out what day of the week you end on knowing the day that you started on. Also, if you end on a friday what happens with the weekend that immediately follows it.

c++ : get week number from yyyyMMdd

I'm writing a impala udf in c++ which gets week of year when provided with date in yyyyMMdd. But could not seem to find way to convert yyyyMMdd to week of year in c++. In java I can you Calendar, but how to go about it in c++.
TIA
You can just use std::mktime from <ctime>. Example:
std::tm date={};
date.tm_year=2014-1900;
date.tm_mon=9-1;
date.tm_mday=28;
std::mktime(&date);
After the call, date.tm_wday is adjusted (0=Sunday). date.tm_yday is also adjusted.
To get the week into the year, use: (date.tm_yday-date.tm_wday+7)/7
This calculation returns 1 for the first full week (namely, first week with a Sunday in it in the year, including Jan 1 in years that start with Sunday); and 0 for days in the first partial week.
I answered this here, but for the sake of completeness, I will repeat it here too:
Use iso_week.h from howardhinnant.github.io/iso_week.html :
#include <iostream>
#include "iso_week.h"
int main() {
using namespace iso_week;
using namespace std::chrono;
// Get the current time and floor to convert to the sys_days:
auto today = floor<days>(system_clock::now());
// Convert from sys_days to iso_week::year_weeknum_weekday format
auto yww = year_weeknum_weekday{today};
// Print current week number of the year
std::cout << "The current week of " << yww.year() << " is: "
<< yww.weeknum() << std::endl;
// Set any day
auto any_day = 2014_y/9/28;
// Get week of `any_day`
std::cout << "The week of " << any_day.year() << " on `any day` was: "
<< any_day.weeknum() << std::endl;
}
which gives the output:
The current week of 2019 is: W18
The week in 2014 on `any day` was: W09
Use boost::date library.It's simple and easy to use.

weekdays' duration using boost date

Is there a way to get only the no. of weekdays between 2 boost dates.
In the following, I'm only getting calendar days.
date begin_dt(2011,Aug,3);
date end_dt(day_clock::local_day());
days duration=end_dt-begin_dt;
std::cout<<"calendar days between begin & end date are: "<<duration<<std::endl;
Perhaps the simplest way is to run a day_iterator from start to finish:
#include <iostream>
#include <boost/date_time.hpp>
int main()
{
using namespace boost::gregorian;
date begin_dt(2011,Aug,3);
date end_dt(day_clock::local_day());
days duration=end_dt-begin_dt;
std::cout<<"calendar days between begin & end date are:" << duration << '\n';
int cnt=0;
for(day_iterator iter = begin_dt; iter!=end_dt; ++iter)
{
if( iter->day_of_week() != boost::date_time::Saturday
&& iter->day_of_week() != boost::date_time::Sunday)
++cnt;
}
std::cout << "of them " << cnt << " are weekdays\n";
}
You could start substracting the number of days to the next week start, and deleting either 1 or two depending if you're on saturday or before, or sunday. Then, you can divide the rest of the days remaining by 7, multiply that number by 2, and substract to the days. You have to make a case for the remainder too. If it is 6 (saturday), you have to remove one more. Not easy, but you get the idea.