#include <ctime>

// int GetWeekOfTheYear(int, int, int);
// void GetDateFromWeekNumber(int, int, int, int&, int&);

void DateWeekConversion() {

   int year = 2011;
   int week_num = GetWeekOfTheYear(year, 9, 30);

   cout << "week of the year = " << week_num << endl;

   year--;
   int day, month;
   GetDateFromWeekNumber(year, week_num, 5, day, month); 
   cout << "same week = " << year << "-" << month << "-" << day << endl;
   GetDateFromWeekNumber(year, week_num-1, 5, day, month); 
   cout << "prev - 1 week = " << year << "-" << month << "-" << day << endl;

}




int GetWeekOfTheYear(int year=2010, int month=2, int day=19) {

   const char * weekday[] = { "Sunday", "Monday",
                              "Tuesday", "Wednesday",
                              "Thursday", "Friday", "Saturday"};
   std::tm timeinfo;
   timeinfo.tm_sec = timeinfo.tm_min = timeinfo.tm_hour = 1; // past midnight
   timeinfo.tm_mday = day;
   timeinfo.tm_mon = month-1; // month number starting with 0
   timeinfo.tm_year = year - 1900;
   timeinfo.tm_hour = 0; 
   timeinfo.tm_min  = 0; 
   timeinfo.tm_sec  = 1;
   timeinfo.tm_isdst= 0; // day-light saving   

   std::mktime(&timeinfo);
   char buffer[4];
   strftime(buffer,4,"%W", &timeinfo);  // '%W' = week number of the year
   int week  = atoi(buffer)+1; // week starts at 0
   
   //  cout << "week of the year = " << week << endl;
   // cout << "the day of the week = " << weekday[timeinfo.tm_wday] << endl;
   
   return week;
}








// Get the date for a given year, week and weekday(1-7) 
void GetDateFromWeekNumber(int year, int week, int dayOfWeek, 
                           int& day, int& month)
{
   std::tm jan1;
   jan1.tm_year = year - 1900; 
   jan1.tm_mon  = 0; // JAN
   jan1.tm_mday = 1; // 1st
   jan1.tm_hour = 0; 
   jan1.tm_min  = 0; 
   jan1.tm_sec  = 1;
   jan1.tm_isdst= 0; // day-light saving

   std::time_t tim = std::mktime(&jan1);
   int wday_on_Jan1 = jan1.tm_wday;
   int days = (week-1)*7 - wday_on_Jan1 + dayOfWeek+1;

   
   enum Months { JAN = 1, FEB, MAR, APR, MAY, JUN, 
                 JUL, AUG, SEP, OCT, NOV, DEC };

   int NDays[13];
   NDays[0] = 0;
   NDays[1] = 31;
   NDays[2] = NDays[1] + ((year%4==0) ? 29 : 28); 

   for (int i=3; i<13; ++i) {
      NDays[i] = NDays[i-1] + ( (i%2==1 || i==8) ? 31 : 30);
   } 

   
   Months tm_month=JAN;
   for (; tm_month <= DEC; tm_month++ ) {
      if( (days - NDays[tm_month]) <= 0) break;   
   }

   month = tm_month; 
   day = days - NDays[month-1]; 


   std::tm newtime;
   newtime.tm_year = year - 1900; 
   newtime.tm_mon  = month-1; 
   newtime.tm_mday = day; 
   newtime.tm_hour = 0; 
   newtime.tm_min  = 0; 
   newtime.tm_sec  = 1;
   newtime.tm_isdst= 0; 

   std::mktime(&newtime);
   int new_dayOfWeek = newtime.tm_wday;



   if(!(new_dayOfWeek==dayOfWeek)) {
      int diff = dayOfWeek - new_dayOfWeek;
      day += dayOfWeek - new_dayOfWeek;

      // cout << "new_dayOfWeek = " << new_dayOfWeek 
      //      << ", diff = " << diff 
      //      << ", date = " <<  year << "-" << month << "-" << day << endl;
   }

}

