]> git.saurik.com Git - wxWidgets.git/blame - src/common/time.cpp
Remove the documentation of non-existent wxNO_T macro.
[wxWidgets.git] / src / common / time.cpp
CommitLineData
59068d79
VZ
1///////////////////////////////////////////////////////////////////////////////
2// Name: src/common/time.cpp
3// Purpose: Implementation of time-related functions.
4// Author: Vadim Zeitlin
5// Created: 2011-11-26
6// RCS-ID: $Id: wxhead.cpp,v 1.11 2010-04-22 12:44:51 zeitlin Exp $
7// Copyright: (c) 2011 Vadim Zeitlin <vadim@wxwidgets.org>
8// Licence: wxWindows licence
9///////////////////////////////////////////////////////////////////////////////
10
11// ============================================================================
12// declarations
13// ============================================================================
14
15// ----------------------------------------------------------------------------
16// headers
17// ----------------------------------------------------------------------------
18
19// for compilers that support precompilation, includes "wx.h".
20#include "wx/wxprec.h"
21
22#ifdef __BORLANDC__
23 #pragma hdrstop
24#endif
25
26#include "wx/time.h"
27
173a5ddc
VZ
28#ifndef WX_PRECOMP
29 #ifdef __WXMSW__
30 #include "wx/msw/wrapwin.h"
31 #endif
32 #include "wx/intl.h"
33 #include "wx/log.h"
34#endif
35
59068d79
VZ
36#ifndef WX_GMTOFF_IN_TM
37 // Define it for some systems which don't (always) use configure but are
38 // known to have tm_gmtoff field.
39 #if defined(__WXPALMOS__) || defined(__DARWIN__)
40 #define WX_GMTOFF_IN_TM
41 #endif
42#endif
43
173a5ddc
VZ
44#if defined(__VISAGECPP__) && !defined(HAVE_FTIME)
45 #define HAVE_FTIME
46# if __IBMCPP__ >= 400
47 # define ftime(x) _ftime(x)
48# endif
49#endif
50
51#if defined(__MWERKS__) && defined(__WXMSW__)
52# undef HAVE_FTIME
53# undef HAVE_GETTIMEOFDAY
54#endif
55
56#ifndef __WXPALMOS5__
57#ifndef __WXWINCE__
58#include <time.h>
59#else
60#include "wx/msw/private.h"
61#include "wx/msw/wince/time.h"
62#endif
63#endif // __WXPALMOS5__
64
65
66#if !defined(__WXMAC__) && !defined(__WXWINCE__)
67 #include <sys/types.h> // for time_t
68#endif
69
70#if defined(HAVE_GETTIMEOFDAY)
71 #include <sys/time.h>
72 #include <unistd.h>
73#elif defined(HAVE_FTIME)
74 #include <sys/timeb.h>
75#endif
76
77#ifdef __WXPALMOS__
78 #include <DateTime.h>
79 #include <TimeMgr.h>
80 #include <SystemMgr.h>
81#endif
82
fb7ce3e8
VZ
83#if defined(__MWERKS__) && wxUSE_UNICODE
84 #include <wtime.h>
85#endif
86
87#if defined(__DJGPP__) || defined(__WINE__)
88 #include <sys/timeb.h>
89 #include <values.h>
90#endif
91
173a5ddc
VZ
92namespace
93{
94
95const int MILLISECONDS_PER_SECOND = 1000;
96const int MICROSECONDS_PER_MILLISECOND = 1000;
97const int MICROSECONDS_PER_SECOND = 1000*1000;
98
99} // anonymous namespace
100
59068d79
VZ
101// ============================================================================
102// implementation
103// ============================================================================
104
fb7ce3e8
VZ
105// NB: VC8 safe time functions could/should be used for wxMSW as well probably
106#if defined(__WXWINCE__) && defined(__VISUALC8__)
107
108struct tm *wxLocaltime_r(const time_t *t, struct tm* tm)
109{
110 __time64_t t64 = *t;
111 return _localtime64_s(tm, &t64) == 0 ? tm : NULL;
112}
113
114struct tm *wxGmtime_r(const time_t* t, struct tm* tm)
115{
116 __time64_t t64 = *t;
117 return _gmtime64_s(tm, &t64) == 0 ? tm : NULL;
118}
119
120#else // !wxWinCE with VC8
121
122#if (!defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R)) && wxUSE_THREADS && !defined(__WINDOWS__)
123static wxMutex timeLock;
124#endif
125
126#ifndef HAVE_LOCALTIME_R
127struct tm *wxLocaltime_r(const time_t* ticks, struct tm* temp)
128{
129#if wxUSE_THREADS && !defined(__WINDOWS__)
130 // No need to waste time with a mutex on windows since it's using
131 // thread local storage for localtime anyway.
132 wxMutexLocker locker(timeLock);
133#endif
134
135 // Borland CRT crashes when passed 0 ticks for some reason, see SF bug 1704438
136#ifdef __BORLANDC__
137 if ( !*ticks )
138 return NULL;
139#endif
140
141 const tm * const t = localtime(ticks);
142 if ( !t )
143 return NULL;
144
145 memcpy(temp, t, sizeof(struct tm));
146 return temp;
147}
148#endif // !HAVE_LOCALTIME_R
149
150#ifndef HAVE_GMTIME_R
151struct tm *wxGmtime_r(const time_t* ticks, struct tm* temp)
152{
153#if wxUSE_THREADS && !defined(__WINDOWS__)
154 // No need to waste time with a mutex on windows since it's
155 // using thread local storage for gmtime anyway.
156 wxMutexLocker locker(timeLock);
157#endif
158
159#ifdef __BORLANDC__
160 if ( !*ticks )
161 return NULL;
162#endif
163
164 const tm * const t = gmtime(ticks);
165 if ( !t )
166 return NULL;
167
168 memcpy(temp, gmtime(ticks), sizeof(struct tm));
169 return temp;
170}
171#endif // !HAVE_GMTIME_R
172
173#endif // wxWinCE with VC8/other platforms
174
59068d79
VZ
175// returns the time zone in the C sense, i.e. the difference UTC - local
176// (in seconds)
177int wxGetTimeZone()
178{
179#ifdef WX_GMTOFF_IN_TM
180 // set to true when the timezone is set
181 static bool s_timezoneSet = false;
182 static long gmtoffset = LONG_MAX; // invalid timezone
183
184 // ensure that the timezone variable is set by calling wxLocaltime_r
185 if ( !s_timezoneSet )
186 {
187 // just call wxLocaltime_r() instead of figuring out whether this
188 // system supports tzset(), _tzset() or something else
189 time_t t = time(NULL);
190 struct tm tm;
191
192 wxLocaltime_r(&t, &tm);
193 s_timezoneSet = true;
194
195 // note that GMT offset is the opposite of time zone and so to return
196 // consistent results in both WX_GMTOFF_IN_TM and !WX_GMTOFF_IN_TM
197 // cases we have to negate it
198 gmtoffset = -tm.tm_gmtoff;
199
200 // this function is supposed to return the same value whether DST is
201 // enabled or not, so we need to use an additional offset if DST is on
202 // as tm_gmtoff already does include it
203 if ( tm.tm_isdst )
204 gmtoffset += 3600;
205 }
206 return (int)gmtoffset;
207#elif defined(__DJGPP__) || defined(__WINE__)
208 struct timeb tb;
209 ftime(&tb);
210 return tb.timezone*60;
211#elif defined(__VISUALC__)
212 // We must initialize the time zone information before using it (this will
213 // be done only once internally).
214 _tzset();
215
216 // Starting with VC++ 8 timezone variable is deprecated and is not even
217 // available in some standard library version so use the new function for
218 // accessing it instead.
219 #if wxCHECK_VISUALC_VERSION(8)
220 long t;
221 _get_timezone(&t);
222 return t;
223 #else // VC++ < 8
224 return timezone;
225 #endif
8c7114c2
VZ
226#else // Use some kind of time zone variable.
227 // In any case we must initialize the time zone before using it.
228 tzset();
229
230 #if defined(WX_TIMEZONE) // If WX_TIMEZONE was defined by configure, use it.
231 return WX_TIMEZONE;
232 #elif defined(__BORLANDC__) || defined(__MINGW32__) || defined(__VISAGECPP__)
233 return _timezone;
234 #elif defined(__MWERKS__)
235 // This is just plain wrong but apparently MetroWerks runtime didn't have
236 // any way to get the time zone.
237 return 28800;
238 #else // unknown platform -- assume it has timezone
239 return timezone;
240 #endif // different time zone variables
241#endif // different ways to determine time zone
59068d79 242}
173a5ddc
VZ
243
244// Get local time as seconds since 00:00:00, Jan 1st 1970
245long wxGetLocalTime()
246{
247 struct tm tm;
248 time_t t0, t1;
249
250 // This cannot be made static because mktime can overwrite it.
251 //
252 memset(&tm, 0, sizeof(tm));
253 tm.tm_year = 70;
254 tm.tm_mon = 0;
255 tm.tm_mday = 5; // not Jan 1st 1970 due to mktime 'feature'
256 tm.tm_hour = 0;
257 tm.tm_min = 0;
258 tm.tm_sec = 0;
259 tm.tm_isdst = -1; // let mktime guess
260
261 // Note that mktime assumes that the struct tm contains local time.
262 //
263 t1 = time(&t1); // now
264 t0 = mktime(&tm); // origin
265
266 // Return the difference in seconds.
267 //
268 if (( t0 != (time_t)-1 ) && ( t1 != (time_t)-1 ))
269 return (long)difftime(t1, t0) + (60 * 60 * 24 * 4);
270
271 wxLogSysError(_("Failed to get the local system time"));
272 return -1;
273}
274
275// Get UTC time as seconds since 00:00:00, Jan 1st 1970
276long wxGetUTCTime()
277{
278 return (long)time(NULL);
279}
280
281#if wxUSE_LONGLONG
282
283wxLongLong wxGetUTCTimeUSec()
284{
285#if defined(__WXMSW__)
286 FILETIME ft;
287 ::GetSystemTimeAsFileTime(&ft);
288
289 // FILETIME is in 100ns or 0.1us since 1601-01-01, transform to us since
290 // 1970-01-01.
291 wxLongLong t(ft.dwHighDateTime, ft.dwLowDateTime);
292 t /= 10;
293 t -= wxLL(11644473600000000); // Unix - Windows epochs difference in us.
294 return t;
295#else // non-MSW
296
297#ifdef HAVE_GETTIMEOFDAY
298 timeval tv;
299 if ( wxGetTimeOfDay(&tv) != -1 )
300 {
301 wxLongLong val(tv.tv_sec);
302 val *= MICROSECONDS_PER_SECOND;
303 val += tv.tv_usec;
304 return val;
305 }
306#endif // HAVE_GETTIMEOFDAY
307
308 // Fall back to lesser precision function.
309 return wxGetUTCTimeMillis()*MICROSECONDS_PER_MILLISECOND;
310#endif // MSW/!MSW
311}
312
313// Get local time as milliseconds since 00:00:00, Jan 1st 1970
314wxLongLong wxGetUTCTimeMillis()
315{
316 wxLongLong val = MILLISECONDS_PER_SECOND;
317
318 // If possible, use a function which avoids conversions from
319 // broken-up time structures to milliseconds
320#if defined(__WXPALMOS__)
321 DateTimeType thenst;
322 thenst.second = 0;
323 thenst.minute = 0;
324 thenst.hour = 0;
325 thenst.day = 1;
326 thenst.month = 1;
327 thenst.year = 1970;
328 thenst.weekDay = 5;
329 uint32_t now = TimGetSeconds();
330 uint32_t then = TimDateTimeToSeconds (&thenst);
331 return SysTimeToMilliSecs(SysTimeInSecs(now - then));
332#elif defined(__WXMSW__)
333 FILETIME ft;
334 ::GetSystemTimeAsFileTime(&ft);
335
336 // FILETIME is expressed in 100ns (or 0.1us) units since 1601-01-01,
337 // transform them to ms since 1970-01-01.
338 wxLongLong t(ft.dwHighDateTime, ft.dwLowDateTime);
339 t /= 10000;
340 t -= wxLL(11644473600000); // Unix - Windows epochs difference in ms.
341 return t;
342#elif defined(HAVE_GETTIMEOFDAY)
343 struct timeval tp;
344 if ( wxGetTimeOfDay(&tp) != -1 )
345 {
346 val *= tp.tv_sec;
347 return (val + (tp.tv_usec / MICROSECONDS_PER_MILLISECOND));
348 }
349 else
350 {
351 wxLogError(_("wxGetTimeOfDay failed."));
352 return 0;
353 }
354#elif defined(HAVE_FTIME)
355 struct timeb tp;
356
357 // ftime() is void and not int in some mingw32 headers, so don't
358 // test the return code (well, it shouldn't fail anyhow...)
359 (void)::ftime(&tp);
360 val *= tp.time;
361 return (val + tp.millitm);
362#else // no gettimeofday() nor ftime()
363 // If your platform/compiler does not support ms resolution please
364 // do NOT just shut off these warnings, drop me a line instead at
365 // <guille@iies.es>
366
367 #if defined(__VISUALC__) || defined (__WATCOMC__)
368 #pragma message("wxStopWatch will be up to second resolution!")
369 #elif defined(__BORLANDC__)
370 #pragma message "wxStopWatch will be up to second resolution!"
371 #else
372 #warning "wxStopWatch will be up to second resolution!"
373 #endif // compiler
374
375 val *= wxGetUTCTime();
376 return val;
377#endif // time functions
378}
379
380wxLongLong wxGetLocalTimeMillis()
381{
382 return wxGetUTCTimeMillis() - wxGetTimeZone()*MILLISECONDS_PER_SECOND;
383}
384
385#else // !wxUSE_LONGLONG
386
387double wxGetLocalTimeMillis(void)
388{
389 return (double(clock()) / double(CLOCKS_PER_SEC)) * 1000.0;
390}
391
392#endif // wxUSE_LONGLONG/!wxUSE_LONGLONG