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