So I was wondering if someone could give me a point in the right direction here. I have a program I'm looking to build that will take a string from a text file and is supposed to concatenate on to it the date of the last work day, so Tuesday would grab Mondays date, Monday would grab Fridays date, if its the May 1st it grabs a date from April etc, in the form of MMDDYY. So for example if today is Tuesday May 1st my program would produce the string DataLine1_04302017.
I don't have access to an IDE at the moment to play around and test things with and it's something I want to work on when I get home later today. I know how to do all the string altering and text printouts, I'm just wondering if the time.h or ctime library support what I'm trying to do with the date as is, or if I'm going to need to play around with some if statements and math to get the month changes right.
Make the current time a std::chrono::system_clock::time_point and then add/subtract std::chrono::duration<int, std::ratio<3600*24>> (for Days), std::chrono::hours, std::chrono::minutes to it. An example here: http://www.cplusplus.com/forum/beginner/215483/#msg1001178
#include <iostream>
#include <string>
#include <ctime>
// return true if the time represents a working day
// in this trivial example, days other than saturdays and sundays are working days
bool is_working_day( const std::tm& day )
{ return day.tm_wday > 0 && day.tm_wday < 7 ; }
std::tm previous_day( std::tm day )
{
day.tm_mday -= 1 ; // decrement day by one; doesn't matter if it goes to zero
// mktime accepts and correctly adjusts values which are outside their normal ranges.
constauto prev = std::mktime( std::addressof(day) ) ;
return *std::localtime( std::addressof(prev) ) ;
}
std::string last_working_day( std::time_t time = std::time(nullptr) ) // in format: MMDDYY
{
auto tm = *std::localtime( std::addressof(time) ) ;
do tm = previous_day(tm) ; while( !is_working_day(tm) ) ;
char buff[1024] ;
std::strftime( buff, sizeof(buff), "%m%d%Y", std::addressof(tm) ) ;
return buff ;
}
// invariant: y, m, d are within range
std::string last_working_day( int y, int m /* jan == 1 */ , int d )
{
std::tm tm {} ;
tm.tm_year = y - 1900 ; // years since 1900
tm.tm_mon = m - 1 ; // jan == 0
tm.tm_mday = d ;
return last_working_day( std::mktime( std::addressof(tm) ) ) ;
}
int main()
{
std::cout << last_working_day() << '\n' // for today
<< last_working_day( 2017, 1, 2 ) << '\n' ; // for 02, january, 2017
}
With out seeing the date string I'm just guessing the best way is to determine the day, such as Monday, then you will know how many days to subtract from the day of month.
Thank you JLBorges, this looks like it's exactly what I'm looking for. I can easily modify this for what I'm trying to do (though there is a small bug where you set the last day of the week to 7 instead of 6, simple fix). Though I'm curious. I've seen this in a few places but why exactly do you subtract the year from 1900?
That says that returns the number of years since 1900 (which makes sense, but I'm not sure how or why that is being used.
Also to Samuel, I will not be getting the date from a text document. The text document will contain the name of a data file that was created the day before this program is activated, and is named based on its type and its date. The code I'm writing is just to check if the data file had been written correctly, or if there was some issue in the naming process.
Anyway thanks guys. This was my first time using the time library outside of making a seed for number generation. I wasn't aware of just how accurate the library was. I'll be playing around with this later on. Thank you!