00001
00002
00003 #include "ace/OS_NS_time.h"
00004
00005 ACE_RCSID(ace, OS_NS_time, "$Id: OS_NS_time.cpp 79134 2007-07-31 18:23:50Z johnnyw $")
00006
00007 #if !defined (ACE_HAS_INLINED_OSCALLS)
00008 # include "ace/OS_NS_time.inl"
00009 #endif
00010
00011 #if defined (ACE_LACKS_STRPTIME)
00012 # include "ace/os_include/os_ctype.h"
00013 #endif
00014
00015 #include "ace/OS_NS_Thread.h"
00016 #include "ace/Object_Manager_Base.h"
00017
00018 #if defined (ACE_HAS_WINCE)
00019 # include "ace/OS_NS_stdio.h"
00020
00021 namespace
00022 {
00023 ACE_TCHAR const * const ACE_OS_day_of_week_name[] =
00024 {
00025 ACE_TEXT ("Sun"),
00026 ACE_TEXT ("Mon"),
00027 ACE_TEXT ("Tue"),
00028 ACE_TEXT ("Wed"),
00029 ACE_TEXT ("Thu"),
00030 ACE_TEXT ("Fri"),
00031 ACE_TEXT ("Sat")
00032 };
00033
00034 ACE_TCHAR const * const ACE_OS_month_name[] =
00035 {
00036 ACE_TEXT ("Jan"),
00037 ACE_TEXT ("Feb"),
00038 ACE_TEXT ("Mar"),
00039 ACE_TEXT ("Apr"),
00040 ACE_TEXT ("May"),
00041 ACE_TEXT ("Jun"),
00042 ACE_TEXT ("Jul"),
00043 ACE_TEXT ("Aug"),
00044 ACE_TEXT ("Sep"),
00045 ACE_TEXT ("Oct"),
00046 ACE_TEXT ("Nov"),
00047 ACE_TEXT ("Dec")
00048 };
00049
00050 static ACE_TCHAR const ACE_OS_CTIME_R_FMTSTR[] = ACE_TEXT ("%3s %3s %02d %02d:%02d:%02d %04d\n");
00051 }
00052 #endif
00053
00054 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00055
00056 # if defined (ACE_HAS_WINCE)
00057 ACE_TCHAR *
00058 ACE_OS::ctime_r (const time_t *clock, ACE_TCHAR *buf, int buflen)
00059 {
00060
00061 if (buflen < 26)
00062 {
00063 errno = ERANGE;
00064 return 0;
00065 }
00066
00067
00068
00069 ULARGE_INTEGER _100ns;
00070 _100ns.QuadPart = (DWORDLONG) *clock * 10000 * 1000
00071 + ACE_Time_Value::FILETIME_to_timval_skew;
00072 FILETIME file_time;
00073 file_time.dwLowDateTime = _100ns.LowPart;
00074 file_time.dwHighDateTime = _100ns.HighPart;
00075
00076 FILETIME localtime;
00077 SYSTEMTIME systime;
00078 FileTimeToLocalFileTime (&file_time, &localtime);
00079 FileTimeToSystemTime (&localtime, &systime);
00080 ACE_OS::sprintf (buf, ACE_OS_CTIME_R_FMTSTR,
00081 ACE_OS_day_of_week_name[systime.wDayOfWeek],
00082 ACE_OS_month_name[systime.wMonth - 1],
00083 systime.wDay,
00084 systime.wHour,
00085 systime.wMinute,
00086 systime.wSecond,
00087 systime.wYear);
00088 return buf;
00089 }
00090 # endif
00091
00092 # if defined (ACE_LACKS_DIFFTIME)
00093 double
00094 ACE_OS::difftime (time_t t1, time_t t0)
00095 {
00096
00097 struct tm tms[2], *ptms[2], temp;
00098 double seconds;
00099 int swap = 0;
00100
00101
00102 ptms[1] = ::gmtime_r (&t1, &tms[1]);
00103 if (ptms[1] == 0) return 0.0;
00104
00105 ptms[0] = ::gmtime_r (&t0, &tms[0]);
00106 if (ptms[0] == 0) return 0.0;
00107
00108
00109 if (tms[1].tm_year < tms[0].tm_year)
00110 swap = 1;
00111 else if (tms[1].tm_year == tms[0].tm_year)
00112 {
00113 if (tms[1].tm_yday < tms[0].tm_yday)
00114 swap = 1;
00115 else if (tms[1].tm_yday == tms[0].tm_yday)
00116 {
00117 if (tms[1].tm_hour < tms[0].tm_hour)
00118 swap = 1;
00119 else if (tms[1].tm_hour == tms[0].tm_hour)
00120 {
00121 if (tms[1].tm_min < tms[0].tm_min)
00122 swap = 1;
00123 else if (tms[1].tm_min == tms[0].tm_min)
00124 {
00125 if (tms[1].tm_sec < tms[0].tm_sec)
00126 swap = 1;
00127 }
00128 }
00129 }
00130 }
00131
00132 if (swap)
00133 temp = tms[0], tms[0] = tms[1], tms[1] = temp;
00134
00135 seconds = 0.0;
00136 if (tms[1].tm_year > tms[0].tm_year)
00137 {
00138
00139 seconds = 60 - tms[0].tm_sec;
00140 tms[0].tm_sec = 0;
00141 tms[0].tm_min += 1;
00142 seconds += 60 * (60 - tms[0].tm_min);
00143 tms[0].tm_min = 0;
00144 tms[0].tm_hour += 1;
00145 seconds += 60*60 * (24 - tms[0].tm_hour);
00146 tms[0].tm_hour = 0;
00147 tms[0].tm_yday += 1;
00148
00149 # define ISLEAPYEAR(y) ((y)&3u?0:(y)%25u?1:(y)/25u&12?0:1)
00150
00151 if (ISLEAPYEAR(tms[0].tm_year))
00152 seconds += 60*60*24 * (366 - tms[0].tm_yday);
00153 else
00154 seconds += 60*60*24 * (365 - tms[0].tm_yday);
00155
00156 tms[0].tm_yday = 0;
00157 tms[0].tm_year += 1;
00158
00159 while (tms[1].tm_year > tms[0].tm_year)
00160 {
00161 if (ISLEAPYEAR(tms[0].tm_year))
00162 seconds += 60*60*24 * 366;
00163 else
00164 seconds += 60*60*24 * 365;
00165
00166 tms[0].tm_year += 1;
00167 }
00168
00169 # undef ISLEAPYEAR
00170
00171 }
00172 else
00173 {
00174
00175 if (tms[1].tm_sec < tms[0].tm_sec)
00176 {
00177 if (tms[1].tm_min == 0)
00178 {
00179 if (tms[1].tm_hour == 0)
00180 {
00181 tms[1].tm_yday -= 1;
00182 tms[1].tm_hour += 24;
00183 }
00184 tms[1].tm_hour -= 1;
00185 tms[1].tm_min += 60;
00186 }
00187 tms[1].tm_min -= 1;
00188 tms[1].tm_sec += 60;
00189 }
00190 tms[1].tm_sec -= tms[0].tm_sec;
00191
00192 if (tms[1].tm_min < tms[0].tm_min)
00193 {
00194 if (tms[1].tm_hour == 0)
00195 {
00196 tms[1].tm_yday -= 1;
00197 tms[1].tm_hour += 24;
00198 }
00199 tms[1].tm_hour -= 1;
00200 tms[1].tm_min += 60;
00201 }
00202 tms[1].tm_min -= tms[0].tm_min;
00203
00204 if (tms[1].tm_hour < tms[0].tm_hour)
00205 {
00206 tms[1].tm_yday -= 1;
00207 tms[1].tm_hour += 24;
00208 }
00209 tms[1].tm_hour -= tms[0].tm_hour;
00210
00211 tms[1].tm_yday -= tms[0].tm_yday;
00212 }
00213
00214
00215 seconds += tms[1].tm_sec;
00216 seconds += 60 * tms[1].tm_min;
00217 seconds += 60*60 * tms[1].tm_hour;
00218 seconds += 60*60*24 * tms[1].tm_yday;
00219
00220 return seconds;
00221 }
00222 # endif
00223
00224 struct tm *
00225 ACE_OS::localtime_r (const time_t *t, struct tm *res)
00226 {
00227 ACE_OS_TRACE ("ACE_OS::localtime_r");
00228 #if defined (ACE_HAS_REENTRANT_FUNCTIONS)
00229 # if defined (DIGITAL_UNIX)
00230 ACE_OSCALL_RETURN (::_Plocaltime_r (t, res), struct tm *, 0);
00231 # else
00232 ACE_OSCALL_RETURN (::localtime_r (t, res), struct tm *, 0);
00233 # endif
00234 #elif defined (ACE_HAS_TR24731_2005_CRT)
00235 ACE_SECURECRTCALL (localtime_s (res, t), struct tm *, 0, res);
00236 return res;
00237 #elif !defined (ACE_HAS_WINCE)
00238 ACE_OS_GUARD
00239
00240 ACE_UNUSED_ARG (res);
00241 struct tm * res_ptr;
00242 ACE_OSCALL (::localtime (t), struct tm *, 0, res_ptr);
00243 if (res_ptr == 0)
00244 return 0;
00245 else
00246 {
00247 *res = *res_ptr;
00248 return res;
00249 }
00250 #elif defined (ACE_HAS_WINCE)
00251
00252
00253
00254
00255 TIME_ZONE_INFORMATION pTz;
00256
00257 const unsigned short int __mon_yday[2][13] =
00258 {
00259
00260 { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
00261
00262 { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
00263 };
00264
00265 ULARGE_INTEGER _100ns;
00266 ::GetTimeZoneInformation (&pTz);
00267
00268 _100ns.QuadPart = (DWORDLONG) *t * 10000 * 1000 + ACE_Time_Value::FILETIME_to_timval_skew;
00269 FILETIME file_time;
00270 file_time.dwLowDateTime = _100ns.LowPart;
00271 file_time.dwHighDateTime = _100ns.HighPart;
00272
00273 FILETIME localtime;
00274 SYSTEMTIME systime;
00275 FileTimeToLocalFileTime (&file_time, &localtime);
00276 FileTimeToSystemTime (&localtime, &systime);
00277
00278 res->tm_hour = systime.wHour;
00279
00280 if(pTz.DaylightBias!=0)
00281 res->tm_isdst = 1;
00282 else
00283 res->tm_isdst = 1;
00284
00285 int iLeap;
00286 iLeap = (res->tm_year % 4 == 0 && (res->tm_year% 100 != 0 || res->tm_year % 400 == 0));
00287
00288
00289 res->tm_mday = systime.wDay;
00290 res->tm_min = systime.wMinute;
00291 res->tm_mon = systime.wMonth - 1;
00292 res->tm_sec = systime.wSecond;
00293 res->tm_wday = systime.wDayOfWeek;
00294 res->tm_yday = __mon_yday[iLeap][systime.wMonth] + systime.wDay;
00295 res->tm_year = systime.wYear;
00296 res->tm_year = res->tm_year - 1900;
00297
00298 return res;
00299 #else
00300
00301
00302 ACE_UNUSED_ARG (t);
00303 ACE_UNUSED_ARG (res);
00304 ACE_NOTSUP_RETURN (0);
00305 #endif
00306 }
00307
00308 time_t
00309 ACE_OS::mktime (struct tm *t)
00310 {
00311 ACE_OS_TRACE ("ACE_OS::mktime");
00312 # if defined (ACE_HAS_WINCE)
00313 SYSTEMTIME t_sys;
00314 FILETIME t_file;
00315 t_sys.wSecond = t->tm_sec;
00316 t_sys.wMinute = t->tm_min;
00317 t_sys.wHour = t->tm_hour;
00318 t_sys.wDay = t->tm_mday;
00319 t_sys.wMonth = t->tm_mon + 1;
00320 t_sys.wYear = t->tm_year + 1900;
00321 t_sys.wDayOfWeek = t->tm_wday;
00322 if (SystemTimeToFileTime (&t_sys, &t_file) == 0)
00323 return -1;
00324 ACE_Time_Value tv (t_file);
00325 return tv.sec ();
00326 # else
00327 # if defined (ACE_HAS_THREADS) && !defined (ACE_HAS_MT_SAFE_MKTIME)
00328 ACE_OS_GUARD
00329 # endif
00330
00331 ACE_OSCALL_RETURN (ACE_STD_NAMESPACE::mktime (t), time_t, (time_t) -1);
00332 # endif
00333 }
00334
00335 #if defined (ACE_HAS_POWERPC_TIMER) && defined (ghs)
00336 void
00337 ACE_OS::readPPCTimeBase (u_long &most, u_long &least)
00338 {
00339 ACE_OS_TRACE ("ACE_OS::readPPCTimeBase");
00340
00341
00342
00343
00344
00345 asm("aclock:");
00346 asm("mftb r5,TBU");
00347 asm("mftb r6,TBL");
00348 asm("mftb r7,TBU");
00349 asm("cmpw r5,r7");
00350 asm("bne aclock");
00351
00352 asm("stw r5, 0(r3)");
00353 asm("stw r6, 0(r4)");
00354 }
00355 #endif
00356
00357 #if defined (ACE_LACKS_STRPTIME) && !defined (ACE_REFUSE_STRPTIME_EMULATION)
00358 char *
00359 ACE_OS::strptime_emulation (const char *buf, const char *format, struct tm *tm)
00360 {
00361 int bi = 0;
00362 int fi = 0;
00363 int percent = 0;
00364
00365 if (!buf || !format)
00366 return 0;
00367
00368 while (format[fi] != '\0')
00369 {
00370 if (percent)
00371 {
00372 percent = 0;
00373 switch (format[fi])
00374 {
00375 case '%':
00376 if (buf[bi] == '%')
00377 {
00378 fi++; bi++;
00379 }
00380 else
00381 return const_cast<char*> (buf + bi);
00382 break;
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411 case 'd':
00412
00413 case 'e':
00414 if (!ACE_OS::strptime_getnum
00415 (buf + bi, &tm->tm_mday, &bi, &fi, 1, 31))
00416 return const_cast<char*> (buf + bi);
00417
00418 break;
00419
00420 case 'D':
00421 if (!ACE_OS::strptime_getnum
00422 (buf + bi, &tm->tm_mon, &bi, &fi, 1, 12))
00423 return const_cast<char*> (buf + bi);
00424
00425 fi--;
00426 tm->tm_mon--;
00427
00428 if (buf[bi] != '/')
00429 return const_cast<char*> (buf + bi);
00430
00431 bi++;
00432
00433 if (!ACE_OS::strptime_getnum
00434 (buf + bi, &tm->tm_mday, &bi, &fi, 1, 31))
00435 return const_cast<char*> (buf + bi);
00436
00437 fi--;
00438 if (buf[bi] != '/')
00439 return const_cast<char*> (buf + bi);
00440 bi++;
00441 if (!ACE_OS::strptime_getnum
00442 (buf + bi, &tm->tm_year, &bi, &fi, 0, 99))
00443 return const_cast<char*> (buf + bi);
00444 if (tm->tm_year < 69)
00445 tm->tm_year += 100;
00446 break;
00447
00448 case 'H':
00449
00450 case 'k':
00451 if (!ACE_OS::strptime_getnum
00452 (buf + bi, &tm->tm_hour, &bi, &fi, 0, 23))
00453 return const_cast<char*> (buf + bi);
00454 break;
00455
00456
00457
00458
00459
00460
00461
00462
00463 case 'j':
00464 if (!ACE_OS::strptime_getnum
00465 (buf + bi, &tm->tm_yday, &bi, &fi, 1, 366))
00466 return const_cast<char*> (buf + bi);
00467
00468 tm->tm_yday--;
00469 break;
00470
00471 case 'm':
00472 if (!ACE_OS::strptime_getnum
00473 (buf + bi, &tm->tm_mon, &bi, &fi, 1, 12))
00474 return const_cast<char*> (buf + bi);
00475
00476 tm->tm_mon--;
00477 break;
00478
00479 case 'M':
00480 if (!ACE_OS::strptime_getnum
00481 (buf + bi, &tm->tm_min, &bi, &fi, 0, 59))
00482 return const_cast<char*> (buf + bi);
00483
00484 break;
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496 case 'R':
00497 if (!ACE_OS::strptime_getnum
00498 (buf + bi, &tm->tm_hour, &bi, &fi, 0, 23))
00499 return const_cast<char*> (buf + bi);
00500
00501 fi--;
00502 if (buf[bi] != ':')
00503 return const_cast<char*> (buf + bi);
00504 bi++;
00505 if (!ACE_OS::strptime_getnum
00506 (buf + bi, &tm->tm_min, &bi, &fi, 0, 59))
00507 return const_cast<char*> (buf + bi);
00508
00509 break;
00510
00511 case 'S':
00512 if (!ACE_OS::strptime_getnum
00513 (buf + bi, &tm->tm_sec, &bi, &fi, 0, 61))
00514 return const_cast<char*> (buf + bi);
00515 break;
00516
00517 case 'T':
00518 if (!ACE_OS::strptime_getnum
00519 (buf + bi, &tm->tm_hour, &bi, &fi, 0, 23))
00520 return const_cast<char*> (buf + bi);
00521
00522 fi--;
00523 if (buf[bi] != ':')
00524 return const_cast<char*> (buf + bi);
00525 bi++;
00526 if (!ACE_OS::strptime_getnum
00527 (buf + bi, &tm->tm_min, &bi, &fi, 0, 59))
00528 return const_cast<char*> (buf + bi);
00529
00530 fi--;
00531 if (buf[bi] != ':')
00532 return const_cast<char*> (buf + bi);
00533 bi++;
00534 if (!ACE_OS::strptime_getnum
00535 (buf + bi, &tm->tm_sec, &bi, &fi, 0, 61))
00536 return const_cast<char*> (buf + bi);
00537
00538 break;
00539
00540 case 'w':
00541 if (!ACE_OS::strptime_getnum
00542 (buf + bi, &tm->tm_wday, &bi, &fi, 0, 6))
00543 return const_cast<char*> (buf + bi);
00544
00545 break;
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557 case 'y':
00558 if (!ACE_OS::strptime_getnum
00559 (buf + bi, &tm->tm_year, &bi, &fi, 0, 99))
00560 return const_cast<char*> (buf + bi);
00561
00562 if (tm->tm_year < 69)
00563 tm->tm_year += 100;
00564 break;
00565
00566 case 'Y':
00567 if (!ACE_OS::strptime_getnum
00568 (buf + bi, &tm->tm_year, &bi, &fi, 0, 0))
00569 return const_cast<char*> (buf + bi);
00570
00571 tm->tm_year -= 1900;
00572 break;
00573
00574 default:
00575 return const_cast<char*> (buf + bi);
00576 }
00577
00578 }
00579 else
00580 {
00581 if (format[fi] == '%')
00582 {
00583 percent = 1;
00584 fi++;
00585 }
00586 else
00587 {
00588 if (format[fi] == buf[bi])
00589 {
00590 fi++;
00591 bi++;
00592 }
00593 else
00594 return const_cast<char*> (buf + bi);
00595 }
00596 }
00597 }
00598
00599 return const_cast<char*> (buf + bi);
00600 }
00601
00602 int
00603 ACE_OS::strptime_getnum (const char *buf,
00604 int *num,
00605 int *bi,
00606 int *fi,
00607 int min,
00608 int max)
00609 {
00610 int i = 0, tmp = 0;
00611
00612 while (isdigit (buf[i]))
00613 {
00614 tmp = (tmp * 10) + (buf[i] - '0');
00615 if (max && (tmp > max))
00616 return 0;
00617 i++;
00618 }
00619
00620 if (tmp < min)
00621 return 0;
00622 else if (i)
00623 {
00624 *num = tmp;
00625 (*fi)++;
00626 *bi += i;
00627 return 1;
00628 }
00629 else
00630 return 0;
00631 }
00632 #endif
00633
00634 ACE_END_VERSIONED_NAMESPACE_DECL