home *** CD-ROM | disk | FTP | other *** search
/ nisttime.carsoncity.k12.mi.us / nisttime.carsoncity.k12.mi.us.tar / nisttime.carsoncity.k12.mi.us / pub / daytime / adjclk.c next >
Text File  |  1996-11-18  |  4KB  |  185 lines

  1. void adjclk(xdiff,cmos,ldst)
  2. double xdiff;        /*difference to apply to local clock*/
  3. int cmos;        /*cmos clock present if 1 */
  4. int ldst;        /*daylight saving time observed if 1 */
  5. {
  6. #include <stdio.h>
  7. #include <dos.h>
  8. /*
  9.     this subroutine adjusts the time of the local clock
  10.     by algebraically adding xdiff seconds to it so that
  11.     if xdiff is negative the local clock is retarded.
  12.  
  13.     if cmos = 1, then the cmos clock is adjusted as well.
  14. */
  15. int mm;
  16. int iday,ihr,imin,isec,ihun;    /*adjustment broken into bits*/
  17. int hribm,minibm,secibm,hunibm;    /*bits of the local time */
  18. int yribm,moibm,dayibm;        /*bits of the local date */
  19. int centc,yrc,moc,dayc,hrc,minc,secc;  /*bits of cmos time*/
  20. int lday[13]={0,31,28,31,30,31,30,31,31,30,31,30,31}; /*days in each mon*/
  21. char cnvbcd(int);        /*converts integers to packed BCD*/
  22. /*
  23.     break correction down into days, hours, ...
  24.     note that all corrections except for the days can only
  25.     be +/- 1 or 0, but that the days correction can be
  26.     arbitrarily large.
  27. */
  28.     iday= (int) (xdiff/86400l);
  29.     xdiff -= 86400l*(long int)iday;
  30.     ihr= (int) (xdiff/3600);
  31.     xdiff -= 3600l*(long int)ihr;
  32.     imin= (int) (xdiff/60);
  33.     xdiff -= 60*imin;
  34.     isec= (int) xdiff;
  35.     xdiff -= isec;
  36.     ihun= 100*xdiff;
  37. /*
  38.     get local time and add correction. start with the
  39.     least significant part of the time and deal with
  40.     overflows into the next unit of the time if needed.
  41.     note that even a small time correction can ripple
  42.     through all of the units if it is made near the
  43.     end of the day.
  44.  
  45.     note this this process may result in losing 1 tick
  46.     on the local machine since a tick may happen in the
  47.     time between the clock is read and the corrected
  48.     value is put back.
  49. */
  50.     _AH=0x2c;
  51.     geninterrupt(0x21);
  52.     hribm=_CH;
  53.     minibm=_CL;
  54.     secibm=_DH;
  55.     hunibm=_DL;
  56.     _AH=0x2a;
  57.     geninterrupt(0x21);
  58.     yribm=_CX;
  59.     moibm=_DH;
  60.     dayibm=_DL;
  61. /*
  62.     begin corrections
  63. */
  64.     hunibm += ihun + 3;    /*round up one-half tick */
  65.     if(hunibm > 99)
  66.         {
  67.         hunibm -= 100;
  68.         secibm++;
  69.     }
  70.     if(hunibm < 0)
  71.         {
  72.         hunibm += 100;
  73.         secibm--;
  74.     }
  75.     secibm += isec;
  76.     if(secibm > 59)
  77.         {
  78.         secibm -= 60;
  79.         minibm++;
  80.     }
  81.     if(secibm < 0)
  82.         {
  83.         secibm += 60;
  84.         minibm--;
  85.     }
  86.     minibm += imin;
  87.     if(minibm > 59)
  88.         {
  89.         minibm -= 60;
  90.         hribm++;
  91.     }
  92.     if(minibm < 0)
  93.         {
  94.         minibm += 60;
  95.         hribm--;
  96.     }
  97.     hribm += ihr;
  98.     if(hribm > 23)
  99.         {
  100.         hribm -= 24;
  101.         dayibm++;
  102.     }
  103.     if(hribm < 0)
  104.         {
  105.         hribm += 24;
  106.         dayibm--;
  107.     }
  108.     dayibm += iday;
  109.     while(dayibm < 1)    /*if pushed back to previous month*/
  110.         {
  111.         moibm--;    /*back up 1 month*/
  112.         if(moibm < 1)    /*if month is pushed before Jan*/
  113.             {
  114.             moibm=12;        /*set december of previous year*/
  115.             yribm--;
  116.         }
  117.         dayibm += lday[moibm];  /*add days of this month*/
  118. /*
  119.         feb. has 29 days if year-1900 is evenly divisible
  120.         by 4
  121. */
  122.         if( (        moibm == 2       )  &&
  123.              ( ( (yribm-1900) & 3) == 0) ) dayibm++;
  124.     }
  125. /*
  126.     compute last day of this month, watching out for feb.
  127.     in a leap year.  then see if the correction has pushed
  128.     us into the next month.
  129. */
  130.     mm=lday[moibm];
  131.     if( (moibm == 2)  && ( ( (yribm-1900) & 3) == 0) ) mm++;
  132.     while(dayibm > mm)
  133.         {
  134.         dayibm -= mm;
  135.         moibm++;        /*advance to next month*/
  136.         if(moibm > 12)    /*and to next year if needed*/
  137.             {
  138.             moibm=1;
  139.             yribm++;
  140.         }
  141.         mm=lday[moibm];
  142.         if( (moibm == 2) && ( ( (yribm-1900) & 3) ==0) ) mm++;
  143.     }
  144. /*
  145.     now set local clock to this corrected time
  146. */
  147.     _AH=0x2d;
  148.     _CH=hribm;
  149.     _DH=secibm;
  150.     _CL=minibm;
  151.     _DL=hunibm;
  152.     geninterrupt(0x21);
  153.     _AH=0x2b;
  154.     _CX=yribm;
  155.     _DH=moibm;
  156.     _DL=dayibm;
  157.     geninterrupt(0x21);
  158. /*
  159.     set cmos clock if needed. otherwise we are done.
  160. */
  161.     if(cmos == 0) return;
  162. /*
  163.     convert time to packed bcd
  164. */
  165.     centc=cnvbcd(yribm/100);
  166.     yrc=cnvbcd(yribm%100);
  167.     moc=cnvbcd(moibm);
  168.     dayc=cnvbcd(dayibm);
  169.     hrc=cnvbcd(hribm);
  170.     minc=cnvbcd(minibm);
  171.     if(hunibm > 50) secibm++;    /*round to nearest second*/
  172.     secc=cnvbcd(secibm);
  173.     _AH=3;
  174.     _CH=hrc;
  175.     _CL=minc;
  176.     _DH=secc;
  177.     _DL=ldst;
  178.     geninterrupt(0x1a);
  179.     _AH=5;
  180.     _CH=centc;
  181.     _CL=yrc;
  182.     _DH=moc;
  183.     _DL=dayc;
  184.     geninterrupt(0x1a);
  185. }