By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
428,853 Members | 2,144 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 428,853 IT Pros & Developers. It's quick & easy.

Why does my dateclass class gives the wrong date?

P: 29
I have made a date program. I need it to do three things now:

1. Return the previous dates, (0, 1, 2, 3... Days ago)
2. Skip the weekends.
3. Skip these holidays:

New Year's Day (Jan 1)
MLKJ Day (Jan 18)
Pres. Day (Feb 15)
Good Friday (Apr 2)
Memorial Day (May 31)
Indep. Day (Jul 5 observed)
Labor Day (Sep 6)
Thanksgiving Day (Nov 25)
Christmas (Dec 24 observed)

This is my code, it gives problems:

Expand|Select|Wrap|Line Numbers
  1. #include "dateclass.h"
  2. #include <iostream>
  3.  
  4. using namespace std;
  5.  
  6. int main()
  7. {
  8.     dateclass current;
  9.     cout << current.decrement(0);
  10.  
  11.     return 0;
  12. }
  13.  
Expand|Select|Wrap|Line Numbers
  1. #include "numdate.h"
  2. #include "numvalue.h"
  3.  
  4. using namespace std;
  5.  
  6. class dateclass
  7. {
  8. private:
  9.     ushort day;
  10.     ushort newday;
  11.     ushort month;
  12.     ushort year;
  13.     string curdate;
  14.     string srchdate;
  15.     string weekday;
  16.     string datestring;
  17.     time_t rawtime;
  18. public:
  19.  
  20.     void reset(){
  21.         time(&rawtime);
  22.         datestring = ctime(&rawtime);
  23.         curdate.clear();
  24.         datestring.clear();
  25.     }
  26.  
  27.     dateclass() //date constructor 
  28.     {
  29.         time(&rawtime);
  30.         datestring = ctime(&rawtime);
  31.  
  32.         curdate = datestring;
  33.         curdate.erase(0,4); //remove day prefix
  34.         curdate.erase(7,9); //remove time
  35.         curdate.insert(6, ",", 1); //insert comma
  36.  
  37.         numvalue current(curdate);
  38.  
  39.         month = current.getmonth();
  40.         day = current.getday();
  41.         year = current.getyear();
  42.  
  43.         weekday = datestring.substr(0,3);
  44.     };
  45.  
  46.     const string& getcurdate()
  47.     {
  48.         srchdate = curdate;
  49.         if (day < 10) //change "0x" to "x" in date
  50.             srchdate = curdate.erase(4,1);
  51.         return srchdate;
  52.     };
  53.  
  54.     string decrement(ushort decrement)
  55.     {
  56.         exclusion weekdays(weekday);
  57.         decrement = weekdays.decrement(decrement);
  58.  
  59.         numdate numeric (month, day, year);
  60.         numeric.decrement(decrement);
  61.  
  62.         srchdate = numeric.revert();
  63.         numvalue search(srchdate);
  64.         newday = search.getday();
  65.  
  66.         if (newday < 10)
  67.             srchdate = srchdate.erase(4,1);
  68.  
  69.         return srchdate;
  70.     };
  71. };
  72.  
Expand|Select|Wrap|Line Numbers
  1. #include "exclusion.h"
  2.  
  3. using namespace std;
  4. const ushort Feb = 31;
  5.  
  6. enum holidays { NewYear = 1, MartinLuther = 18, Washington = 46, GoodFriday = 92, MemorialDay = 151,\
  7.     IndependenceDay = 187, LaborDay = 249, ThanksgivingDay = 329, Christmas = 358 };
  8.  
  9. class numdate
  10. {
  11. private:
  12.     ushort m_month;
  13.     ushort d_day;
  14.     ushort y_year;
  15.     ushort t_month;
  16.     ushort t_day;
  17.     ushort t_year;
  18.  
  19.     int raw;
  20.     ushort num_days;
  21.  
  22.     ushort Mar;
  23.     ushort Apr;
  24.     ushort May;
  25.     ushort Jun;
  26.     ushort Jul;
  27.     ushort Aug;
  28.     ushort Sep;
  29.     ushort Oct;
  30.     ushort Nov;
  31.     ushort Dec;
  32. public:
  33.     numdate(int month, int day, int year) : m_month(month), d_day(day), y_year(year)
  34.     {
  35.         t_month = 0; //reset temporary
  36.         t_day = 0;
  37.         t_year = 0;
  38.     }
  39.  
  40.     ushort ret_month() {return m_month;};
  41.     ushort ret_day() {return d_day;};
  42.     ushort ret_year() {return y_year;};
  43.  
  44.     void decrement(ushort decrement)
  45.     {
  46.         if (y_year % 4 == 0)
  47.             {Mar = 60; Apr = 91; May = 121; Jun = 152; Jul = 182;
  48.             Aug = 213; Sep = 244; Oct = 274; Nov = 305; Dec = 335;}
  49.         else
  50.             {Mar = 59; Apr = 90; May = 120; Jun = 151; Jul = 181;
  51.             Aug = 212; Sep = 243; Oct = 273; Nov = 304; Dec = 334;}
  52.  
  53.         switch(m_month)
  54.         {
  55.         case 1: break;
  56.         case 2:    num_days = d_day + Feb; break;
  57.         case 3: num_days = d_day + Mar; break;
  58.         case 4: num_days = d_day + Apr; break;
  59.         case 5: num_days = d_day + May; break;
  60.         case 6: num_days = d_day + Jun; break;
  61.         case 7: num_days = d_day + Jul; break;
  62.         case 8: num_days = d_day + Aug; break;
  63.         case 9: num_days = d_day + Sep; break;
  64.         case 10: num_days = d_day + Oct; break;
  65.         case 11: num_days = d_day + Nov; break;
  66.         case 12: num_days = d_day + Dec; break;
  67.         }
  68.  
  69.         t_year = y_year;
  70.  
  71.         while (num_days < decrement)
  72.         {
  73.             t_year = t_year - 1;
  74.             if (t_year % 4 == 0) {num_days += 366;}
  75.             else {num_days += 365;}
  76.         }
  77.  
  78.         raw = num_days - decrement;
  79.         t_day = raw;
  80.  
  81.         if (raw <= NewYear && num_days >= NewYear)
  82.             t_day--;
  83.         if (raw <= MartinLuther && num_days >= MartinLuther)
  84.             t_day -= 3;
  85.         if (raw <= Washington && num_days >= Washington)
  86.             t_day -= 3;
  87.         if (raw <= GoodFriday && num_days >= GoodFriday)
  88.             t_day--;
  89.         if (raw <= MemorialDay && num_days >= MemorialDay)
  90.             t_day -= 3;
  91.         if (raw <= IndependenceDay && num_days > IndependenceDay)
  92.             t_day -= 3;
  93.         if (raw <= LaborDay && num_days >= LaborDay)
  94.             t_day -= 3;
  95.         if (raw <= ThanksgivingDay && num_days >= ThanksgivingDay)
  96.             t_day--;
  97.         if (raw <= Christmas && num_days >= Christmas)
  98.             t_day--;
  99.  
  100.         if (t_day <= 0)
  101.         {
  102.             t_year = t_year - 1;
  103.             if (t_year % 4 == 0) {t_day += 366;}
  104.             else {t_day += 365;}
  105.         }
  106.  
  107.         if (t_day > Dec) {t_day = t_day - Dec; t_month = 12;}
  108.         else if (t_day > Nov) {t_day = t_day - Nov; t_month = 11;}
  109.         else if (t_day > Oct) {t_day = t_day - Oct; t_month = 10;}
  110.         else if (t_day > Sep) {t_day = t_day - Sep; t_month = 9;}
  111.         else if (t_day > Aug) {t_day = t_day - Aug; t_month = 8;}
  112.         else if (t_day > Jul) {t_day = t_day - Jul; t_month = 7;}
  113.         else if (t_day > Jun) {t_day = t_day - Jun; t_month = 6;}
  114.         else if (t_day > May) {t_day = t_day - May; t_month = 5;}
  115.         else if (t_day > Apr) {t_day = t_day - Apr; t_month = 4;}
  116.         else if (t_day > Mar) {t_day = t_day - Mar; t_month = 3;}
  117.         else if (t_day > Feb) {t_day = t_day - Feb; t_month = 2;}
  118.         else {t_month = 1;}
  119.  
  120.     };
  121.  
  122.     string revert()
  123.     {
  124.         string vdate;
  125.  
  126.         switch (t_month)
  127.         {
  128.         case 1: vdate += "Jan "; break;
  129.         case 2: vdate += "Feb "; break;
  130.         case 3: vdate += "Mar "; break;
  131.         case 4: vdate += "Apr "; break;
  132.         case 5: vdate += "May "; break;
  133.         case 6: vdate += "Jun "; break;
  134.         case 7: vdate += "Jul "; break;
  135.         case 8: vdate += "Aug "; break;
  136.         case 9: vdate += "Sep "; break;
  137.         case 10: vdate += "Oct "; break;
  138.         case 11: vdate += "Nov "; break;
  139.         case 12: vdate += "Dec "; break;
  140.         }
  141.  
  142.         vdate += ((char) ((t_day / 10) + 48));
  143.         vdate += ((char) ((t_day % 10) + 48));
  144.  
  145.         vdate += ", ";
  146.  
  147.         vdate += ((char) ((t_year / 1000) + 48));
  148.         vdate += ((char) (((t_year % 1000) / 100) + 48));
  149.         vdate += ((char) ((((t_year % 1000) % 100) / 10) + 48));
  150.         vdate += ((char) ((((t_year % 1000) % 100) % 10) + 48));
  151.  
  152.         return vdate;
  153.     };
  154. };
  155.  
Expand|Select|Wrap|Line Numbers
  1. #include <time.h>
  2. #include <string>
  3.  
  4. typedef unsigned short ushort;
  5. using namespace std;
  6.  
  7. class exclusion
  8. {
  9. private:
  10.     string weekday;
  11.     int num;
  12.     ushort countdown;
  13.     ushort remainder;
  14.     ushort weekend;
  15.  
  16. public:
  17.     exclusion(string weekday)
  18.     {
  19.         if(weekday == "Sat") num = 0;
  20.         else if(weekday == "Sun") num = 1;
  21.         else if(weekday == "Mon") num = 2;
  22.         else if(weekday == "Tue") num = 3;
  23.         else if(weekday == "Wed") num = 4;
  24.         else if(weekday == "Thu") num = 5;
  25.         else num = 6;
  26.  
  27.         if (num == 1)
  28.             weekend = 1;
  29.         else if (num > 1)
  30.             weekend = 2;
  31.         else
  32.             weekend = 0;
  33.     };
  34.  
  35.     ushort decrement(ushort countdown)
  36.     {
  37.         remainder = countdown;
  38.         if (countdown < num)
  39.             return remainder;
  40.         remainder += weekend;
  41.         countdown -= num;
  42.         remainder += 2 * (countdown / 7);
  43.         countdown -= 7 * (countdown / 7);
  44.         remainder += countdown / 6;
  45.         return remainder;
  46.     };
  47. };
  48.  
Expand|Select|Wrap|Line Numbers
  1. #include <string>
  2.  
  3. typedef unsigned short ushort;
  4. using namespace std;
  5.  
  6. class numvalue
  7. {
  8. private:
  9.     ushort day;
  10.     ushort month;
  11.     ushort year;
  12.     char number;
  13.     string str_month;
  14.     string date;
  15.  
  16. public:
  17.     numvalue(string input) : date(input){};
  18.  
  19.     ushort getmonth()
  20.      {
  21.         str_month = date.substr(0,3); //get first 3 chars
  22.  
  23.         if (str_month == "Jan") month = 1; //get month values
  24.         else if (str_month == "Feb") month = 2;
  25.         else if (str_month == "Mar") month = 3;
  26.         else if (str_month == "Apr") month = 4;
  27.         else if (str_month == "May") month = 5;
  28.         else if (str_month == "Jun") month = 6;
  29.         else if (str_month == "Jul") month = 7;
  30.         else if (str_month == "Aug") month = 8;
  31.         else if (str_month == "Sep") month = 9;
  32.         else if (str_month == "Oct") month = 10;
  33.         else if (str_month == "Nov") month = 11;
  34.         else month = 12;
  35.  
  36.         return month;
  37.     };
  38.  
  39.     ushort getday()
  40.     {
  41.         number = date.at(5);
  42.         day = (int) number - 48;
  43.         number = date.at(4);
  44.         day += 10 * ((int) number - 48);
  45.  
  46.         return day;
  47.     };
  48.  
  49.     ushort getyear()
  50.     {
  51.         number = date.at(11);
  52.         year = (int) number - 48;
  53.         number = date.at(10);
  54.         year += 10 * ((int) number - 48);
  55.         number = date.at(9);
  56.         year += 100 * ((int) number - 48);
  57.         number = date.at(8);
  58.         year += 1000 * ((int) number - 48);
  59.  
  60.         return year;
  61.     };
  62. };
  63.  
When I try to get today's date, it returns Nov 24, 2010.
(today is Nov. 25). When I try to get the day 4 days back, I get Nov 20, 2010, (a saturday, I am trying to exclude weekends and holidays). Can anyone help please?
Nov 25 '10 #1
Share this Question
Share on Google+
7 Replies


Banfa
Expert Mod 5K+
P: 8,916
I am wondering why at line 30 of dateclass.h you have not just called either std::gmtime or std::localtime from the header <ctime> to convert your time_t variable to a structure containing all the various components?
Nov 25 '10 #2

P: 29
Never mind about that. I did it how I did it. However, it does not seem to work.
Nov 25 '10 #3

100+
P: 542
Being rude won`t get you far.
Nov 26 '10 #4

P: 29
I wasn't being rude. I am just saying, those functions seem to do the same thing. I really don't care about the time, I just need the date.
Nov 26 '10 #5

Banfa
Expert Mod 5K+
P: 8,916
You have made the whole thing overly complex by trying to work in days months and years. It you worked in seconds past the epoch and just converted to days months and years for output all your calculations would be simpler.

You use the numerical value 48 where you should be using the character constant '0' and have thus introduced a portability issue.

The logic in exclusion::decrement appears wrong if num - countdown == 1

At the end of the calculation you remove a 0 from the result string if day < 10 but it would be far easier to not put that 0 into the string in the first place in numdate::revert.

You use of class data is erratic and some classes (exclusion) have class data members that are just not used or that could have automatic scope to the function they are used in.


The whole thing is an unmitigated mess and a maintenance nightmare I see no obvious errors but then that is hardly surprising since the code is so convoluted that it's operation is not obvious.

If you really want to go ahead with it I suggest you add output (cout) statements into the code to output the data at various points of the calculation to highlight the point where it is going wrong.
Nov 26 '10 #6

P: 29
Ok, I changed the main.cpp code for the output:

Expand|Select|Wrap|Line Numbers
  1. #include "dateclass.h"
  2. #include <iostream>
  3.  
  4. using namespace std;
  5.  
  6. int main()
  7. {
  8.     dateclass current;
  9.     cout << "Today: " << current.decrement(0) << endl;
  10.     cout << "2 Days Ago: " << current.decrement(1) << endl; //compensate for skipping holidays
  11.     cout << "3 Days Ago: " << current.decrement(2) << endl;
  12.     cout << "4 Days Ago: " << current.decrement(3) << endl;
  13.     cout << "7 Days Ago: " << current.decrement(4) << endl; //should skip weekends, however, goes to Sunday date
  14.  
  15.     return 0;
  16. }
  17.  
Output:

Today: Nov 26, 2010
2 Days Ago: Nov 24, 2010
3 Days Ago: Nov 23, 2010
4 Days Ago: Nov 22, 2010
7 Days Ago: Nov 21, 2010
Press any key to continue . . .


On 7 Days Ago, it should be "Nov 19, 2010", the most recent non-weekend, a Friday. However, it returns the Sunday Date.

For 5 days, it returns Saturday date, "Nov 20, 2010".

Also, what did you mean by "seconds past the epoch and just converted to days months and years for output". If you say it is simpler, how would I do it?
Nov 26 '10 #7

P: 29
By the way, thanks. I spent a whole month working on this.
Dec 12 '10 #8

Post your reply

Sign in to post your reply or Sign up for a free account.