home *** CD-ROM | disk | FTP | other *** search
/ nisttime.carsoncity.k12.mi.us / nisttime.carsoncity.k12.mi.us.tar / nisttime.carsoncity.k12.mi.us / pub / acts / diftim.c < prev    next >
C/C++ Source or Header  |  1997-12-08  |  12KB  |  493 lines

  1. void diftim(buf)
  2. char buf[280];
  3. {
  4. #include "nistime.h"
  5. #include <stdio.h>
  6. #ifdef IBMPC
  7. #include <dos.h>
  8. #endif
  9. char c;
  10. float xx,interp();                /* holds tick fraction */
  11. int j,yr,mo,day,hr,min,sec,dst;   /* holds parsed NIST time */
  12. int yribm,moibm,dayibm,hribm,minibm,secibm,hunibm; /* holds computer time */
  13. #ifdef IBMPC
  14. int yrat,moat,dayat,hrat,minat,secat;/* holds CMOS time for AT*/
  15. #endif
  16. int iterr = 0;
  17. float diff;                  /* holds time difference */
  18. float elapse;                  /* days since last comparison */
  19. float ddiff;                   /* difference of difference in sec */
  20. #ifdef IBMPC
  21. float adiff;                   /* same for IBMPC CMOS clock */
  22. #endif
  23. #ifdef IBMPC
  24. extern int utcdif;           /* local time - utc in hours */
  25. extern int dsflag;           /* daylight saving time? 1=yes, 0=no */
  26. extern int atflag;           /* AT-type machine? 1=yes, 0=no */
  27. int lday[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31}; /*last day of month*/
  28. #endif
  29. static int tday[13] = {0,0,31,59,90,120,151,181,212,243,273,304,334};
  30. int done = 0;         /* flag to show when comparison is complete */
  31. extern int wrtdif;    /*1=write dif to file, 0=don't 2=get rate too */
  32. extern int debug;     /* 1=debug on, 0=debug off */
  33. char *ptrslw,*ptrfas,*ptrrat;   /*output format strings*/
  34. #ifdef IBMPC
  35. int unpbcd();
  36. int dsdone=0;                /* flag to show conversion for daylight sav.*/
  37. #endif
  38. #ifdef SUN
  39. #include <sys/time.h>
  40. struct timeval tvv,*tp;
  41. struct tm gvv,*gv;
  42. extern int hs;               /*1 if dialing at 1200, 0 if at 300 */
  43. LONG cvt2jd();           /*computes MJD from yr-mo-dy*/
  44. #endif
  45. /*
  46.     the following structure holds the values computed the last
  47.     time the program was run as read to estimate the rate offset
  48.     of the clock.  the values are read by getlst() from the last
  49.     line in file nistime.dif if "A" mode was selected.  if "a" mode
  50.     was selected, this structure is not used.
  51. */
  52. extern struct tmprev
  53.     {
  54.     int yrprev;     /* time of previous comparison in first 6 values*/
  55.     int moprev;
  56.     int dyprev;
  57.     int hrprev;
  58.     int mnprev;
  59.     int scprev;
  60.     float dffprv;   /* value of difference followed by unts*/
  61.     char unprev;
  62. #ifdef IBMPC
  63.     float datprv;   /* difference and units for IBMPC CMOS clock*/
  64.     char uatprv;
  65. #endif
  66. } tmpp;
  67.     ptrslw="\n Computer clock slow by %.3f %s\n";
  68.     ptrfas="\n Computer clock fast by %.3f %s\n";
  69.     ptrrat="\n Approximate rate offset= %.3f sec/day.\n";
  70. /*
  71.     this subroutine receives a time string in character
  72.     array buf.  it is parsed and compared with the system
  73.     clock.  the origin of the parser is the - character between
  74.     the year and the month so that leading stuff will simply be
  75.     ignored.
  76.  
  77.     the IBMPC version performs the comparison using local time
  78.     this subroutine uses global variables dsflag to check for
  79.     daylight savings time and utcdif to convert from UTC to local
  80.     time
  81.  
  82.     the SUN version performs the comparison using UTC directly
  83.     since that is available from the system
  84.  
  85.  
  86.     begin by getting computer time now.
  87. */
  88. #ifdef IBMPC
  89.     _AH=0x2c;
  90.     geninterrupt(0x21);
  91.     hribm=_CH;
  92.     minibm=_CL;
  93.     secibm=_DH;
  94.     hunibm=_DL;
  95. /*
  96.     also get tick fraction now for interpolating later
  97. */
  98.     xx=interp();
  99.     _AH=0x2a;
  100.     geninterrupt(0x21);
  101.     yribm=_CX;
  102.     moibm=_DH;
  103.     dayibm=_DL;
  104.     yribm -= 1900; /*number of years since 1900*/
  105. /*
  106.     if this is an at-type machine, read CMOS clock too
  107. */
  108.     if(atflag != 0)
  109.     {
  110.     _AH=2;
  111.     geninterrupt(0x1a);
  112.     hrat=_CH;
  113.     minat=_CL;
  114.     secat=_DH;
  115.     _AH=4;
  116.     geninterrupt(0x1a);
  117.     yrat=_CL;
  118.     moat=_DH;
  119.     dayat=_DL;
  120.     }
  121. #endif
  122. #ifdef SUN
  123.     tp= &tvv;
  124.     gv= &gvv;
  125.     gettimeofday(tp,0);
  126. /*
  127.     get tick fraction from interp
  128. */
  129.     xx=interp();
  130.     gv=gmtime(tp);
  131.     yribm=gv->tm_year;
  132.     moibm=gv->tm_mon + 1;
  133.     dayibm=gv->tm_mday;
  134.     hribm=gv->tm_hour;
  135.     minibm=gv->tm_min;
  136.     secibm=gv->tm_sec;
  137.     hunibm=tp->tv_usec/10000;
  138. #endif
  139. /*
  140.     now parse line from NIST transmission
  141.     the year is expressed as the number of years since 1900.
  142.     if the received value is less than 80 then assume that it 
  143.     signals a year after 2000 since the ACTS systems didn't
  144.     exist in 1980.
  145. */
  146.     for(j=0; (buf[j] != 0) && (buf[j] != '-') ; j++) ;
  147.     sscanf(&buf[j-2],"%2d-%2d-%2d %2d:%2d:%2d %d",&yr,&mo,&day,
  148.     &hr,&min,&sec,&dst);
  149.     if(yr < 80) yr += 100;    /*number of years since 1900*/
  150. /*
  151.     for IBMPC version, convert to local time and
  152.     daylight savings time if necessary
  153.  
  154.     note that this conversion is not necessary for the
  155.     SUN which performs the comparison directly on UTC
  156. */
  157. #ifdef IBMPC
  158. /*
  159.     make standard-time portion of dst flag contiguous
  160. */
  161.     if(dst == 0) dst = 100;
  162. /*
  163.     convert from utc to local time. note that minute and second
  164.     are already correct.
  165.     daylight savings time flag must also be updated
  166.     if conversion to local time changes the day
  167.  
  168. */
  169.     if( (yr & 3) == 0 ) lday[2]=29;  /* 29 days for Feb in leap year */
  170.     hr += utcdif;                    /* convert hour to local time */
  171. /*
  172.     also do first part of conversion to daylight savings time
  173.     see parset and arcdif where same problem is dealt with
  174. */
  175.     if( (dsflag != 0) && (dst <= 50) && (dst > 1) )
  176.     {
  177.     hr++;
  178.     dsdone=1;
  179.     }
  180.     if(hr < 0)
  181.     {
  182.     hr += 24;
  183.     day--;
  184.     dst++;         /* update daylight savings flag for change of day*/
  185.     if(day < 1)
  186.        {
  187.        mo--;
  188.        if(mo < 1)
  189.           {
  190.           mo=12;
  191.           yr--;
  192.           }
  193.        day=lday[mo];
  194.        }
  195.     }
  196.     if(hr > 23)
  197.     {
  198.     hr -= 24;
  199.     day++;
  200.     dst--;        /* update daylight saving flag for change of day */
  201.     if(day > lday[mo])
  202.        {
  203.        day=1;
  204.        mo++;
  205.        if(mo > 12)
  206.           {
  207.           mo=1;
  208.           yr++;
  209.           }
  210.        }
  211.     }
  212. /*
  213.     now finish up daylight savings time if enabled
  214. */
  215.     if( (dsflag != 0) && (dsdone == 0) )
  216.     {
  217.        if( (dst == 51) && (hr >= 2) ) hr++;
  218.        if( (dst ==  1) && (hr <  2) ) hr++;
  219.     }
  220. #endif
  221. /*
  222.     ready to begin comparing the clocks
  223.     first print out both times
  224. */
  225.     printf("\n Computer time= %2d-%2.2d-%2.2d %2.2d:%2.2d:%2.2d.%2.2d",
  226.           yribm%100,moibm,dayibm,hribm,minibm,secibm,hunibm);
  227.     printf("\n NIST time    = %2d-%2.2d-%2.2d %2.2d:%2.2d:%2.2d.00",
  228.           yr%100,mo,day,hr,min,sec);
  229.     diff=365*(yribm - yr) + tday[moibm] - tday[mo] + dayibm - day;
  230.     if( ( (yribm & 3) == 0)  && (moibm > 2) ) diff++;
  231.     if( ( (yr    & 3) == 0)  && (mo    > 2) ) diff--;
  232. /*
  233.     compute time since last comparison if "A" mode was selected
  234.     time is computed as days and fractions
  235. */
  236.     if(wrtdif == 2)
  237.        {
  238.        elapse=365*(yr - tmpp.yrprev) +tday[mo] - tday[tmpp.moprev]
  239.         + day - tmpp.dyprev;
  240.        if( ( (yr & 3) == 0)  && (mo  >2) ) elapse++;
  241.        if( ( (tmpp.yrprev & 3) == 0) && (tmpp.moprev > 2) )elapse--;
  242.        elapse += ( (float) (hr - tmpp.hrprev) )/24. +
  243.              ( (float) (min -tmpp.mnprev) )/1440. +
  244.              ( (float) (sec -tmpp.scprev) )/86400.;
  245.        if(debug != 0) printf("\n time since last comparison=%f",elapse);
  246. /*
  247.     convert difference last time to seconds if necessary
  248. */
  249.     switch(tmpp.unprev)
  250.           {
  251.           case 'd':
  252.         ddiff = 86400.*tmpp.dffprv;
  253.         break;
  254.           case 'h':
  255.         ddiff = 3600.*tmpp.dffprv;
  256.         break;
  257.           case 'm':
  258.         ddiff = 60.*tmpp.dffprv;
  259.         break;
  260.           case 's':
  261.         ddiff=tmpp.dffprv;
  262.         break;
  263.           default:
  264.         printf("\n Units of difference= %c, not d,h,m,s.",
  265.             tmpp.unprev);
  266.         break;
  267.           }
  268.     if(debug != 0) printf("\n previous difference= %f sec.",ddiff);
  269.        }
  270.     if(diff > 1)
  271.     {
  272.     printf(ptrfas,diff,"days.");
  273.     done=1;
  274.     }
  275.     if(diff < -1)
  276.     {
  277.     printf(ptrslw,-diff,"days.");
  278.     done=1;
  279.     }
  280. /*
  281.     if difference has been printed as days and rate estimate
  282.     is selected, print value now
  283. */
  284.     if( (wrtdif == 2) && (done == 1) )
  285.        {
  286.        ddiff = (86400.*diff - ddiff)/elapse;
  287.        printf(ptrrat,ddiff);
  288.        }
  289.     if(done == 0)
  290.     {
  291.        diff= 24*diff + hribm - hr;
  292.        if(diff > 2)
  293.        {
  294.           printf(ptrfas,diff,"hours.");
  295.           done=1;
  296.        }
  297.        if(diff < -2)
  298.        {
  299.           printf(ptrslw,-diff,"hours.");
  300.           done=1;
  301.        }
  302.        if( (wrtdif == 2) && (done == 1) )
  303.         {
  304.         ddiff=(3600.*diff - ddiff)/elapse;
  305.         printf(ptrrat,ddiff);
  306.         }
  307.     }
  308.     if(done == 0)
  309.     {
  310.        diff=60*diff + minibm - min;
  311.        if(diff > 10)
  312.        {
  313.        printf(ptrfas,diff,"minutes.");
  314.        done=1;
  315.        }
  316.        if(diff < -10)
  317.        {
  318.        printf(ptrslw,-diff,"minutes.");
  319.        done=1;
  320.        }
  321.        if( (wrtdif == 2) && (done == 1) )
  322.         {
  323.         ddiff=(60.*diff - ddiff)/elapse;
  324.         printf(ptrrat,ddiff);
  325.         }
  326.     }
  327.     if(done == 0)
  328.     {
  329.        diff=60*diff + secibm - sec +  0.01*(float)hunibm;
  330. /*
  331.     Add the fraction of a tick computed by interp.  this value
  332.     tends to make the local clock later, since this value must be
  333.     added to the integer values read from the system.
  334.     If this is a SUN system, the interval between ticks is defined 
  335.     in the header file nistime.h.  It is typically 20 msec on a Sun, 
  336.     10 msec on a VAX and 3906 usec on a DEC RISC machine.  This number
  337.     is always given in microseconds and is converted to seconds
  338.     here.  Note that the value in paretheses is a tick fraction
  339.     expressed as a percent.  All MS DOS machines uses the same clock
  340.     rate of roughly 18.2 ticks/second or about 55 msec betweek
  341.     ticks.
  342. */
  343. #ifdef IBMPC
  344.        diff +=  0.000549*(100-xx);
  345. #endif
  346. #ifdef SUN
  347.        diff += ( (double) tickus) *(100-xx)*1e-8;
  348. #endif
  349.        if(diff > 0)
  350.           {
  351.           printf(ptrfas,diff,"seconds.");
  352. #ifdef IBMPC
  353.           iterr= 18.2*diff;
  354. #endif
  355.           }
  356.        if(diff < 0)
  357.           {
  358.           printf(ptrslw,-diff,"seconds.");
  359. #ifdef IBMPC
  360.           iterr= -18.2*diff;
  361. #endif
  362.           }
  363. #ifdef IBMPC
  364.        if(iterr == 0)
  365.           printf("\nClocks agree to within 1 computer clock tick.\n");
  366.        else
  367.           printf("\nDifference is %d computer clock tick(s). \n",iterr);
  368. #endif
  369. #ifdef SUN
  370.        if(diff == 0)
  371.         printf("\n Clocks agree to within 10 msec. \n");
  372. #endif
  373.        if(wrtdif == 2)
  374.         {
  375.         ddiff= (diff - ddiff)/elapse;
  376.         printf(ptrrat,ddiff);
  377.         }
  378.     }
  379. #ifdef IBMPC
  380.     if(atflag == 0)return;
  381.     printf("\n\nCompare time of CMOS (Battery-run) Clock with NIST.\n");
  382. /*
  383.     begin comparison of CMOS time -- first convert from packed
  384.     BCD to normal binary, then compare as above.
  385. */
  386.     yrat=unpbcd(yrat);
  387.     if(yrat < 80) yrat += 100;        /*years since 1900*/
  388.     moat=unpbcd(moat);
  389.     dayat=unpbcd(dayat);
  390.     hrat=unpbcd(hrat);
  391.     minat=unpbcd(minat);
  392.     secat=unpbcd(secat);
  393.     printf("\nCMOS time= %2.2d-%2.2d-%2.2d %2.2d:%2.2d:%2.2d",
  394.     yrat%100,moat,dayat,hrat,minat,secat);
  395.     printf("\nNIST time= %2.2d-%2.2d-%2.2d %2.2d:%2.2d:%2.2d",
  396.     yr%100,mo,day,hr,min,sec);
  397.     diff=365*(yrat - yr) + tday[moat] - tday[mo] + dayat - day;
  398.     if( ( (yrat & 3) == 0) && (moat > 2) )  diff++;
  399.     if( ( (yr   & 3) == 0) && (mo   > 2) )  diff--;
  400. /*
  401.     if rate estimate was selected, convert previous difference
  402.     to seconds if necessary
  403. */
  404.     if(wrtdif == 2)
  405.        {
  406.        switch(tmpp.uatprv)
  407.         {
  408.         case 'd':
  409.            adiff=86400.*tmpp.datprv;
  410.            break;
  411.         case 'h':
  412.            adiff=3600.*tmpp.datprv;
  413.            break;
  414.         case 'm':
  415.            adiff=60.*tmpp.datprv;
  416.            break;
  417.         case 's':
  418.            adiff=tmpp.datprv;
  419.            break;
  420.         default:
  421.            printf("\n units of difference=%c, not d,h,m,s.",
  422.             tmpp.uatprv);
  423.         }
  424.        }
  425.     done=0;
  426.     if(diff > 1)
  427.     {
  428.        printf(ptrfas,diff,"days.");
  429.        done=1;
  430.     }
  431.     if(diff < -1)
  432.     {
  433.        printf(ptrslw,-diff,"days.");
  434.        done=1;
  435.     }
  436.     if ( (wrtdif == 2) && (done == 1) )
  437.        {
  438.        adiff=(86400.*diff - adiff)/elapse;
  439.        printf(ptrrat,adiff);
  440.        }
  441.     if(done == 0)
  442.     {
  443.     diff=24*diff + hrat - hr;
  444.     if(diff > 2)
  445.        {
  446.        printf(ptrfas,diff,"hours.");
  447.        done=1;
  448.        }
  449.     if(diff < -2)
  450.        {
  451.        printf(ptrslw,-diff,"hours.");
  452.        done=1;
  453.        }
  454.     if( (wrtdif == 2) && (done == 1) )
  455.        {
  456.        ddiff=(3600.*diff - adiff)/elapse;
  457.        printf(ptrrat,adiff);
  458.        }
  459.     }
  460.     if(done == 0)
  461.     {
  462.     diff=60*diff + minat - min;
  463.     if(diff > 10)
  464.        {
  465.        printf(ptrfas,diff,"minutes.");
  466.        done=1;
  467.        }
  468.     if(diff < -10)
  469.        {
  470.        printf(ptrslw,-diff,"minutes.");
  471.        done=1;
  472.        }
  473.     if( (wrtdif == 2) && (done == 1) )
  474.        {
  475.        adiff=(60.*diff - adiff)/elapse;
  476.        printf(ptrrat,adiff);
  477.        }
  478.     }
  479.     if(done == 0)
  480.     {
  481.     diff=60*diff +secat - sec;
  482.     if(diff > 0)  printf(ptrfas,diff,"seconds.");
  483.     if(diff < 0)  printf(ptrslw,-diff,"seconds.");
  484.     if(diff == 0) printf("\n Time agrees to within 1 second.\n");
  485.     if(wrtdif == 2)
  486.        {
  487.        adiff=(diff - adiff)/elapse;
  488.        printf(ptrrat,adiff);
  489.        }
  490.     }
  491. #endif
  492. }
  493.