Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

chron3.c

Go to the documentation of this file.
00001 
00002 /*
00003  *   THIS FILE IS UNDER RCS - DO NOT MODIFY UNLESS YOU HAVE
00004  *   CHECKED IT OUT USING THE COMMAND CHECKOUT.
00005  *
00006  *    $Id: chron3_8c-source.html 2161 2006-05-19 16:55:03Z paulf $
00007  *
00008  *    Revision history:
00009  *     $Log$
00009  *     Revision 1.1  2006/05/19 16:55:01  paulf
00009  *     first inclusion
00009  *
00010  *     Revision 1.1  2000/02/14 18:51:48  lucky
00011  *     Initial revision
00012  *
00013  *
00014  */
00015 
00016 #include <stdio.h>
00017 #include <time.h>
00018 #include <sys/types.h>
00019 #include <chron3.h>
00020 /*
00021    chron3.c : Time/date conversion routines.
00022 
00023    91May07 CEJ Version 1.0 - chron.c, chron.h
00024 
00025    Modified by W. Kohler, March 8, 1993.
00026    Source file name changed from chron.c to chron2.c.
00027    Include file name changed from chron.h to chron2.h.
00028    Routine datime added to calculate gregorian date and time from
00029    julian seconds.  Seconds added to structure Greg in file chron2.h.
00030 
00031    Modified by L. Dietz,  March 30, 1995.
00032    Source file name changed from chron2.c to chron3.c.
00033    Include file name changed from chron2.h to chron3.h.
00034    Routines date15 and julsec15 added to convert between time in
00035    julian seconds and character strings.
00036    Added a define statement to set the century (#define CENTURY 1900)
00037 
00038    Modified by L. Dietz, January 30, 1995.
00039    Added routine epochsec15 to convert from time given in a
00040    15-character string and seconds since 1970-01-01 00:00:00.0 GMT.
00041 
00042    Modified by L. Dietz, October, 1998.
00043    Changed make the library Y2K-compliant. 
00044    + Removed the CENTURY definition from chron3.h! 
00045    + Removed all functions that dealt with 2-digit-year date strings 
00046      and replaced them with 4-digit-year counterparts.
00047         date15     -> date17
00048         date18     -> date20
00049         julsec15   -> julsec17
00050         epochsec15 -> epochsec17
00051         timegm     -> timegm (fixed to call epochsec17)
00052 
00053    Modified by L. Dietz, November, 1998.
00054    Changed to make function MT-safe.  
00055    Eliminated the file-global "struct Greg G" workspace and had each function 
00056    declare its own "struct Greg" variable, if needed.  Changed function
00057    arguments for grg(), gregor(), and datime() to include a pointer to 
00058    struct Greg for returning information to calling function.
00059 
00060 */
00061 
00062 /*********************C O P Y R I G H T   N O T I C E ***********************/
00063 /* Copyright 1991 by Carl Johnson.  All rights are reserved. Permission     */
00064 /* is hereby granted for the use of this product for nonprofit, commercial, */
00065 /* or noncommercial publications that contain appropriate acknowledgement   */
00066 /* of the author. Modification of this code is permitted as long as this    */
00067 /* notice is included in each resulting source module.                      */
00068 /****************************************************************************/
00069 
00070 int mo[] = {   0,  31,  59,  90, 120, 151, 181, 212, 243, 273, 304, 334,
00071                0,  31,  60,  91, 121, 152, 182, 213, 244, 274, 305, 335};
00072 char *cmo[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
00073                "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
00074 
00075 /*
00076  * Calculate julian minute from gregorian date and time.
00077  */
00078 long julmin( struct Greg *pg )
00079 {
00080         return(1440L * (julian(pg) - 2305448L) + 60L * pg->hour + pg->minute);
00081 }
00082 
00083 /*
00084  * Calculate gregorian date and time from julian minutes.
00085  */
00086 struct Greg *grg( long min, struct Greg *pg )
00087 {
00088         long j;
00089         long m;
00090 
00091         j = min/1440L;
00092         m = min-1440L*j;
00093         j += 2305448L;
00094         gregor(j,pg);
00095         pg->hour = m/60;
00096         pg->minute = m - 60 * pg->hour;
00097         return(pg);
00098 }
00099 
00100 /*
00101  * julian : Calculate julian date from gregorian date.
00102  */
00103 long julian( struct Greg *pg )
00104 {
00105         long jul;
00106         int leap;
00107         int year;
00108         int n;
00109 
00110         jul = 0;
00111         year = pg->year;
00112         if(year < 1) goto x110;
00113         year--;
00114         jul = 365;
00115 
00116 /* four hundred year rule */
00117         n = year / 400;
00118         jul += n * 146097L;
00119         year -= n * 400;
00120 
00121 /* hundred year rule */
00122         n = year / 100;
00123         jul += n * 36524L;
00124         year -= n * 100;
00125 
00126 /* four year rule */
00127         n = year / 4;
00128         jul += n * 1461L;
00129         year -= n * 4;
00130 
00131 /* one year rule */
00132         jul += year * 365L;
00133 
00134 /* Handle days in current year */
00135 x110:
00136         leap = 0;
00137         if(pg->year % 4   == 0) leap = 12;
00138         if(pg->year % 100 == 0) leap = 0;
00139         if(pg->year % 400 == 0) leap = 12;
00140         jul += mo[pg->month + leap - 1] + pg->day + 1721060L;
00141         return(jul);
00142 }
00143 
00144 /*
00145  * gregor : Calculate gregorian date from julian date.
00146  */
00147 struct Greg *gregor( long min, struct Greg *pg )
00148 {
00149         long test;
00150         long check;
00151         int leap;
00152         int left;
00153         int imo;
00154 
00155         pg->year = (min - 1721061L) / 365L;
00156         pg->month = 1;
00157         pg->day = 1;
00158         test = julian(pg);
00159         if(test <= min) goto x110;
00160 
00161 x20:
00162         pg->year--;
00163         test = julian(pg);
00164         if(test > min) goto x20;
00165         goto x210;
00166 
00167 x105:
00168         pg->year++;
00169         test = julian(pg);
00170 
00171 x110:
00172         check = test - min - 366L;
00173         if(check < 0) goto x210;
00174         if(check > 0) goto x105;
00175 
00176         if(pg->year % 400 == 0) goto x210;
00177         if(pg->year % 100 == 0) goto x105;
00178         if(pg->year %   4 == 0) goto x210;
00179         goto x105;
00180 
00181 x210:
00182         left = min - test;
00183         leap = 0;
00184         if(pg->year %   4 == 0) leap = 12;
00185         if(pg->year % 100 == 0) leap = 0;
00186         if(pg->year % 400 == 0) leap = 12;
00187         for(imo=1; imo<12; imo++) {
00188                 if(mo[imo+leap] <= left)
00189                         continue;
00190                 pg->month = imo;
00191                 pg->day = left - mo[imo+leap-1] + 1;
00192                 return(pg);
00193         }
00194         pg->month = 12;
00195         pg->day = left - mo[11+leap] + 1;
00196         return(pg);
00197 }
00198 
00199 /*
00200  * date20 : Create 20 char date string in the form 1988Jan23 1234 12.21
00201  *          from the julian seconds.  Remember to leave space for the
00202  *          string termination (NULL).
00203  *          Replaces non-Y2K-compliant date18() function
00204  *          Added to chron3.c 10/28/98 by LDD.
00205  */
00206 void date20( double secs, char *c20)
00207 {
00208         struct Greg g;
00209         long minute;
00210         double sex;
00211         int hrmn;
00212 
00213         minute = (long) (secs / 60.0);
00214         sex = secs - 60.0 * minute;
00215         grg(minute, &g);
00216         hrmn = 100 * g.hour + g.minute;
00217         sprintf(c20, "%04d%3s%2d %4d%6.2f",
00218                 g.year, cmo[g.month-1], g.day, hrmn, sex);
00219 }
00220 
00221 /*
00222  * tnow : Returns current system time for time stamping
00223  */
00224 double tnow( void )
00225 {
00226         struct Greg g;
00227 /*      struct timeb q; */
00228         time_t tsecs;
00229         double secs;
00230 
00231         g.year   = 1970;
00232         g.month  = 1;
00233         g.day    = 1;
00234         g.hour   = 0;
00235         g.minute = 0;
00236 /* original code by Carl; ftime() not supported on Sparc C compiler 3.0.1 */
00237 /*      ftime(&q);                                              */
00238 /*      secs = 60.0 * julmin(&g) + q.time +  0.001 * q.millitm; */
00239         time(&tsecs);                                   /*950501:ldd.*/
00240         secs = 60.0 * julmin(&g) + (double) tsecs;      /*950501:ldd.*/
00241         return secs;
00242 }
00243 
00244 /*
00245  * Calculate gregorian date and time from julian seconds.
00246  */
00247 struct Greg *datime( double secs, struct Greg *pg )
00248 {
00249         long j, m, min;
00250 
00251         min = (long) (secs / 60.0);
00252         j = min/1440L;
00253         m = min-1440L*j;
00254         j += 2305448L;
00255         gregor(j,pg);
00256         pg->hour = m/60;
00257         pg->minute = m - 60 * pg->hour;
00258         pg->second = (float) (secs - 60.0 * min);
00259         return(pg);
00260 }
00261 
00262 /*
00263  * date17 : Build a 17 char date string in the form 19880123123412.21
00264  *          from the julian seconds.  Remember to leave space for the
00265  *          string termination (NULL).
00266  *          Replaces the non-Y2K-compliant date15() function.
00267  *          Added to chron3.c on 10/28/98 by LDD
00268  */
00269 void date17( double secs, char *c17 )
00270 {
00271         struct Greg g;
00272         long minute;
00273         double sex;
00274 
00275         minute = (long) (secs / 60.0);
00276         sex = secs - 60.0 * (double) minute;
00277         grg(minute,&g);
00278         sprintf(c17, "%04d%02d%02d%02d%02d%05.2f\0",
00279                 g.year, g.month, g.day, g.hour, g.minute, sex);
00280 }
00281 
00282 /*
00283  * julsec17 : Calculate time in julian seconds from a character string
00284  *            of the form 19880123123412.21
00285  *            Replaces the non-Y2K-compliant julsec15() function.
00286  *            Added to chron3.c on 10/28/98 by LDD
00287  */
00288 double julsec17( char *c17 )
00289 {
00290         struct Greg  g;
00291         double       jsecs;
00292         int          narg, i;
00293         int          isec, hsec;
00294 
00295 /*** Make sure there are no blanks in the time part of the pick ***/
00296         for(i=0; i<17; i++)
00297         {
00298                 if( c17[i] == ' ' )  c17[i] = '0';
00299         }
00300 
00301 /***  Read character string  ***/
00302         narg = sscanf( c17, "%4d%2d%2d%2d%2d%2d.%2d",
00303                         &g.year, &g.month, &g.day,
00304                         &g.hour, &g.minute, &isec, &hsec);
00305 
00306         if ( narg < 7 )  return( 0.0 );
00307 
00308 
00309 /***  Calculate julian seconds ***/
00310         jsecs   = 60.0 * (double) julmin(&g) +
00311                          (double) isec +
00312                          (double) hsec / 100.0;
00313 
00314         return( jsecs );
00315 }
00316 
00317 /*
00318  * epochsec17 :  Convert time in a character string form of
00319  *               ccyymmddhhmmss.ff (19880231010155.23) to
00320  *               seconds since 1970-01-01 00:00:00.0
00321  *               Replaces the non-Y2K-compliant epochsec15() function.
00322  *               Added to chron3.c on 10/28/98 by LDD
00323  */
00324 int epochsec17( double *sec, char *tstr )
00325 {
00326    double jsec;
00327 
00328    jsec = julsec17( tstr );
00329    if( jsec==0.0 )
00330    {
00331       *sec=0.0;
00332       return ( -1 );
00333    }
00334 
00335    *sec = jsec-GSEC1970;
00336    return ( 0 );
00337 }
00338 
00339 /*
00340  * timegm :  Convert time as a struct tm to seconds since 1970-01-01 00:00:00.0
00341  *           This function is equivalent to timegm() in SunOS 4.x.
00342  *           Added to chron3.c on 2/27/98 by WMK
00343  *           Modified to be Y2K compliant 10/28/98 by LDD
00344  */
00345 time_t timegm( struct tm *tm )
00346 {
00347    char   tstr[18];
00348    double dsec;
00349 
00350    sprintf( tstr, "%04d%02d%02d%02d%02d%02d.00",
00351             tm->tm_year + 1900,
00352             tm->tm_mon + 1,
00353             tm->tm_mday,
00354             tm->tm_hour,
00355             tm->tm_min,
00356             tm->tm_sec );
00357 
00358    epochsec17( &dsec, tstr );
00359    return( (time_t)dsec );
00360 }
00361 

Generated on Tue May 6 09:16:00 2003 for Earthworm Libs by doxygen1.3-rc3