00001
00002
00003 #include "ace/OS_NS_time.h"
00004
00005 ACE_RCSID(ace, OS_NS_time, "$Id: OS_NS_time.cpp 86094 2009-07-17 19:04:11Z schmidt $")
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 = 0;
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 t_sys.wMilliseconds = 0;
00323 if (SystemTimeToFileTime (&t_sys, &t_file) == 0)
00324 return -1;
00325 ACE_Time_Value tv (t_file);
00326 return tv.sec ();
00327 # else
00328 # if defined (ACE_HAS_THREADS) && !defined (ACE_HAS_MT_SAFE_MKTIME)
00329 ACE_OS_GUARD
00330 # endif
00331
00332 ACE_OSCALL_RETURN (ACE_STD_NAMESPACE::mktime (t), time_t, (time_t) -1);
00333 # endif
00334 }
00335
00336 #if defined (ACE_HAS_POWERPC_TIMER) && defined (ghs)
00337 void
00338 ACE_OS::readPPCTimeBase (u_long &most, u_long &least)
00339 {
00340 ACE_OS_TRACE ("ACE_OS::readPPCTimeBase");
00341
00342
00343
00344
00345
00346 asm("aclock:");
00347 asm("mftb r5,TBU");
00348 asm("mftb r6,TBL");
00349 asm("mftb r7,TBU");
00350 asm("cmpw r5,r7");
00351 asm("bne aclock");
00352
00353 asm("stw r5, 0(r3)");
00354 asm("stw r6, 0(r4)");
00355 }
00356 #endif
00357
00358 #if defined (ACE_LACKS_STRPTIME)
00359 char *
00360 ACE_OS::strptime_emulation (const char *buf, const char *format, struct tm *tm)
00361 {
00362 int bi = 0;
00363 int fi = 0;
00364 bool percent = false;
00365
00366 if (!buf || !format)
00367 return 0;
00368
00369 while (format[fi] != '\0')
00370 {
00371 if (percent)
00372 {
00373 percent = false;
00374 switch (format[fi])
00375 {
00376 case '%':
00377 if (buf[bi] == '%')
00378 {
00379 ++fi;
00380 ++bi;
00381 }
00382 else
00383 return const_cast<char*> (buf + bi);
00384 break;
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
00412
00413 case 'd':
00414
00415 case 'e':
00416 if (!ACE_OS::strptime_getnum
00417 (buf + bi, &tm->tm_mday, &bi, &fi, 1, 31))
00418 return const_cast<char*> (buf + bi);
00419
00420 break;
00421
00422 case 'D':
00423 if (!ACE_OS::strptime_getnum
00424 (buf + bi, &tm->tm_mon, &bi, &fi, 1, 12))
00425 return const_cast<char*> (buf + bi);
00426
00427 --fi;
00428 tm->tm_mon--;
00429
00430 if (buf[bi] != '/')
00431 return const_cast<char*> (buf + bi);
00432
00433 ++bi;
00434
00435 if (!ACE_OS::strptime_getnum
00436 (buf + bi, &tm->tm_mday, &bi, &fi, 1, 31))
00437 return const_cast<char*> (buf + bi);
00438
00439 --fi;
00440 if (buf[bi] != '/')
00441 return const_cast<char*> (buf + bi);
00442 ++bi;
00443 if (!ACE_OS::strptime_getnum
00444 (buf + bi, &tm->tm_year, &bi, &fi, 0, 99))
00445 return const_cast<char*> (buf + bi);
00446 if (tm->tm_year < 69)
00447 tm->tm_year += 100;
00448 break;
00449
00450 case 'H':
00451
00452 case 'k':
00453 if (!ACE_OS::strptime_getnum
00454 (buf + bi, &tm->tm_hour, &bi, &fi, 0, 23))
00455 return const_cast<char*> (buf + bi);
00456 break;
00457
00458
00459
00460
00461
00462
00463
00464
00465 case 'j':
00466 if (!ACE_OS::strptime_getnum
00467 (buf + bi, &tm->tm_yday, &bi, &fi, 1, 366))
00468 return const_cast<char*> (buf + bi);
00469
00470 tm->tm_yday--;
00471 break;
00472
00473 case 'm':
00474 if (!ACE_OS::strptime_getnum
00475 (buf + bi, &tm->tm_mon, &bi, &fi, 1, 12))
00476 return const_cast<char*> (buf + bi);
00477
00478 tm->tm_mon--;
00479 break;
00480
00481 case 'M':
00482 if (!ACE_OS::strptime_getnum
00483 (buf + bi, &tm->tm_min, &bi, &fi, 0, 59))
00484 return const_cast<char*> (buf + bi);
00485
00486 break;
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498 case 'R':
00499 if (!ACE_OS::strptime_getnum
00500 (buf + bi, &tm->tm_hour, &bi, &fi, 0, 23))
00501 return const_cast<char*> (buf + bi);
00502
00503 --fi;
00504 if (buf[bi] != ':')
00505 return const_cast<char*> (buf + bi);
00506 ++bi;
00507 if (!ACE_OS::strptime_getnum
00508 (buf + bi, &tm->tm_min, &bi, &fi, 0, 59))
00509 return const_cast<char*> (buf + bi);
00510
00511 break;
00512
00513 case 'S':
00514 if (!ACE_OS::strptime_getnum
00515 (buf + bi, &tm->tm_sec, &bi, &fi, 0, 61))
00516 return const_cast<char*> (buf + bi);
00517 break;
00518
00519 case 'T':
00520 if (!ACE_OS::strptime_getnum
00521 (buf + bi, &tm->tm_hour, &bi, &fi, 0, 23))
00522 return const_cast<char*> (buf + bi);
00523
00524 --fi;
00525 if (buf[bi] != ':')
00526 return const_cast<char*> (buf + bi);
00527 ++bi;
00528 if (!ACE_OS::strptime_getnum
00529 (buf + bi, &tm->tm_min, &bi, &fi, 0, 59))
00530 return const_cast<char*> (buf + bi);
00531
00532 --fi;
00533 if (buf[bi] != ':')
00534 return const_cast<char*> (buf + bi);
00535 ++bi;
00536 if (!ACE_OS::strptime_getnum
00537 (buf + bi, &tm->tm_sec, &bi, &fi, 0, 61))
00538 return const_cast<char*> (buf + bi);
00539
00540 break;
00541
00542 case 'w':
00543 if (!ACE_OS::strptime_getnum
00544 (buf + bi, &tm->tm_wday, &bi, &fi, 0, 6))
00545 return const_cast<char*> (buf + bi);
00546
00547 break;
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559 case 'y':
00560 if (!ACE_OS::strptime_getnum
00561 (buf + bi, &tm->tm_year, &bi, &fi, 0, 99))
00562 return const_cast<char*> (buf + bi);
00563
00564 if (tm->tm_year < 69)
00565 tm->tm_year += 100;
00566 break;
00567
00568 case 'Y':
00569 if (!ACE_OS::strptime_getnum
00570 (buf + bi, &tm->tm_year, &bi, &fi, 0, 0))
00571 return const_cast<char*> (buf + bi);
00572
00573 tm->tm_year -= 1900;
00574 break;
00575
00576 default:
00577 return const_cast<char*> (buf + bi);
00578 }
00579
00580 }
00581 else
00582 {
00583 if (format[fi] == '%')
00584 {
00585 percent = true;
00586 ++fi;
00587 }
00588 else
00589 {
00590 if (format[fi] == buf[bi])
00591 {
00592 ++fi;
00593 ++bi;
00594 }
00595 else
00596 return const_cast<char*> (buf + bi);
00597 }
00598 }
00599 }
00600
00601 return const_cast<char*> (buf + bi);
00602 }
00603
00604 int
00605 ACE_OS::strptime_getnum (const char *buf,
00606 int *num,
00607 int *bi,
00608 int *fi,
00609 int min,
00610 int max)
00611 {
00612 int i = 0, tmp = 0;
00613
00614 while (isdigit (buf[i]))
00615 {
00616 tmp = (tmp * 10) + (buf[i] - '0');
00617 if (max && (tmp > max))
00618 return 0;
00619 ++i;
00620 }
00621
00622 if (tmp < min)
00623 return 0;
00624 else if (i)
00625 {
00626 *num = tmp;
00627 (*fi)++;
00628 *bi += i;
00629 return 1;
00630 }
00631 else
00632 return 0;
00633 }
00634 #endif
00635
00636 ACE_END_VERSIONED_NAMESPACE_DECL