home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #30 / NN_1992_30.iso / spool / comp / lang / c / 18327 < prev    next >
Encoding:
Internet Message Format  |  1992-12-14  |  2.2 KB

  1. Path: sparky!uunet!mdcbbs!sysjj.mdcbbs.com!lembark
  2. Newsgroups: comp.lang.c
  3. Subject: re: find the number difference of dates
  4. Message-ID: <1992Dec11.103710.1@sysjj.mdcbbs.com>
  5. From: lembark@sysjj.mdcbbs.com
  6. Date: 11 Dec 92 10:37:10 GMT
  7. Organization: EDS Unigraphics, Cypress CA
  8. Nntp-Posting-Host: vxd1
  9. Nntp-Posting-User: eschner
  10. Lines: 58
  11.  
  12. easiest way to find the difference between two days:
  13.  
  14. regardless of leapyears, days in the month, etc: there are always 24 hours in 
  15. a day and 3600 sec in a day.  another nice trick is that the absolute
  16. difference of two numbers in a modular base == (a - b + base ) % base (e.g., 
  17. ( time of day differences: ( hour1 - hour2 + 24 ) % 24 )).
  18.  
  19.     time_t time1, time2;
  20.     time_t n = 3600 * 24, days1 = time1/n, days2 = time2/n;
  21.     time_t max = (time_t)-1/n, diff = (days1 - days2 + maxday) % max;
  22.  
  23. (time_t)-1 works since time_t is normally an unsigned quantity; (time_t)~0 does
  24. the same basic thing (32 bits of 0xFFF... will do the same thing).
  25.  
  26. another approach is to convert both of them to unsigned int's by calculating
  27. the number of days since a particluar date earlier than both (e.g., 1/1/1900)
  28. and take the difference of the result:
  29.  
  30. {     /* somewhere in your code: */
  31.     unsigned days1 = nndate( year1, month1, day1 ),
  32.          days2 = nndate( year2, month2, day2 ),
  33.          difference = days1 < days2 ? days2 - days1 : days1 - days2;
  34. }
  35.  
  36.  
  37. /*
  38.    convert a year, month and day value to number of days since 1/1/BASE_YEAR,
  39.    obvious choices for BASE_YEAR are 1900 [which wasn't a leap year] or 
  40.    1970.  this will only work with julain dates (most of us don't have much
  41.    to do with gregorian dates, however, so that't o.k.).
  42.  
  43.    BASE_YEAR == 1970 => unsigned days has the same time span as
  44.    unsigned long seconds: about 180 years...
  45. */
  46. unsigned nndate( unsigned yy, unsigned mm, unsigned dd )
  47. {
  48.     unsigned nn, i, j;
  49.     unsigned month_days[13][2] =
  50.         { {0,31,28,31,30,31,30,31,31,30,31,30,31},
  51.           {0,31,29,31,30,31,30,31,31,30,31,30,31} };
  52.  
  53.     for( i = BASE_YEAR, nn=0 ; i < yy ; i++ )
  54.         nn+= 365 + leapyr(i);
  55.  
  56.     i = leapyr( i );    /* save repeated calls to leapyr */
  57.     for( j = 0 ; i < mm ; i++ )
  58.         nn+= month_days[j][i];
  59.  
  60.     nn+= dd;
  61.  
  62.     return nn;
  63. }
  64.  
  65. int leapyr( year )
  66. {
  67.     return ( (!(year%4)&&(year%100) || !(year%400) );
  68. }
  69.  
  70.