Thread: Need to simplify/shorten this code. Help.

  1. #1
    Registered User
    Join Date
    Oct 2007
    Posts
    9

    Need to simplify/shorten this code. Help.

    Im doing this days between dates prog and I need to shorten this fuction without loosing its purpose. Can someone help.
    Code:
    int days (int yer2,int yer1,int mnth2,int mnth1,int day1,int day2)
    {
         int fyear1,syear1,fyear2,syear2,theyer1,theyer2;
         if (mnth1==1 || mnth2==1 || mnth1==2  || mnth2==2)
         {
            fyear1=int((yer1-1)/100);
            syear1=2-fyear1+int(fyear1/4);
            fyear2=int((yer2-1)/100);
            syear2=2-fyear2+int(fyear2/4);
            theyer1=int(365.25*(yer1-1))+int(30.6001*(mnth1+13))+fyear1+day1+1720995;
            theyer2=int(365.25*(yer2-1))+int(30.6001*(mnth2+13))+syear2+day2+1720995;
            
         }
         else
         {
            fyear1=int(yer1/100);
            fyear1=2-fyear1+(int(fyear1/4));
            syear2=int(yer2/100);
            syear2=2-syear2+(int(syear2/4));
            theyer1=int(365.25*(yer1))+int(30.6001*(mnth1+1))+fyear1+day1+1720995;
            theyer2=int(365.25*(yer2))+int(30.6001*(mnth2+1))+syear2+day2+1720995;
            
         }
         return abs(theyer1-theyer2);
    
    }

  2. #2
    The larch
    Join Date
    May 2006
    Posts
    3,573
    I haven't used the <ctime> header a lot, but with the help of references I came up with something as the following:
    Code:
    #include <iostream>
    #include <ctime>
    #include <cmath>
    
    std::time_t get_date(int year, int month, int day)
    {
        std::tm a;
        a.tm_sec = 0;
        a.tm_min = 0;
        a.tm_hour = 0;
        a.tm_mday = day;
        a.tm_mon = month - 1;
        a.tm_year = year - 1900;
        a.tm_isdst = 0;
        return std::mktime(&a);
    }
    
    int main()
    {
        std::cout << 
        std::abs((int)std::difftime( get_date(2004, 1, 1), get_date(2005, 1, 1))/(60*60*24))
        << '\n';
    }
    Not sure if boost has something easier to use.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  3. #3
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Very nice code. I just have one thing to say about it: if ints were 16 bits, then that would wrap after a mere 9.10194444 hours: http://www.google.ca/search?hl=en&q=...G=Search&meta=

    With 32-bit ints, you're safe for 68.0962597 years. http://www.google.ca/search?hl=en&q=...G=Search&meta=

    On the other hand, why risk this at all? Simply use this and away you go.
    Code:
    std::abs((int)(std::difftime( get_date(2004, 1, 1), get_date(2005, 1, 1))/(60*60*24)))
    Of course, you're then limited to 2^15-1 days (for 16-bit ints). So perhaps modf() would be best.
    Code:
    #include <cmath>
    double days, seconds =
        std::difftime(
            get_date(2004, 1, 1),
            get_date(2005, 1, 1)
        ) / (60*60*24));
    std::modf(seconds, &days);
    Sigh . . . I think I have too much spare time on my hands.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  4. #4
    Registered User
    Join Date
    Oct 2007
    Posts
    9
    Is there a way to write this differently, more simplistic? The codes above seem a little complex for me. I don't want to come off like an expert or something but I feel that my code isn't right, that it can be written differently. Either shorten it a little bit or do the calculations differently.

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Use the approach that anon posted, but write your own function which assigns a "day number" to both dates, which gets called twice in your function.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  6. #6
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    I agree, us anon's example, or some other library function that does date/time calculations.
    Code:
    theyer1=int(365.25*(yer1))+int(30.6001*(mnth1+1))+fyear1+day1+1720995;
    Have you tested this for all sorts of arbitrary calculations of short and long date intervals, gapping over leap years and non-leapyears, etc, etc.

    By the way, there's a bunch of duplication in your code. The first thing I would do is to convert your common for first and second year calculation into one function:
    Code:
    int dayNo(int y, int m, int d)
    {
         int yoff = 0;
         int moff = 1;
         int fy, sy;
         if (m == 1 || m == 2) 
         {
             yoff = 1;
             moff = 13;
         }
         fy = (y - 1) / 100;
         sy = 2 - fy + (fy / 4);
         return int(365.25*(y - yoff)+int(30.6001*(m+moff)) + sy + d = 1720995;
    }
    I removed a bunch of "int()" since the calculation itself is done completely in integer in the first place, it doesn't need to be "int()" around it - it's already done automagically by the compiler (or rather the processor - but by the compiler choosing integer math operations).

    I also used a few local variables to avoid having an almost identical calculation twice. It makes it easier to read the code, and it's easier to change ONE long complicated calculation than to do two different calculations.


    Using this function makes it much easier to produce the days funciton:
    Code:
    int days (int yer2,int yer1,int mnth2,int mnth1,int day1,int day2)
    {
         int theyer1 = dayNo(yer1, mnth1, day1);
         int theyer2 = dayNo(yer2, mnth2, day2);
    
         return abs(theyer1-theyer2);
    }

    I'm also dubious to the code in red below:
    Code:
            fyear1=int((yer1-1)/100);
            syear1=2-fyear1+int(fyear1/4);
            fyear2=int((yer2-1)/100);
            syear2=2-fyear2+int(fyear2/4);
              theyer1=int(365.25*(yer1-1))+int(30.6001*(mnth1+13))+fyear1+day1+1720995;
            theyer2=int(365.25*(yer2-1))+int(30.6001*(mnth2+13))+syear2+day2+1720995;
    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Enforcing Machine Code Restrictions?
    By SMurf in forum Tech Board
    Replies: 21
    Last Post: 03-30-2009, 07:34 AM
  2. Obfuscated Code Contest: The Results
    By Stack Overflow in forum Contests Board
    Replies: 29
    Last Post: 02-18-2005, 05:39 PM
  3. Obfuscated Code Contest
    By Stack Overflow in forum Contests Board
    Replies: 51
    Last Post: 01-21-2005, 04:17 PM
  4. Interface Question
    By smog890 in forum C Programming
    Replies: 11
    Last Post: 06-03-2002, 05:06 PM
  5. Replies: 0
    Last Post: 02-21-2002, 06:05 PM