00001
00002 #if defined(_Windows) || defined(_WINNT)
00003 #include <sys\timeb.h>
00004 #include <windows.h>
00005 #else
00006 #include <stdlib.h>
00007 #include <errno.h>
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
00058 , double p_time
00059 )
00060 {
00061 time_t _lowtime;
00062 int _millis = 0;
00063
00064
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
00087 double _hrtime = GetHighResTime() + 0.005;
00088
00089 _lowtime = (time_t)_hrtime;
00090 _millis = (int)((_hrtime - _lowtime) * 100.0 );
00091 }
00092 else
00093 {
00094 _lowtime = (time_t)p_time;
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:
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:
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:
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:
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:
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:
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:
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
00217
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
00234 strncpy( _work, _stringptr, 4 );
00235 _work[4] = '\0';
00236 time_check.tm_year = atoi(_work) - 1900;
00237
00238
00239 _stringptr += 4;
00240 strncpy( _work, _stringptr, 2 );
00241 _work[2] = '\0';
00242 time_check.tm_mon = atoi(_work) - 1;
00243
00244
00245 _stringptr += 2;
00246 strncpy( _work, _stringptr, 2 );
00247 time_check.tm_mday = atoi(_work);
00248
00249
00250 _stringptr += 2;
00251 strncpy( _work, _stringptr, 2 );
00252 time_check.tm_hour = atoi(_work);
00253
00254
00255 _stringptr += 2;
00256 strncpy( _work, _stringptr, 2 );
00257 time_check.tm_min = atoi(_work);
00258
00259
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
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
00294
00295
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
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
00366 , short * r_year
00367 , short * r_monthnum
00368 , short * r_monthday
00369 , short * r_year2
00370 , short * r_julday
00371 , bool * r_isleap
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
00388
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
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