Also use Objects as part of an operation but as a result don't generate Any operation...
[ACE_TAO.git] / ACE / ace / OS_NS_time.cpp
blob2ab3c7ebe475313389294296d3c5690d383328aa
1 #include "ace/OS_NS_time.h"
3 #if !defined (ACE_HAS_INLINED_OSCALLS)
4 # include "ace/OS_NS_time.inl"
5 #endif /* ACE_HAS_INLINED_OSCALLS */
7 #if defined (ACE_LACKS_STRPTIME)
8 # include "ace/os_include/os_ctype.h"
9 #endif /* ACE_LACKS_STRPTIME */
11 #include "ace/OS_NS_Thread.h"
12 #include "ace/Object_Manager_Base.h"
14 #if defined (ACE_HAS_WINCE)
15 # include "ace/OS_NS_stdio.h" /* Need ACE_OS::sprintf() */
17 namespace
19 ACE_TCHAR const * const ACE_OS_day_of_week_name[] =
21 ACE_TEXT ("Sun"),
22 ACE_TEXT ("Mon"),
23 ACE_TEXT ("Tue"),
24 ACE_TEXT ("Wed"),
25 ACE_TEXT ("Thu"),
26 ACE_TEXT ("Fri"),
27 ACE_TEXT ("Sat")
30 ACE_TCHAR const * const ACE_OS_month_name[] =
32 ACE_TEXT ("Jan"),
33 ACE_TEXT ("Feb"),
34 ACE_TEXT ("Mar"),
35 ACE_TEXT ("Apr"),
36 ACE_TEXT ("May"),
37 ACE_TEXT ("Jun"),
38 ACE_TEXT ("Jul"),
39 ACE_TEXT ("Aug"),
40 ACE_TEXT ("Sep"),
41 ACE_TEXT ("Oct"),
42 ACE_TEXT ("Nov"),
43 ACE_TEXT ("Dec")
46 static ACE_TCHAR const ACE_OS_CTIME_R_FMTSTR[] = ACE_TEXT ("%3s %3s %02d %02d:%02d:%02d %04d\n");
47 } /* end blank namespace */
48 #endif /* ACE_HAS_WINCE */
50 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
52 # if defined (ACE_HAS_WINCE)
53 ACE_TCHAR *
54 ACE_OS::ctime_r (const time_t *clock, ACE_TCHAR *buf, int buflen)
56 // buflen must be at least 26 wchar_t long.
57 if (buflen < 26) // Again, 26 is a magic number.
59 errno = ERANGE;
60 return 0;
62 // This is really stupid, converting FILETIME to timeval back and
63 // forth. It assumes FILETIME and DWORDLONG are the same structure
64 // internally.
65 ULARGE_INTEGER _100ns;
66 _100ns.QuadPart = (DWORDLONG) *clock * 10000 * 1000
67 + ACE_Time_Value::FILETIME_to_timval_skew;
68 FILETIME file_time;
69 file_time.dwLowDateTime = _100ns.LowPart;
70 file_time.dwHighDateTime = _100ns.HighPart;
72 FILETIME localtime;
73 SYSTEMTIME systime;
74 FileTimeToLocalFileTime (&file_time, &localtime);
75 FileTimeToSystemTime (&localtime, &systime);
76 ACE_OS::snprintf (buf, buflen, ACE_OS_CTIME_R_FMTSTR,
77 ACE_OS_day_of_week_name[systime.wDayOfWeek],
78 ACE_OS_month_name[systime.wMonth - 1],
79 systime.wDay,
80 systime.wHour,
81 systime.wMinute,
82 systime.wSecond,
83 systime.wYear);
84 return buf;
86 # endif /* ACE_HAS_WINCE */
88 # if defined (ACE_LACKS_DIFFTIME)
89 double
90 ACE_OS::difftime (time_t t1, time_t t0)
92 /* return t1 - t0 in seconds */
93 struct tm tms[2], *ptms[2], temp;
94 double seconds;
95 int swap = 0;
97 /* extract the tm structure from time_t */
98 ptms[1] = ::gmtime_r (&t1, &tms[1]);
99 if (ptms[1] == 0) return 0.0;
101 ptms[0] = ::gmtime_r (&t0, &tms[0]);
102 if (ptms[0] == 0) return 0.0;
104 /* make sure t1 is > t0 */
105 if (tms[1].tm_year < tms[0].tm_year)
106 swap = 1;
107 else if (tms[1].tm_year == tms[0].tm_year)
109 if (tms[1].tm_yday < tms[0].tm_yday)
110 swap = 1;
111 else if (tms[1].tm_yday == tms[0].tm_yday)
113 if (tms[1].tm_hour < tms[0].tm_hour)
114 swap = 1;
115 else if (tms[1].tm_hour == tms[0].tm_hour)
117 if (tms[1].tm_min < tms[0].tm_min)
118 swap = 1;
119 else if (tms[1].tm_min == tms[0].tm_min)
121 if (tms[1].tm_sec < tms[0].tm_sec)
122 swap = 1;
128 if (swap)
129 temp = tms[0], tms[0] = tms[1], tms[1] = temp;
131 seconds = 0.0;
132 if (tms[1].tm_year > tms[0].tm_year)
134 // Accumulate the time until t[0] catches up to t[1]'s year.
135 seconds = 60 - tms[0].tm_sec;
136 tms[0].tm_sec = 0;
137 tms[0].tm_min += 1;
138 seconds += 60 * (60 - tms[0].tm_min);
139 tms[0].tm_min = 0;
140 tms[0].tm_hour += 1;
141 seconds += 60*60 * (24 - tms[0].tm_hour);
142 tms[0].tm_hour = 0;
143 tms[0].tm_yday += 1;
145 # define ISLEAPYEAR(y) ((y)&3u?0:(y)%25u?1:(y)/25u&12?0:1)
147 if (ISLEAPYEAR(tms[0].tm_year))
148 seconds += 60*60*24 * (366 - tms[0].tm_yday);
149 else
150 seconds += 60*60*24 * (365 - tms[0].tm_yday);
152 tms[0].tm_yday = 0;
153 tms[0].tm_year += 1;
155 while (tms[1].tm_year > tms[0].tm_year)
157 if (ISLEAPYEAR(tms[0].tm_year))
158 seconds += 60*60*24 * 366;
159 else
160 seconds += 60*60*24 * 365;
162 tms[0].tm_year += 1;
165 # undef ISLEAPYEAR
168 else
170 // Normalize
171 if (tms[1].tm_sec < tms[0].tm_sec)
173 if (tms[1].tm_min == 0)
175 if (tms[1].tm_hour == 0)
177 tms[1].tm_yday -= 1;
178 tms[1].tm_hour += 24;
180 tms[1].tm_hour -= 1;
181 tms[1].tm_min += 60;
183 tms[1].tm_min -= 1;
184 tms[1].tm_sec += 60;
186 tms[1].tm_sec -= tms[0].tm_sec;
188 if (tms[1].tm_min < tms[0].tm_min)
190 if (tms[1].tm_hour == 0)
192 tms[1].tm_yday -= 1;
193 tms[1].tm_hour += 24;
195 tms[1].tm_hour -= 1;
196 tms[1].tm_min += 60;
198 tms[1].tm_min -= tms[0].tm_min;
200 if (tms[1].tm_hour < tms[0].tm_hour)
202 tms[1].tm_yday -= 1;
203 tms[1].tm_hour += 24;
205 tms[1].tm_hour -= tms[0].tm_hour;
207 tms[1].tm_yday -= tms[0].tm_yday;
210 // accumulate the seconds
211 seconds += tms[1].tm_sec;
212 seconds += 60 * tms[1].tm_min;
213 seconds += 60*60 * tms[1].tm_hour;
214 seconds += 60*60*24 * tms[1].tm_yday;
216 return seconds;
218 # endif /* ACE_LACKS_DIFFTIME */
220 struct tm *
221 ACE_OS::localtime_r (const time_t *t, struct tm *res)
223 ACE_OS_TRACE ("ACE_OS::localtime_r");
224 #if defined (ACE_HAS_TR24731_2005_CRT)
225 ACE_SECURECRTCALL (localtime_s (res, t), struct tm *, 0, res);
226 return res;
227 #elif defined (ACE_HAS_WINCE)
228 // This is really stupid, converting FILETIME to timeval back and
229 // forth. It assumes FILETIME and DWORDLONG are the same structure
230 // internally.
232 TIME_ZONE_INFORMATION pTz;
234 const unsigned short int __mon_yday[2][13] =
236 /* Normal years. */
237 { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
238 /* Leap years. */
239 { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
242 ULARGE_INTEGER _100ns;
243 ::GetTimeZoneInformation (&pTz);
245 _100ns.QuadPart = (DWORDLONG) *t * 10000 * 1000 + ACE_Time_Value::FILETIME_to_timval_skew;
246 FILETIME file_time;
247 file_time.dwLowDateTime = _100ns.LowPart;
248 file_time.dwHighDateTime = _100ns.HighPart;
250 FILETIME localtime;
251 SYSTEMTIME systime;
252 FileTimeToLocalFileTime (&file_time, &localtime);
253 FileTimeToSystemTime (&localtime, &systime);
255 res->tm_hour = systime.wHour;
257 if(pTz.DaylightBias!=0)
258 res->tm_isdst = 1;
259 else
260 res->tm_isdst = 1;
262 int iLeap;
263 iLeap = (res->tm_year % 4 == 0 && (res->tm_year% 100 != 0 || res->tm_year % 400 == 0));
264 // based on leap select which group to use
266 res->tm_mday = systime.wDay;
267 res->tm_min = systime.wMinute;
268 res->tm_mon = systime.wMonth - 1;
269 res->tm_sec = systime.wSecond;
270 res->tm_wday = systime.wDayOfWeek;
271 res->tm_yday = __mon_yday[iLeap][systime.wMonth] + systime.wDay;
272 res->tm_year = systime.wYear;// this the correct year but bias the value to start at the 1900
273 res->tm_year = res->tm_year - 1900;
275 return res;
276 #elif defined (ACE_LACKS_LOCALTIME_R)
277 ACE_OS_GUARD
279 ACE_UNUSED_ARG (res);
280 struct tm * res_ptr = 0;
281 ACE_OSCALL (::localtime (t), struct tm *, 0, res_ptr);
282 if (res_ptr == 0)
283 return 0;
284 else
286 *res = *res_ptr;
287 return res;
289 #else
290 return ace_localtime_r_helper (t, res);
291 #endif /* ACE_HAS_TR24731_2005_CRT */
294 time_t
295 ACE_OS::mktime (struct tm *t)
297 ACE_OS_TRACE ("ACE_OS::mktime");
298 # if defined (ACE_HAS_WINCE)
299 SYSTEMTIME t_sys;
300 FILETIME t_file;
301 t_sys.wSecond = t->tm_sec;
302 t_sys.wMinute = t->tm_min;
303 t_sys.wHour = t->tm_hour;
304 t_sys.wDay = t->tm_mday;
305 t_sys.wMonth = t->tm_mon + 1; // SYSTEMTIME is 1-indexed, tm is 0-indexed
306 t_sys.wYear = t->tm_year + 1900; // SYSTEMTIME is real; tm is since 1900
307 t_sys.wDayOfWeek = t->tm_wday; // Ignored in below function call.
308 t_sys.wMilliseconds = 0;
309 if (SystemTimeToFileTime (&t_sys, &t_file) == 0)
310 return -1;
311 ACE_Time_Value tv (t_file);
312 return tv.sec ();
313 # else
314 # if defined (ACE_HAS_THREADS) && !defined (ACE_HAS_MT_SAFE_MKTIME)
315 ACE_OS_GUARD
316 # endif /* ACE_HAS_THREADS && ! ACE_HAS_MT_SAFE_MKTIME */
318 ACE_OSCALL_RETURN (ACE_STD_NAMESPACE::mktime (t), time_t, (time_t) -1);
319 # endif /* ACE_HAS_WINCE */
322 #if defined (ACE_LACKS_STRPTIME)
323 char *
324 ACE_OS::strptime_emulation (const char *buf, const char *format, struct tm *tm)
326 int bi = 0;
327 int fi = 0;
328 bool percent = false;
330 if (!buf || !format)
331 return 0;
333 while (format[fi] != '\0')
335 if (percent)
337 percent = false;
338 switch (format[fi])
340 case '%': // an escaped %
341 if (buf[bi] == '%')
343 ++fi;
344 ++bi;
346 else
347 return const_cast<char*> (buf + bi);
348 break;
350 /* not supported yet: weekday via locale long/short names
351 case 'a': / * weekday via locale * /
352 / * FALL THROUGH * /
353 case 'A': / * long/short names * /
354 break;
357 /* not supported yet:
358 case 'b': / * month via locale * /
359 / * FALL THROUGH * /
360 case 'B': / * long/short names * /
361 / * FALL THROUGH * /
362 case 'h':
363 break;
366 /* not supported yet:
367 case 'c': / * %x %X * /
368 break;
371 /* not supported yet:
372 case 'C': / * date & time - * /
373 / * locale long format * /
374 break;
377 case 'd': /* day of month (1-31) */
378 /* FALL THROUGH */
379 case 'e':
380 if (!ACE_OS::strptime_getnum
381 (buf + bi, &tm->tm_mday, &bi, &fi, 1, 31))
382 return const_cast<char*> (buf + bi);
384 break;
386 case 'D': /* %m/%d/%y */
387 if (!ACE_OS::strptime_getnum
388 (buf + bi, &tm->tm_mon, &bi, &fi, 1, 12))
389 return const_cast<char*> (buf + bi);
391 --fi;
392 tm->tm_mon--;
394 if (buf[bi] != '/')
395 return const_cast<char*> (buf + bi);
397 ++bi;
399 if (!ACE_OS::strptime_getnum
400 (buf + bi, &tm->tm_mday, &bi, &fi, 1, 31))
401 return const_cast<char*> (buf + bi);
403 --fi;
404 if (buf[bi] != '/')
405 return const_cast<char*> (buf + bi);
406 ++bi;
407 if (!ACE_OS::strptime_getnum
408 (buf + bi, &tm->tm_year, &bi, &fi, 0, 99))
409 return const_cast<char*> (buf + bi);
410 if (tm->tm_year < 69)
411 tm->tm_year += 100;
412 break;
414 case 'H': /* hour (0-23) */
415 /* FALL THROUGH */
416 case 'k':
417 if (!ACE_OS::strptime_getnum
418 (buf + bi, &tm->tm_hour, &bi, &fi, 0, 23))
419 return const_cast<char*> (buf + bi);
420 break;
422 /* not supported yet:
423 case 'I': / * hour (0-12) * /
424 / * FALL THROUGH * /
425 case 'l':
426 break;
429 case 'j': /* day of year (0-366) */
430 if (!ACE_OS::strptime_getnum
431 (buf + bi, &tm->tm_yday, &bi, &fi, 1, 366))
432 return const_cast<char*> (buf + bi);
434 tm->tm_yday--;
435 break;
437 case 'm': /* an escaped % */
438 if (!ACE_OS::strptime_getnum
439 (buf + bi, &tm->tm_mon, &bi, &fi, 1, 12))
440 return const_cast<char*> (buf + bi);
442 tm->tm_mon--;
443 break;
445 case 'M': /* minute (0-59) */
446 if (!ACE_OS::strptime_getnum
447 (buf + bi, &tm->tm_min, &bi, &fi, 0, 59))
448 return const_cast<char*> (buf + bi);
450 break;
452 /* not supported yet:
453 case 'p': / * am or pm for locale * /
454 break;
457 /* not supported yet:
458 case 'r': / * %I:%M:%S %p * /
459 break;
462 case 'R': /* %H:%M */
463 if (!ACE_OS::strptime_getnum
464 (buf + bi, &tm->tm_hour, &bi, &fi, 0, 23))
465 return const_cast<char*> (buf + bi);
467 --fi;
468 if (buf[bi] != ':')
469 return const_cast<char*> (buf + bi);
470 ++bi;
471 if (!ACE_OS::strptime_getnum
472 (buf + bi, &tm->tm_min, &bi, &fi, 0, 59))
473 return const_cast<char*> (buf + bi);
475 break;
477 case 'S': /* seconds (0-61) */
478 if (!ACE_OS::strptime_getnum
479 (buf + bi, &tm->tm_sec, &bi, &fi, 0, 61))
480 return const_cast<char*> (buf + bi);
481 break;
483 case 'T': /* %H:%M:%S */
484 if (!ACE_OS::strptime_getnum
485 (buf + bi, &tm->tm_hour, &bi, &fi, 0, 23))
486 return const_cast<char*> (buf + bi);
488 --fi;
489 if (buf[bi] != ':')
490 return const_cast<char*> (buf + bi);
491 ++bi;
492 if (!ACE_OS::strptime_getnum
493 (buf + bi, &tm->tm_min, &bi, &fi, 0, 59))
494 return const_cast<char*> (buf + bi);
496 --fi;
497 if (buf[bi] != ':')
498 return const_cast<char*> (buf + bi);
499 ++bi;
500 if (!ACE_OS::strptime_getnum
501 (buf + bi, &tm->tm_sec, &bi, &fi, 0, 61))
502 return const_cast<char*> (buf + bi);
504 break;
506 case 'w': /* day of week (0=Sun-6) */
507 if (!ACE_OS::strptime_getnum
508 (buf + bi, &tm->tm_wday, &bi, &fi, 0, 6))
509 return const_cast<char*> (buf + bi);
511 break;
513 /* not supported yet: date, based on locale
514 case 'x': / * date, based on locale * /
515 break;
518 /* not supported yet:
519 case 'X': / * time, based on locale * /
520 break;
523 case 'y': /* the year - 1900 (0-99) */
524 if (!ACE_OS::strptime_getnum
525 (buf + bi, &tm->tm_year, &bi, &fi, 0, 99))
526 return const_cast<char*> (buf + bi);
528 if (tm->tm_year < 69)
529 tm->tm_year += 100;
530 break;
532 case 'Y': /* the full year (1999) */
533 if (!ACE_OS::strptime_getnum
534 (buf + bi, &tm->tm_year, &bi, &fi, 0, 0))
535 return const_cast<char*> (buf + bi);
537 tm->tm_year -= 1900;
538 break;
540 default: /* unrecognised */
541 return const_cast<char*> (buf + bi);
542 } /* switch (format[fi]) */
545 else
546 { /* if (percent) */
547 if (format[fi] == '%')
549 percent = true;
550 ++fi;
552 else
554 if (format[fi] == buf[bi])
556 ++fi;
557 ++bi;
559 else
560 return const_cast<char*> (buf + bi);
562 } /* if (percent) */
563 } /* while (format[fi] */
565 return const_cast<char*> (buf + bi);
569 ACE_OS::strptime_getnum (const char *buf,
570 int *num,
571 int *bi,
572 int *fi,
573 int min,
574 int max)
576 int i = 0, tmp = 0;
578 while (isdigit (buf[i]))
580 tmp = (tmp * 10) + (buf[i] - '0');
581 if (max && (tmp > max))
582 return 0;
583 ++i;
586 if (tmp < min)
587 return 0;
588 else if (i)
590 *num = tmp;
591 (*fi)++;
592 *bi += i;
593 return 1;
595 else
596 return 0;
598 #endif /* ACE_LACKS_STRPTIME */
600 ACE_END_VERSIONED_NAMESPACE_DECL