1. msec resolution for timer functions under Win32
[wxWidgets.git] / src / common / timercmn.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: common/timercmn.cpp
3 // Purpose: Common timer implementation
4 // Author: Julian Smart
5 // Modified by: Vadim Zeitlin on 12.11.99 to get rid of all ifdefs
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart and Markus Holzem
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 #ifdef __GNUG__
21 #pragma implementation "timerbase.h"
22 #endif
23
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
26
27 #ifdef __BORLANDC__
28 #pragma hdrstop
29 #endif
30
31 #ifndef WX_PRECOMP
32 #include "wx/intl.h"
33 #include "wx/log.h"
34 #endif
35
36 #include "wx/timer.h"
37
38 // I'm told VMS is POSIX, so should have localtime()
39 #if defined(__WXMSW__) || defined(__VMS__) || defined(__WXPM__) || defined(__WXMAC__)
40 // configure might have found it already for us
41 #ifndef HAVE_LOCALTIME
42 #define HAVE_LOCALTIME
43 #endif
44 #endif
45
46 // TODO: #define WX_GMTOFF_IN_TM for Windows compilers which have it here
47
48 #if defined(__WIN32__) && !defined(WX_GMTOFF_IN_TM)
49 #include <windows.h>
50 #endif
51
52 #if defined(HAVE_GETTIMEOFDAY)
53 #include <sys/time.h>
54 #include <unistd.h>
55 #elif defined(HAVE_LOCALTIME)
56 #include <time.h>
57 #ifndef __WXMAC__
58 #include <sys/types.h> // for time_t
59 #endif
60 #elif defined(HAVE_FTIME)
61 #include <sys/timeb.h>
62 #else
63 #error "no function to find the current time on this system"
64 #endif
65
66 // ----------------------------------------------------------------------------
67 // macros
68 // ----------------------------------------------------------------------------
69
70 // on some really old systems gettimeofday() doesn't have the second argument,
71 // define wxGetTimeOfDay() to hide this difference
72 #ifdef HAVE_GETTIMEOFDAY
73 #ifdef WX_GETTIMEOFDAY_NO_TZ
74 struct timezone;
75 #define wxGetTimeOfDay(tv, tz) gettimeofday(tv)
76 #else
77 #define wxGetTimeOfDay(tv, tz) gettimeofday((tv), (tz))
78 #endif
79 #endif // HAVE_GETTIMEOFDAY
80
81 // ============================================================================
82 // implementation
83 // ============================================================================
84
85 // ----------------------------------------------------------------------------
86 // wxStopWatch
87 // ----------------------------------------------------------------------------
88
89 void wxStopWatch::Start(long t)
90 {
91 m_t0 = wxGetCurrentMTime() - t;
92
93 m_pause = 0;
94 }
95
96 long wxStopWatch::Time() const
97 {
98 return m_pause ? m_pause : GetElapsedTime();
99 }
100
101 // ----------------------------------------------------------------------------
102 // old timer functions superceded by wxStopWatch
103 // ----------------------------------------------------------------------------
104
105 static long wxStartTime = 0;
106
107 // starts the global timer
108 void wxStartTimer()
109 {
110 wxStartTime = wxGetCurrentMTime();
111 }
112
113 // Returns elapsed time in milliseconds
114 long wxGetElapsedTime(bool resetTimer)
115 {
116 long oldTime = wxStartTime;
117 long newTime = wxGetCurrentMTime();
118
119 if ( resetTimer )
120 wxStartTime = newTime;
121
122 return newTime - oldTime;
123 }
124
125
126 // Get number of seconds since 00:00:00 GMT, Jan 1st 1970.
127 long wxGetCurrentTime()
128 {
129 return wxGetCurrentMTime() / 1000;
130 }
131
132 // ----------------------------------------------------------------------------
133 // the functions to get the current time and timezone info
134 // ----------------------------------------------------------------------------
135
136 // return GMT time in millisecond
137 long wxGetCurrentMTime()
138 {
139 #if defined(__WIN32__)
140 SYSTEMTIME st;
141 ::GetLocalTime(&st);
142
143 return 1000*(60*(60*st.wHour+st.wMinute)+st.wSecond)+st.wMilliseconds;
144 #else
145 #if defined(HAVE_LOCALTIME)
146 time_t t0 = time(&t0);
147 if ( t0 != (time_t)-1 )
148 {
149 struct tm *tp = localtime(&t0);
150
151 if ( tp )
152 {
153 return 1000*(60*(60*tp->tm_hour+tp->tm_min)+tp->tm_sec);
154 }
155 }
156 #elif defined(HAVE_GETTIMEOFDAY)
157 struct timeval tp;
158 if ( wxGetTimeOfDay(&tp, (struct timezone *)NULL) != -1 )
159 {
160 return (1000*tp.tv_sec + tp.tv_usec / 1000);
161 }
162 #elif defined(HAVE_FTIME)
163 struct timeb tp;
164 if ( ftime(&tp) == 0 )
165 {
166 return (1000*tp.time + tp.millitm);
167 }
168 #else
169 #error "no function to find the current time on this system"
170 #endif
171
172 wxLogSysError(_("Failed to get the system time"));
173
174 return -1;
175 #endif // __WIN32__/!__WIN32__
176 }
177
178 bool wxGetLocalTime(long *timeZone, int *dstObserved)
179 {
180 #if defined(HAVE_LOCALTIME) && defined(WX_GMTOFF_IN_TM)
181 time_t t0 = time(&t0);
182 if ( t0 != (time_t)-1 )
183 {
184 struct tm *tm = localtime(&t0);
185
186 if ( tm )
187 {
188 *timeZone = tm->tm_gmtoff;
189 *dstObserved = tm->tm_isdst;
190
191 return TRUE;
192 }
193 }
194 #elif defined(HAVE_GETTIMEOFDAY) && !defined(WX_GETTIMEOFDAY_NO_TZ)
195 struct timeval tp;
196 struct timezone tz;
197 if ( gettimeofday(&tp, &tz) != -1 )
198 {
199 *timeZone = 60*tz.tz_minuteswest;
200 *dstObserved = tz.tz_dsttime;
201
202 return TRUE;
203 }
204 #elif defined(HAVE_FTIME)
205 struct timeb tb;
206 if ( ftime(&tb) == 0 )
207 {
208 *timeZone = 60*tb.timezone;
209 *dstObserved = tb.dstflag;
210 }
211 #else // no standard function return tz info
212 // special hacks for known compilers
213 #if defined(__BORLANDC__) || defined(__VISUALC__)
214 *timeZone = _timezone;
215 *dstObserved = _daylight;
216 #elif defined(__SALFORDC__)
217 *timeZone = _timezone;
218 *dstObserved = daylight;
219 #elif defined(__VISAGECPP__)
220 *timeZone = _timezone;
221 *dstObserved = daylight;
222 #elif defined(__WIN32__)
223 TIME_ZONE_INFORMATION tzInfo;
224 switch ( GetTimeZoneInformation(&tzInfo) )
225 {
226 default:
227 wxFAIL_MSG(_T("unknown GetTimeZoneInformation return code"));
228 // fall through
229
230 case TIME_ZONE_ID_UNKNOWN:
231 case TIME_ZONE_ID_STANDARD:
232 *dstObserved = FALSE;
233 break;
234
235 case TIME_ZONE_ID_DAYLIGHT:
236 *dstObserved = TRUE;
237 break;
238 }
239
240 *timeZone = 60*tzInfo.Bias;
241 #else
242 wxFAIL_MSG(_T("wxGetLocalTime() not implemented"));
243 #endif // compiler
244 #endif // all ways in the known Universe to get tz info
245
246 return FALSE;
247 }