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() */
19 ACE_TCHAR
const * const ACE_OS_day_of_week_name
[] =
30 ACE_TCHAR
const * const ACE_OS_month_name
[] =
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)
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.
62 // This is really stupid, converting FILETIME to timeval back and
63 // forth. It assumes FILETIME and DWORDLONG are the same structure
65 ULARGE_INTEGER _100ns
;
66 _100ns
.QuadPart
= (DWORDLONG
) *clock
* 10000 * 1000
67 + ACE_Time_Value::FILETIME_to_timval_skew
;
69 file_time
.dwLowDateTime
= _100ns
.LowPart
;
70 file_time
.dwHighDateTime
= _100ns
.HighPart
;
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],
86 # endif /* ACE_HAS_WINCE */
88 # if defined (ACE_LACKS_DIFFTIME)
90 ACE_OS::difftime (time_t t1
, time_t t0
)
92 /* return t1 - t0 in seconds */
93 struct tm tms
[2], *ptms
[2], temp
;
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
)
107 else if (tms
[1].tm_year
== tms
[0].tm_year
)
109 if (tms
[1].tm_yday
< tms
[0].tm_yday
)
111 else if (tms
[1].tm_yday
== tms
[0].tm_yday
)
113 if (tms
[1].tm_hour
< tms
[0].tm_hour
)
115 else if (tms
[1].tm_hour
== tms
[0].tm_hour
)
117 if (tms
[1].tm_min
< tms
[0].tm_min
)
119 else if (tms
[1].tm_min
== tms
[0].tm_min
)
121 if (tms
[1].tm_sec
< tms
[0].tm_sec
)
129 temp
= tms
[0], tms
[0] = tms
[1], tms
[1] = temp
;
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
;
138 seconds
+= 60 * (60 - tms
[0].tm_min
);
141 seconds
+= 60*60 * (24 - tms
[0].tm_hour
);
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
);
150 seconds
+= 60*60*24 * (365 - tms
[0].tm_yday
);
155 while (tms
[1].tm_year
> tms
[0].tm_year
)
157 if (ISLEAPYEAR(tms
[0].tm_year
))
158 seconds
+= 60*60*24 * 366;
160 seconds
+= 60*60*24 * 365;
171 if (tms
[1].tm_sec
< tms
[0].tm_sec
)
173 if (tms
[1].tm_min
== 0)
175 if (tms
[1].tm_hour
== 0)
178 tms
[1].tm_hour
+= 24;
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)
193 tms
[1].tm_hour
+= 24;
198 tms
[1].tm_min
-= tms
[0].tm_min
;
200 if (tms
[1].tm_hour
< tms
[0].tm_hour
)
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
;
218 # endif /* ACE_LACKS_DIFFTIME */
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
);
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
232 TIME_ZONE_INFORMATION pTz
;
234 const unsigned short int __mon_yday
[2][13] =
237 { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
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
;
247 file_time
.dwLowDateTime
= _100ns
.LowPart
;
248 file_time
.dwHighDateTime
= _100ns
.HighPart
;
252 FileTimeToLocalFileTime (&file_time
, &localtime
);
253 FileTimeToSystemTime (&localtime
, &systime
);
255 res
->tm_hour
= systime
.wHour
;
257 if(pTz
.DaylightBias
!=0)
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;
276 #elif defined (ACE_LACKS_LOCALTIME_R)
279 ACE_UNUSED_ARG (res
);
280 struct tm
* res_ptr
= 0;
281 ACE_OSCALL (::localtime (t
), struct tm
*, 0, res_ptr
);
290 return ace_localtime_r_helper (t
, res
);
291 #endif /* ACE_HAS_TR24731_2005_CRT */
295 ACE_OS::mktime (struct tm
*t
)
297 ACE_OS_TRACE ("ACE_OS::mktime");
298 # if defined (ACE_HAS_WINCE)
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)
311 ACE_Time_Value
tv (t_file
);
314 # if defined (ACE_HAS_THREADS) && !defined (ACE_HAS_MT_SAFE_MKTIME)
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)
324 ACE_OS::strptime_emulation (const char *buf
, const char *format
, struct tm
*tm
)
328 bool percent
= false;
333 while (format
[fi
] != '\0')
340 case '%': // an escaped %
347 return const_cast<char*> (buf
+ bi
);
350 /* not supported yet: weekday via locale long/short names
351 case 'a': / * weekday via locale * /
353 case 'A': / * long/short names * /
357 /* not supported yet:
358 case 'b': / * month via locale * /
360 case 'B': / * long/short names * /
366 /* not supported yet:
367 case 'c': / * %x %X * /
371 /* not supported yet:
372 case 'C': / * date & time - * /
373 / * locale long format * /
377 case 'd': /* day of month (1-31) */
380 if (!ACE_OS::strptime_getnum
381 (buf
+ bi
, &tm
->tm_mday
, &bi
, &fi
, 1, 31))
382 return const_cast<char*> (buf
+ bi
);
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
);
395 return const_cast<char*> (buf
+ bi
);
399 if (!ACE_OS::strptime_getnum
400 (buf
+ bi
, &tm
->tm_mday
, &bi
, &fi
, 1, 31))
401 return const_cast<char*> (buf
+ bi
);
405 return const_cast<char*> (buf
+ 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)
414 case 'H': /* hour (0-23) */
417 if (!ACE_OS::strptime_getnum
418 (buf
+ bi
, &tm
->tm_hour
, &bi
, &fi
, 0, 23))
419 return const_cast<char*> (buf
+ bi
);
422 /* not supported yet:
423 case 'I': / * hour (0-12) * /
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
);
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
);
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
);
452 /* not supported yet:
453 case 'p': / * am or pm for locale * /
457 /* not supported yet:
458 case 'r': / * %I:%M:%S %p * /
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
);
469 return const_cast<char*> (buf
+ bi
);
471 if (!ACE_OS::strptime_getnum
472 (buf
+ bi
, &tm
->tm_min
, &bi
, &fi
, 0, 59))
473 return const_cast<char*> (buf
+ bi
);
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
);
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
);
490 return const_cast<char*> (buf
+ bi
);
492 if (!ACE_OS::strptime_getnum
493 (buf
+ bi
, &tm
->tm_min
, &bi
, &fi
, 0, 59))
494 return const_cast<char*> (buf
+ bi
);
498 return const_cast<char*> (buf
+ bi
);
500 if (!ACE_OS::strptime_getnum
501 (buf
+ bi
, &tm
->tm_sec
, &bi
, &fi
, 0, 61))
502 return const_cast<char*> (buf
+ bi
);
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
);
513 /* not supported yet: date, based on locale
514 case 'x': / * date, based on locale * /
518 /* not supported yet:
519 case 'X': / * time, based on locale * /
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)
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
);
540 default: /* unrecognised */
541 return const_cast<char*> (buf
+ bi
);
542 } /* switch (format[fi]) */
547 if (format
[fi
] == '%')
554 if (format
[fi
] == buf
[bi
])
560 return const_cast<char*> (buf
+ bi
);
563 } /* while (format[fi] */
565 return const_cast<char*> (buf
+ bi
);
569 ACE_OS::strptime_getnum (const char *buf
,
578 while (isdigit (buf
[i
]))
580 tmp
= (tmp
* 10) + (buf
[i
] - '0');
581 if (max
&& (tmp
> max
))
598 #endif /* ACE_LACKS_STRPTIME */
600 ACE_END_VERSIONED_NAMESPACE_DECL