home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1994 #1 / monster.zip / monster / PROG_C / SNIP9404.ZIP / SCALDATE.C < prev    next >
C/C++ Source or Header  |  1994-04-03  |  1KB  |  50 lines

  1. /*
  2. ** scalar date routines    --    public domain by Ray Gardner
  3. ** These will work over the range 1/01/01 thru 14699/12/31
  4. */
  5.  
  6. #include "scaldate.h"
  7.  
  8. int isleap (unsigned yr)
  9. {
  10.    return yr % 400 == 0 || (yr % 4 == 0 && yr % 100 != 0);
  11. }
  12.  
  13. static unsigned months_to_days (unsigned month)
  14. {
  15.    return (month * 3057 - 3007) / 100;
  16. }
  17.  
  18. static long years_to_days (unsigned yr)
  19. {
  20.    return yr * 365L + yr / 4 - yr / 100 + yr / 400;
  21. }
  22.  
  23. long ymd_to_scalar (unsigned yr, unsigned mo, unsigned day)
  24. {
  25.    long scalar;
  26.    scalar = day + months_to_days(mo);
  27.    if ( mo > 2 )                         /* adjust if past February */
  28.       scalar -= isleap(yr) ? 1 : 2;
  29.    yr--;
  30.    scalar += years_to_days(yr);
  31.    return scalar;
  32. }
  33.  
  34. void scalar_to_ymd (long scalar, unsigned *yr, unsigned *mo, unsigned *day)
  35. {
  36.    unsigned n;                /* compute inverse of years_to_days() */
  37.  
  38.    for ( n = (unsigned)((scalar * 400L) / 146097); years_to_days(n) < scalar;)
  39.       n++;                          /* 146097 == years_to_days(400) */
  40.    *yr = n;
  41.    n = (unsigned)(scalar - years_to_days(n-1));
  42.    if ( n > 59 ) {                       /* adjust if past February */
  43.       n += 2;
  44.       if ( isleap(*yr) )
  45.          n -= n > 62 ? 1 : 2;
  46.    }
  47.    *mo = (n * 100 + 3007) / 3057;    /* inverse of months_to_days() */
  48.    *day = n - months_to_days(*mo);
  49. }
  50.