How to iterate through a date range in c++
c++, date, iteration, loops
Solution
It might not actually be easier.... But you can use the time functions from `<ctime>`. Something like this:
string MakeFileName( time_t t )
{
static const char* months[] = { "JAN", "FEB", "MAR", "APR", "MAY", "JUN",
"JUL", "AUG", "SEP", "OCT", "NOV", "DEC" };
struct tm *ptm = localtime(&t);
char buffer[20];
snprintf( buffer, 20, "%02d%s%04d.CSV",
ptm->tm_day, months[ptm->tm_month], ptm->tm_year+1900 );
return string(buffer);
}
Now just get your start and end dates correct in a `time_t` value (remember, it's in seconds). You can just use `00:00:00` for the time.
// Note that day and month are 1-based.
time_t GetDate( int day, int month, int year )
{
struct tm ttm = {0};
ttm.tm_day = day;
ttm.tm_month = month-1;
ttm.tm_year = year-1900;
return mktime(&ttm);
}
With that helper you can set your start and end dates easily:
time_t start = GetDate(1, 1, 2011);
time_t end = GetDate(28, 10, 2013);
for( time_t t = start; t <= end; t += 86400 )
{
string filename = MakeFileName(t);
// TODO...
}
Problem
I have a folder with csv files. Each csv file is named by a date (eg. 01JAN2013.csv, 02JAN2013.csv ). I have to read the files in the order of their date (start date and end date are known). So I am trying to loop through the dates, from the start date to the end date, in order to generate the file names. Currently I am doing: ``` vector<string> dd{"01", "02", "03", "04", "05", "06", "07", "08", "09","10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20","21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31"}; vector<string> mmm{"JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG","SEP", "OCT", "NOV", "DEC"}; vector<string> yyyy{"2011","2012","2013","2014"}; string filePath=DataFolderPath; for(int i=0;i<yyyy.size();i++) { for(int j=0;j<mmm.size();j++) { for(int k=0;k<dd.size();k++) { filePath.append(dd[k]); filePath.append(mmm[j]); filePath.append(yyyy[i]); filePath.append(".csv"); } } } ``` Definitely ugly, but it gets the job done. Is there an easier way to loop through dates in C++. Something along the lines of: ``` for ( currentDate = starDate; currentDate < endDate; currentDate++) { //Do stuff } ``` UPDATE: This is the approach that I finally used, combination of both the answers below: ``` typdef struct tm Time; Time startDate=makeDate(3,1,2011); Time endDate=makeDate(24,1,2014); time_t end=mktime(&endDate); for(Time date=startDate;end>=mktime(&date);++date.tm_mday) { char buffer[16]; strftime(buffer, sizeof(buffer), "%d%b%Y.csv", &date); std::string filename(buffer); //To convert month to CAPS std::transform(filename.begin()+2, filename.begin()+5,filename.begin()+2, ::toupper); std::cout << filename << "\n"; } ``` I also used a `makeDate` helper function based on paddy's answer which return a `struct tm` instead of `time_t`: ``` Time makeDate( int day, int month, int year ) { Time ttm = {0}; ttm.tm_mday= day; ttm.tm_mon= month-1; ttm.tm_year= year-1900; return ttm; } ```