]> git.saurik.com Git - wxWidgets.git/blame - src/common/time.cpp
Correct handle passed to DocumentProperties() in MSW printing code.
[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
226#elif defined(WX_TIMEZONE) // If WX_TIMEZONE was defined by configure, use it.
227 return WX_TIMEZONE;
228#elif defined(__BORLANDC__) || defined(__MINGW32__) || defined(__VISAGECPP__)
229 return _timezone;
230#elif defined(__MWERKS__)
231 return 28800;
232#else // unknown platform -- assume it has timezone
233 return timezone;
234#endif // WX_GMTOFF_IN_TM/!WX_GMTOFF_IN_TM
235}
173a5ddc
VZ
236
237// Get local time as seconds since 00:00:00, Jan 1st 1970
238long wxGetLocalTime()
239{
240 struct tm tm;
241 time_t t0, t1;
242
243 // This cannot be made static because mktime can overwrite it.
244 //
245 memset(&tm, 0, sizeof(tm));
246 tm.tm_year = 70;
247 tm.tm_mon = 0;
248 tm.tm_mday = 5; // not Jan 1st 1970 due to mktime 'feature'
249 tm.tm_hour = 0;
250 tm.tm_min = 0;
251 tm.tm_sec = 0;
252 tm.tm_isdst = -1; // let mktime guess
253
254 // Note that mktime assumes that the struct tm contains local time.
255 //
256 t1 = time(&t1); // now
257 t0 = mktime(&tm); // origin
258
259 // Return the difference in seconds.
260 //
261 if (( t0 != (time_t)-1 ) && ( t1 != (time_t)-1 ))
262 return (long)difftime(t1, t0) + (60 * 60 * 24 * 4);
263
264 wxLogSysError(_("Failed to get the local system time"));
265 return -1;
266}
267
268// Get UTC time as seconds since 00:00:00, Jan 1st 1970
269long wxGetUTCTime()
270{
271 return (long)time(NULL);
272}
273
274#if wxUSE_LONGLONG
275
276wxLongLong wxGetUTCTimeUSec()
277{
278#if defined(__WXMSW__)
279 FILETIME ft;
280 ::GetSystemTimeAsFileTime(&ft);
281
282 // FILETIME is in 100ns or 0.1us since 1601-01-01, transform to us since
283 // 1970-01-01.
284 wxLongLong t(ft.dwHighDateTime, ft.dwLowDateTime);
285 t /= 10;
286 t -= wxLL(11644473600000000); // Unix - Windows epochs difference in us.
287 return t;
288#else // non-MSW
289
290#ifdef HAVE_GETTIMEOFDAY
291 timeval tv;
292 if ( wxGetTimeOfDay(&tv) != -1 )
293 {
294 wxLongLong val(tv.tv_sec);
295 val *= MICROSECONDS_PER_SECOND;
296 val += tv.tv_usec;
297 return val;
298 }
299#endif // HAVE_GETTIMEOFDAY
300
301 // Fall back to lesser precision function.
302 return wxGetUTCTimeMillis()*MICROSECONDS_PER_MILLISECOND;
303#endif // MSW/!MSW
304}
305
306// Get local time as milliseconds since 00:00:00, Jan 1st 1970
307wxLongLong wxGetUTCTimeMillis()
308{
309 wxLongLong val = MILLISECONDS_PER_SECOND;
310
311 // If possible, use a function which avoids conversions from
312 // broken-up time structures to milliseconds
313#if defined(__WXPALMOS__)
314 DateTimeType thenst;
315 thenst.second = 0;
316 thenst.minute = 0;
317 thenst.hour = 0;
318 thenst.day = 1;
319 thenst.month = 1;
320 thenst.year = 1970;
321 thenst.weekDay = 5;
322 uint32_t now = TimGetSeconds();
323 uint32_t then = TimDateTimeToSeconds (&thenst);
324 return SysTimeToMilliSecs(SysTimeInSecs(now - then));
325#elif defined(__WXMSW__)
326 FILETIME ft;
327 ::GetSystemTimeAsFileTime(&ft);
328
329 // FILETIME is expressed in 100ns (or 0.1us) units since 1601-01-01,
330 // transform them to ms since 1970-01-01.
331 wxLongLong t(ft.dwHighDateTime, ft.dwLowDateTime);
332 t /= 10000;
333 t -= wxLL(11644473600000); // Unix - Windows epochs difference in ms.
334 return t;
335#elif defined(HAVE_GETTIMEOFDAY)
336 struct timeval tp;
337 if ( wxGetTimeOfDay(&tp) != -1 )
338 {
339 val *= tp.tv_sec;
340 return (val + (tp.tv_usec / MICROSECONDS_PER_MILLISECOND));
341 }
342 else
343 {
344 wxLogError(_("wxGetTimeOfDay failed."));
345 return 0;
346 }
347#elif defined(HAVE_FTIME)
348 struct timeb tp;
349
350 // ftime() is void and not int in some mingw32 headers, so don't
351 // test the return code (well, it shouldn't fail anyhow...)
352 (void)::ftime(&tp);
353 val *= tp.time;
354 return (val + tp.millitm);
355#else // no gettimeofday() nor ftime()
356 // If your platform/compiler does not support ms resolution please
357 // do NOT just shut off these warnings, drop me a line instead at
358 // <guille@iies.es>
359
360 #if defined(__VISUALC__) || defined (__WATCOMC__)
361 #pragma message("wxStopWatch will be up to second resolution!")
362 #elif defined(__BORLANDC__)
363 #pragma message "wxStopWatch will be up to second resolution!"
364 #else
365 #warning "wxStopWatch will be up to second resolution!"
366 #endif // compiler
367
368 val *= wxGetUTCTime();
369 return val;
370#endif // time functions
371}
372
373wxLongLong wxGetLocalTimeMillis()
374{
375 return wxGetUTCTimeMillis() - wxGetTimeZone()*MILLISECONDS_PER_SECOND;
376}
377
378#else // !wxUSE_LONGLONG
379
380double wxGetLocalTimeMillis(void)
381{
382 return (double(clock()) / double(CLOCKS_PER_SEC)) * 1000.0;
383}
384
385#endif // wxUSE_LONGLONG/!wxUSE_LONGLONG