Calendar calcuation: months with odd number of days

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • yashsewlani
    New Member
    • Oct 2011
    • 1

    Calendar calcuation: months with odd number of days

    I tried making a program for calculating the difference between two dates on CPP, it does work, but it is not completely accurate.
    The program calculates the number of months and multiplies it by 30. The problem here is that all months don't have 30 days. A few has 31 and one has 28/29. My program is below. Can anyone suggest me any changes to get rid of this problem.

    Code:
    #include<iostream.h>
    #include<conio.h>
    #include<time.h>
    #include<string.h>
    void main()
    {
    char a[20];
    char b[20];
    int t,q,m,c,d,e,h,i,k,r,s,u,aa,bb,cc,dd,ee,ff;
    float aaa=0,bbb,ccc,ddd,eee,fff,ll;
    clrscr();
    cout<<"\nEnter The first date\n";           
    cin>>b;                                                    
    t=b[3];
    q=b[4];
    m=((t-48)*10)+(q-48);
    h=b[0];
    i=b[1];
    k=((h-48)*10)+(i-48);
    aa=b[6];
    bb=b[7];
    cc=((aa-48)*10)+(bb-48);
    cout<<"\nEnter The second date\n";
    cin>>a;
    c=a[3];
    d=a[4];
    e=((c-48)*10)+(d-48);
    r=a[0];
    s=a[1];
    u=((r-48)*10)+(s-48);
    dd=a[6];
    ee=a[7];
    ff=((dd-48)*10)+(ee-48);
    cout<<"The first date is "<<m<<" And the month is "<<k<<" and the year is "<<cc;
    cout<<"\nThe second date is "<<e<<" and the month is "<<u<<" and the year is "<<ff;
    aaa=(u-k)*30;
    bbb=e-m;
    ccc=(ff-cc)*365;
    cout<<"\nThe diff is"<<aaa+bbb+ccc;  					
    getch();
    }
    Last edited by Niheel; Oct 3 '11, 04:49 PM.
  • weaknessforcats
    Recognized Expert Expert
    • Mar 2007
    • 9214

    #2
    I would calculate the number of days from a known start date and then just compare the two numbers.

    So:
    1) Let's assume the defined start is 01/01/2000.
    2) Calculate the number of years.
    3) Calculate the number of leap years.
    4) Each year is 365 plus 1 day for eahc leap year.
    5) Add the number of days for the months preceding the current month
    6) Add the number of days for the day

    1)Therefore, to covert 10/2/2011:
    2) 2011 - 2000 = 11 years
    3) 11/4 == 2 leap years
    4) Total = 11 * 365 + 2 days
    5) Add to total number of days in Jan,28,Mar,Apr, May.Jun.Jul.Aug .Sep
    6) Add to total 1 since it's Oct 1

    Do th same with the other date and compare the totals

    Comment

    • donbock
      Recognized Expert Top Contributor
      • Mar 2008
      • 2427

      #3
      Look at library functions mktime and difftime in standard header ctime (time.h).

      Comment

      • Banfa
        Recognized Expert Expert
        • Feb 2006
        • 9067

        #4
        @weaknessforcat s while a agree with your general method I have these comments

        Step 4 of your calculation "11/4 = 2 leap years" is wrong because 2000 was also a leap year

        Step 5 of your formula "Add the number of days for the months preceding the current month" it is important to note that in this step you still need to be take into consideration the leapness (is that a word?) of the current year.

        Comment

        • donbock
          Recognized Expert Top Contributor
          • Mar 2008
          • 2427

          #5
          For serious work with calendar calculations, I strongly recommend the book Calendrical Calculations by Nachum Dershowitz and Edward Reingold. My 15-year-old copy of the first edition is still a valuable part of my reference library. The third edition was published in 2007.

          Comment

          • alexis4
            New Member
            • Dec 2009
            • 113

            #6
            I feel a little weird answering after the experts, but I have recently done a similar thing not in C++, but in C. Add 365 days for each year and for the leap years you can control it like:

            Code:
            if (!(year % 4))
            {
              AddOneMoreDay();
            }

            Now for the last and first years which are not complete with 365 (or 366) days, you can add 30 for each month, using a switch-case at the same time like:

            Code:
            switch (month)
            {
              case _JANUARY:
              case _MARCH:
              case _MAY:
              case _JULY:
              case _AUGUST:
              case _OCTOBER:
              case _DECEMBER:
                AddOneMoreDay();
                break;
            
              case _FEFRUARY:
                SubtractOneDay();
            
                if (year % 4)
                {
                  SubtractOneDay();
                }
                break;
              }
            }

            Finally you add the remaining days for the starting and ending month registered by user, but you must again check the above cases so that you won't miss or add a day that shouldn't be missed or added. Those cases could also be used for calendar validation. For example if user types 32/12, then that calendar should be rejected by the program and a new entry should be asked by the user. This should be done if you want to have a real life program.

            Hope that helps.
            Last edited by alexis4; Oct 3 '11, 08:40 PM. Reason: Last paragraph added

            Comment

            • weaknessforcats
              Recognized Expert Expert
              • Mar 2007
              • 9214

              #7
              You might also add 63 to the number of days in the year. The result is 365+63 == 428 or 366+63 = 429. Now subtract 400 and you have the days in Feb.

              Comment

              • johny10151981
                Top Contributor
                • Jan 2010
                • 1059

                #8
                Code:
                char *DateDiffer(char *Date, int DayToSub)
                {
                	struct tm time,*tmt;
                	time_t mtime;
                	int year,month,date;
                	char *buffer;
                	buffer=(char *)malloc(sizeof(char)*10);
                	if(Date!=NULL)
                	{
                		sscanf(Date,"%d-%d-%d",&year,&month,&date);
                	}	
                
                	memset((char*)(&time),0,sizeof(struct tm));
                	time.tm_year=year-1900;
                	time.tm_mon=month-1;
                	time.tm_mday=date-DayToSub;
                	mtime=mktime(&time);
                	tmt=localtime(&mtime);
                	sprintf(buffer,"%04d-%02d-%02d\n",(tmt->tm_year+1900),(tmt->tm_mon+1),tmt->tm_mday);
                	return buffer;
                }
                use this function,
                I wrote this function for "yyyy-mm-dd" standard date.

                Comment

                • whodgson
                  Contributor
                  • Jan 2007
                  • 542

                  #9
                  Or you could find the Julian day for each date and subtract one from the other to obtain the number of days between. If there is a decimal fraction multiply it by 24 to get the fraction of a day in hours.It takes care of leap years and cancelled days.
                  The function is:
                  Code:
                  double julday(double d, int m, int y) 
                  {
                  int A,C,D;
                  
                  double JD,B;
                  
                  A=int(y/100);
                  if(y<500)B=0;
                  else B=2-A+int(A/4);
                  C=int(365.25*(y+4716));
                  D=int(30.6001*(m+1));
                  
                  JD=C+D+B+d-1524.5;
                  return JD;
                  }

                  Comment

                  • donbock
                    Recognized Expert Top Contributor
                    • Mar 2008
                    • 2427

                    #10
                    Is the point of this exercise for you to write all this code yourself? If not, then I repeat -- Standard Library functions mktime and difftime will do all the hard work for you.

                    Comment

                    Working...