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

timefuncs.cpp

Go to the documentation of this file.
00001 //---------------------------------------------------------------------------
00002 #if defined(_Windows) || defined(_WINNT)
00003 #include <sys\timeb.h>  // ftime
00004 #include <windows.h> // Sleep()
00005 #else
00006 #include <stdlib.h> // fprintf -- DELETE THIS LINE AFTER UNIX CODE TESTED
00007 #include <errno.h>  // errno
00008 #endif
00009 
00010 #include <stdio.h>
00011 #include <time.h>
00012 
00013 #include "timefuncs.h"
00014 #include <worm_exceptions.h>
00015 
00016 //---------------------------------------------------------------------------
00017 
00018 #pragma package(smart_init)
00019 
00020 const char TTimeFuncs::DOW[7][4] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
00021 
00022 const char TTimeFuncs::MOY[12][4] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
00023 
00024 const short TTimeFuncs::MONTH_STARTS[2][12] =
00025 {
00026    { 1, 32, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 }
00027   ,{ 1, 32, 61, 92, 122, 153, 183, 214, 245, 275, 306, 336 }
00028 };
00029 
00030 //---------------------------------------------------------------------------
00031 HIGHRES_TIME TTimeFuncs::GetHighResTime()
00032 {
00033    HIGHRES_TIME r_time;
00034 #if defined(_WINNT) || defined(_Windows)
00035    timeb _tb;
00036    ftime(&_tb);
00037    r_time = (double)_tb.time + (double)_tb.millitm / 1000.0;
00038 #else
00039 static bool _needdebugwarning = true;
00040 if ( _needdebugwarning )
00041 {
00042    fprintf( stdout, "TTimeFuncs::GetHighResTime() NOT YET TESTED ON UNIX" );
00043    _needdebugwarning = false;
00044 }
00045    struct timespec _ts;
00046 
00047    if( clock_gettime( CLOCK_REALTIME, &_ts ) == 0 )
00048    {
00049       r_time = (double) _ts.tv_sec + (double)_ts.tv_nsec*0.000000001;
00050    }
00051 #endif
00052    return r_time;
00053 }
00054 //---------------------------------------------------------------------------
00055 char* TTimeFuncs::DateString( char* r_buffer
00056                             , WORM_TIME_FORMAT p_format
00057                             , WORM_TIME_LOCALE p_locale /* = WORM_GMT_TIME */
00058                             , double p_time             /* = -1.0, means 'now' */
00059                             )
00060 {
00061    time_t   _lowtime;
00062    int      _millis = 0;
00063 
00064    // Only use high-resolution time for those formats that require it
00065    switch ( p_format )
00066    {
00067      case WORM_TIMEFMT_8:
00068      case WORM_TIMEFMT_14:
00069      case WORM_TIMEFMT_16:
00070      case WORM_TIMEFMT_UTC21:
00071      case WORM_TIMEFMT_19:
00072      case WORM_TIMEFMT_26:
00073           if ( p_time == -1.0 )
00074           {
00075              _lowtime = time(NULL);
00076           }
00077           else
00078           {
00079              _lowtime = (int)p_time;
00080           }
00081           break;
00082      case WORM_TIMEFMT_18:
00083      case WORM_TIMEFMT_23:
00084           if ( p_time == -1.0 )
00085           {
00086              // add .005 to prep for rounding to milliseconds
00087              double _hrtime = GetHighResTime() + 0.005;
00088              // get the standard time type for structure conversion
00089              _lowtime = (time_t)_hrtime;  // strip off decimal portion
00090              _millis  = (int)((_hrtime - _lowtime) * 100.0 );
00091           }
00092           else
00093           {
00094              _lowtime = (time_t)p_time;  // strip off decimal portion
00095              _millis  = (int)((p_time - _lowtime) * 100.0 );
00096           }
00097           break;
00098    }
00099 
00100    struct tm* _tmstruct;
00101 
00102    switch( p_locale )
00103    {
00104      case WORM_GMT_TIME:
00105           _tmstruct = gmtime(&_lowtime);
00106           break;
00107      case WORM_LOCAL_TIME:
00108           _tmstruct = localtime(&_lowtime);
00109           break;
00110    }
00111 
00112    switch( p_format )
00113    {
00114      case WORM_TIMEFMT_18:  // YYYYMMDDhhmmss.sss
00115           sprintf( r_buffer
00116                  , "%4d%02d%02d%02d%02d%02d.%03d"
00117                  ,  _tmstruct->tm_year + 1900
00118                  ,  _tmstruct->tm_mon  + 1
00119                  ,  _tmstruct->tm_mday
00120                  ,  _tmstruct->tm_hour
00121                  ,  _tmstruct->tm_min
00122                  ,  _tmstruct->tm_sec
00123                  , _millis
00124                  );
00125           break;
00126      case WORM_TIMEFMT_UTC21:  // YYYYMMDD_UTC_hh:mm:ss
00127           sprintf( r_buffer
00128                  , "%4d%02d%02d_UTC_%02d:%02d:%02d"
00129                  ,  _tmstruct->tm_year + 1900
00130                  ,  _tmstruct->tm_mon  + 1
00131                  ,  _tmstruct->tm_mday
00132                  ,  _tmstruct->tm_hour
00133                  ,  _tmstruct->tm_min
00134                  ,  _tmstruct->tm_sec
00135                  );
00136           break;
00137      case WORM_TIMEFMT_8:  // YYYYMMDD
00138           sprintf( r_buffer
00139                  , "%4d%02d%02d"
00140                  ,  _tmstruct->tm_year + 1900
00141                  ,  _tmstruct->tm_mon  + 1
00142                  ,  _tmstruct->tm_mday
00143                  );
00144           break;
00145      case WORM_TIMEFMT_14:  // YYYYMMDDhhmmss
00146           sprintf( r_buffer
00147                  , "%4d%02d%02d%02d%02d%02d"
00148                  ,  _tmstruct->tm_year + 1900
00149                  ,  _tmstruct->tm_mon  + 1
00150                  ,  _tmstruct->tm_mday
00151                  ,  _tmstruct->tm_hour
00152                  ,  _tmstruct->tm_min
00153                  ,  _tmstruct->tm_sec
00154                  );
00155           break;
00156      case WORM_TIMEFMT_16:  // YYYY/MM/DD hh:mm
00157           sprintf( r_buffer
00158                  , "%4d/%02d/%02d %02d:%02d"
00159                  ,  _tmstruct->tm_year + 1900
00160                  ,  _tmstruct->tm_mon  + 1
00161                  ,  _tmstruct->tm_mday
00162                  ,  _tmstruct->tm_hour
00163                  ,  _tmstruct->tm_min
00164                  );
00165           break;
00166      case WORM_TIMEFMT_19:  // YYYY/MM/DD hh:mm:ss
00167           sprintf( r_buffer
00168                  , "%4d/%02d/%02d %02d:%02d:%02d"
00169                  ,  _tmstruct->tm_year + 1900
00170                  ,  _tmstruct->tm_mon  + 1
00171                  ,  _tmstruct->tm_mday
00172                  ,  _tmstruct->tm_hour
00173                  ,  _tmstruct->tm_min
00174                  ,  _tmstruct->tm_sec
00175                  );
00176           break;
00177      case WORM_TIMEFMT_23:  // YYYY/MM/DD hh:mm:ss.sss
00178           sprintf( r_buffer
00179                  , "%4d/%02d/%02d %02d:%02d:%02d.%03d"
00180                  ,  _tmstruct->tm_year + 1900
00181                  ,  _tmstruct->tm_mon  + 1
00182                  ,  _tmstruct->tm_mday
00183                  ,  _tmstruct->tm_hour
00184                  ,  _tmstruct->tm_min
00185                  ,  _tmstruct->tm_sec
00186                  , _millis
00187                  );
00188           break;
00189 
00190      case WORM_TIMEFMT_26:
00191           sprintf( r_buffer
00192                  , "%s %s %02d %02d:%02d:%02d %04d\n"
00193                  , DOW[_tmstruct->tm_wday]
00194                  , MOY[_tmstruct->tm_mon]
00195                  ,  _tmstruct->tm_mday
00196                  ,  _tmstruct->tm_hour
00197                  ,  _tmstruct->tm_min
00198                  ,  _tmstruct->tm_sec
00199                  ,  _tmstruct->tm_year + 1900
00200                  );
00201           break;
00202    }
00203 
00204    return r_buffer;
00205 }
00206 //---------------------------------------------------------------------------
00207 double TTimeFuncs::TimeToDouble( const char * p_buffer )
00208 {
00209    double r_dbl;
00210 
00211    if ( p_buffer == NULL )
00212    {
00213       throw worm_exception("TTimeFuncs::TimeToDouble(): string parameter was NULL");
00214    }
00215 
00216    // expecting "YYYYMMDDHHMMSS.sss"
00217    //            0123456789012345678
00218    if ( strlen(p_buffer) != 18 )
00219    {
00220       throw worm_exception("TTimeFuncs::TimeToDouble(): string parameter invalid length");
00221    }
00222 
00223    char _timestr[18];
00224    char _work[5];
00225    char * _stringptr;
00226    struct tm time_check;
00227 
00228 
00229    strcpy( _timestr, p_buffer );
00230 
00231    _stringptr = _timestr;
00232 
00233    // year
00234    strncpy( _work, _stringptr, 4 );
00235    _work[4] = '\0';
00236    time_check.tm_year = atoi(_work) - 1900;
00237 
00238    // month
00239    _stringptr += 4;
00240    strncpy( _work, _stringptr, 2 );
00241    _work[2] = '\0';
00242    time_check.tm_mon  = atoi(_work) - 1;
00243 
00244    // day
00245    _stringptr += 2;
00246    strncpy( _work, _stringptr, 2 );
00247    time_check.tm_mday = atoi(_work);
00248 
00249    // hour
00250    _stringptr += 2;
00251    strncpy( _work, _stringptr, 2 );
00252    time_check.tm_hour = atoi(_work);
00253 
00254    // minute
00255    _stringptr += 2;
00256    strncpy( _work, _stringptr, 2 );
00257    time_check.tm_min = atoi(_work);
00258 
00259    // second
00260    _stringptr += 2;
00261    strncpy( _work, _stringptr, 2 );
00262    time_check.tm_sec = atoi(_work);
00263 
00264    time_check.tm_isdst = -1;
00265 
00266 
00267    // millisecond
00268    _stringptr += 3;
00269    strncpy( _work, _stringptr, 3 );
00270 
00271 
00272    r_dbl = (double)mktime(&time_check) + ((double)atoi(_work) / 1000.0);
00273 
00274    return r_dbl;
00275 }
00276 //---------------------------------------------------------------------------
00277 void TTimeFuncs::MSecSleep( unsigned int p_msec )
00278 {
00279 #if defined(_WINNT) || defined(_Windows)
00280    Sleep(p_msec);
00281 #else
00282    struct timespec sleeptime;
00283    struct timespec timeleft;
00284    int err;
00285 
00286    sleeptime.tv_sec = (time_t) p_msec / 1000;
00287    sleeptime.tv_nsec = (long) (1000000 * (p_msec % 1000));
00288 
00289    while( nanosleep(&sleeptime, &timeleft) != 0 )
00290    {
00291       if ( (err = errno) == EINTR)
00292       {
00293         /*printf( "sleep_ew: interrupted by signal;" );*//*DEBUG*/ 
00294         /*printf( " %d msec left\n",
00295                 (int) (timeleft.tv_sec*1000 + timeleft.tv_nsec/1000000) );*//*DEBUG*/
00296         sleeptime = timeleft;
00297       }
00298       else
00299       {
00300          fprintf(stderr, "sleep_ew: error from nanosleep: %s\n",
00301                  strerror(err));
00302          fprintf(stderr,"\ttime requested = %.3f sec, time left = %.3f sec\n",
00303                  sleeptime.tv_sec + sleeptime.tv_nsec*1.e-9,
00304                  timeleft.tv_sec + timeleft.tv_nsec*1.e-9);
00305        }
00306    }
00307 #endif
00308 }
00309 //---------------------------------------------------------------------------
00310 bool TTimeFuncs::IsLeapyear( unsigned int p_year )
00311 {
00312    if ( p_year % 4 != 0 )
00313    {
00314       return false;
00315    }
00316 
00317    if ( p_year % 400 == 0 )
00318    {
00319       return true;
00320    }
00321 
00322    if ( p_year % 100 == 0 )
00323    {
00324       return false;
00325    }
00326 
00327    return true;
00328 }
00329 //---------------------------------------------------------------------------
00330 bool TTimeFuncs::YearJulianToMonDay( short   p_year
00331                                    , short   p_julday
00332                                    , short * r_monthnum
00333                                    , short * r_monthday
00334                                    )
00335 {
00336    if (   p_julday < 1
00337        || r_monthnum == NULL
00338        || r_monthday == NULL
00339       )
00340    {
00341       return false;
00342    }
00343 
00344    // get MONTH_STARTS[x][] index
00345    int _yt =  ( IsLeapyear(p_year) ? 1 : 0 );
00346    int _mi = 0;
00347 
00348    for ( int _m = 0 ; _m < 12 ; _m++ )
00349    {
00350       if ( MONTH_STARTS[_yt][_m] <= p_julday )
00351       {
00352          _mi = _m;
00353          continue;
00354       }
00355       break;
00356    }
00357 
00358    *r_monthday = p_julday - MONTH_STARTS[_yt][_mi] + 1;
00359 
00360    *r_monthnum = _mi + 1;
00361 
00362    return true;
00363 }
00364 //---------------------------------------------------------------------------
00365 bool TTimeFuncs::CrackDate( const char * p_buffer    // "YYYYMMDD...."
00366                           , short      * r_year      // 1900....
00367                           , short      * r_monthnum  // 1 - 12
00368                           , short      * r_monthday  // 1 - 31
00369                           , short      * r_year2     // 0....
00370                           , short      * r_julday    // 1 - 366
00371                           , bool       * r_isleap    // is it a leap year
00372                           )
00373 {
00374    if (   p_buffer == NULL || strlen(p_buffer) < 8
00375        || r_year     == NULL
00376        || r_monthnum == NULL
00377        || r_monthday == NULL
00378       )
00379    {
00380       return false;
00381    }
00382 
00383    bool _isleap;
00384 
00385    char _wrk[9];
00386 
00387    //  YYYYMMDD....
00388    //  012345678
00389 
00390    strncpy( _wrk, p_buffer, 8 );
00391    _wrk[8] = '\0';
00392 
00393    *r_monthday = atoi( _wrk + 6 );
00394 
00395 
00396    _wrk[6] = '\0';
00397 
00398    *r_monthnum = atoi( _wrk + 4 );
00399 
00400 
00401    _wrk[4] = '\0';
00402 
00403    *r_year = atoi( _wrk );
00404 
00405    if ( r_year2 != NULL )
00406    {
00407       *r_year2 = atoi( _wrk + 2 );
00408    }
00409 
00410    if ( r_julday != NULL )
00411    {
00412       _isleap = IsLeapyear( *r_year );
00413 
00414       if ( r_isleap != NULL )
00415       {
00416          *r_isleap = _isleap;
00417       }
00418 
00419       *r_julday = TTimeFuncs::MONTH_STARTS[(_isleap ? 1 : 0)][(*r_monthnum) - 1]
00420                 + *r_monthday
00421                 - 1
00422               ;
00423    }
00424 
00425    return true;
00426 }
00427 //---------------------------------------------------------------------------
00428 bool TTimeFuncs::CrackTime( const char * p_buffer // "HHMMSS.sss" or "........HHMMSS.sss"
00429                           , short      * r_hour
00430                           , short      * r_min
00431                           , short      * r_sec
00432                           , short      * r_msec
00433                           , double     * r_fpsec
00434                           )
00435 {
00436    if ( p_buffer == NULL || r_hour == NULL || r_min == NULL )
00437    {
00438       return false;
00439    }
00440 
00441    if ( strlen(p_buffer) != 10 && strlen(p_buffer) != 18 )
00442    {
00443       return false;
00444    }
00445 
00446    const char  * _pointer = ( strlen(p_buffer) == 10 ? p_buffer : (p_buffer + 8) );
00447 
00448    char   _wrk[4];
00449 
00450    if ( _pointer[6] != '.' )
00451    {
00452       return false;
00453    }
00454 
00455    _wrk[0] = _pointer[0];
00456    _wrk[1] = _pointer[1];
00457    _wrk[2] = '\0';
00458    *r_hour = atoi(_wrk);
00459 
00460 
00461    _wrk[0] = _pointer[2];
00462    _wrk[1] = _pointer[3];
00463    _wrk[2] = '\0';
00464    *r_min = atoi(_wrk);
00465 
00466    if ( r_sec != NULL )
00467    {
00468       int _sec
00469         , _msec
00470         ;
00471 
00472       _wrk[0] = _pointer[4];
00473       _wrk[1] = _pointer[5];
00474       _wrk[2] = '\0';
00475       _sec = atoi(_wrk);
00476 
00477       if ( r_sec != 0 )
00478       {
00479          *r_sec = _sec;
00480       }
00481 
00482       _wrk[0] = _pointer[7];
00483       _wrk[1] = _pointer[8];
00484       _wrk[2] = _pointer[9];
00485       _wrk[3] = '\0';
00486       _msec = atoi(_wrk);
00487 
00488       if ( r_msec != 0 )
00489       {
00490          *r_msec = _msec;
00491       }
00492 
00493       if ( r_fpsec != NULL && r_msec != 0 )
00494       {
00495          *r_msec = (double)_sec + ((double)_msec) / 1000.0;
00496       }
00497    }
00498 
00499    return true;
00500 }
00501 //---------------------------------------------------------------------------
00502 

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