*** empty log message ***
[wxWidgets.git] / src / common / timercmn.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: common/timercmn.cpp
3 // Purpose: Common timer implementation
4 // Author: Julian Smart (original version)
5 // Modified by: Vadim Zeitlin on 12.11.99 to get rid of all ifdefs
6 // Sylvain Bougnoux to add wxStopWatch class
7 //
8 // Completely rewritten from scratch on Dic/99 by
9 // Guillermo Rodriguez <guille@iies.es>
10 //
11 // Created: 04/01/98
12 // RCS-ID: $Id$
13 // Copyright: (c) Julian Smart and Markus Holzem
14 // (c) 1999 Guillermo Rodriguez <guille@iies.es>
15 // Licence: wxWindows license
16 /////////////////////////////////////////////////////////////////////////////
17
18 // ============================================================================
19 // declarations
20 // ============================================================================
21
22 // ----------------------------------------------------------------------------
23 // headers
24 // ----------------------------------------------------------------------------
25
26 #ifdef __GNUG__
27 #pragma implementation "timerbase.h"
28 #endif
29
30 // For compilers that support precompilation, includes "wx.h".
31 #include "wx/wxprec.h"
32
33 #ifdef __BORLANDC__
34 #pragma hdrstop
35 #endif
36
37 #ifndef WX_PRECOMP
38 #include "wx/intl.h"
39 #include "wx/log.h"
40 #endif
41
42 #include "wx/timer.h"
43 #include "wx/longlong.h"
44
45 #if defined(__WIN32__)
46 #include <windows.h>
47 #endif
48
49 #include <time.h>
50 #ifndef __WXMAC__
51 #include <sys/types.h> // for time_t
52 #endif
53
54 #if defined(HAVE_GETTIMEOFDAY)
55 #include <sys/time.h>
56 #include <unistd.h>
57 #elif defined(HAVE_FTIME)
58 #include <sys/timeb.h>
59 #endif
60
61 // ----------------------------------------------------------------------------
62 // macros
63 // ----------------------------------------------------------------------------
64
65 // on some really old systems gettimeofday() doesn't have the second argument,
66 // define wxGetTimeOfDay() to hide this difference
67 #ifdef HAVE_GETTIMEOFDAY
68 #ifdef WX_GETTIMEOFDAY_NO_TZ
69 struct timezone;
70 #define wxGetTimeOfDay(tv, tz) gettimeofday(tv)
71 #else
72 #define wxGetTimeOfDay(tv, tz) gettimeofday((tv), (tz))
73 #endif
74 #endif // HAVE_GETTIMEOFDAY
75
76 // ============================================================================
77 // implementation
78 // ============================================================================
79
80 wxLongLong wxGetLocalTimeMillis();
81
82 // ----------------------------------------------------------------------------
83 // wxStopWatch
84 // ----------------------------------------------------------------------------
85
86 void wxStopWatch::Start(long t)
87 {
88 m_t0 = wxGetLocalTimeMillis() - t;
89
90 m_pause = 0;
91 }
92
93 long wxStopWatch::Time() const
94 {
95 return (m_pause ? m_pause : GetElapsedTime());
96 }
97
98 long wxStopWatch::GetElapsedTime() const
99 {
100 return (wxGetLocalTimeMillis() - m_t0).GetLo();
101 }
102
103 // ----------------------------------------------------------------------------
104 // old timer functions superceded by wxStopWatch
105 // ----------------------------------------------------------------------------
106
107 static wxLongLong wxStartTime = 0;
108
109 // starts the global timer
110 void wxStartTimer()
111 {
112 wxStartTime = wxGetLocalTimeMillis();
113 }
114
115 // Returns elapsed time in milliseconds
116 long wxGetElapsedTime(bool resetTimer)
117 {
118 wxLongLong oldTime = wxStartTime;
119 wxLongLong newTime = wxGetLocalTimeMillis();
120
121 if ( resetTimer )
122 wxStartTime = newTime;
123
124 return (newTime - oldTime).GetLo();
125 }
126
127
128 // ----------------------------------------------------------------------------
129 // the functions to get the current time and timezone info
130 // ----------------------------------------------------------------------------
131
132 // Get local time as seconds since 00:00:00, Jan 1st 1970
133 long wxGetLocalTime()
134 {
135 struct tm tm;
136 time_t t0, t1;
137
138 // This cannot be made static because mktime can overwrite it.
139 //
140 memset(&tm, 0, sizeof(tm));
141 tm.tm_year = 70;
142 tm.tm_mon = 0;
143 tm.tm_mday = 5; // not Jan 1st 1970 due to mktime 'feature'
144 tm.tm_hour = 0;
145 tm.tm_min = 0;
146 tm.tm_sec = 0;
147 tm.tm_isdst = -1; // let mktime guess
148
149 // Note that mktime assumes that the struct tm contains local time.
150 //
151 t1 = time(&t1); // now
152 t0 = mktime(&tm); // origin
153
154 // Return the difference in seconds.
155 //
156 if (( t0 != (time_t)-1 ) && ( t1 != (time_t)-1 ))
157 return (long)difftime(t1, t0) + (60 * 60 * 24 * 4);
158
159 wxLogSysError(_("Failed to get the local system time"));
160 return -1;
161 }
162
163 // Get UTC time as seconds since 00:00:00, Jan 1st 1970
164 long wxGetUTCTime()
165 {
166 struct tm tm, *ptm;
167 time_t t0, t1;
168
169 // This cannot be made static because mktime can overwrite it
170 //
171 memset(&tm, 0, sizeof(tm));
172 tm.tm_year = 70;
173 tm.tm_mon = 0;
174 tm.tm_mday = 5; // not Jan 1st 1970 due to mktime 'feature'
175 tm.tm_hour = 0;
176 tm.tm_min = 0;
177 tm.tm_sec = 0;
178 tm.tm_isdst = -1; // let mktime guess
179
180 // Note that mktime assumes that the struct tm contains local time.
181 //
182 t1 = time(&t1); // now
183 t0 = mktime(&tm); // origin in localtime
184
185 if (( t0 != (time_t)-1 ) && ( t1 != (time_t)-1 ))
186 {
187 // To get t0 as GMT we convert to a struct tm with gmtime,
188 // and then back again.
189 //
190 ptm = gmtime(&t0);
191
192 if (ptm)
193 {
194 memcpy(&tm, ptm, sizeof(tm));
195 t0 = mktime(&tm);
196
197 if (t0 != (time_t)-1 )
198 return (long)difftime(t1, t0) + (60 * 60 * 24 * 4);
199 wxLogSysError(_("Failed 2nd mktime"));
200 }
201 wxLogSysError(_("Failed gmtime"));
202 }
203 wxLogSysError(_("Failed to get the UTC system time"));
204 return -1;
205 }
206
207
208 // Get local time as milliseconds since 00:00:00, Jan 1st 1970
209 wxLongLong wxGetLocalTimeMillis()
210 {
211 // We use wxGetLocalTime() to get the seconds since
212 // 00:00:00 Jan 1st 1970 and then whatever is available
213 // to get millisecond resolution.
214 //
215 wxLongLong val = 1000 * wxGetLocalTime();
216
217 // If we got here, do not fail even if we can't get
218 // millisecond resolution.
219 //
220 #if defined(__WIN32__)
221 SYSTEMTIME st;
222 ::GetLocalTime(&st);
223 return (val + st.wMilliseconds);
224 #elif defined(HAVE_GETTIMEOFDAY)
225 struct timeval tp;
226 if ( wxGetTimeOfDay(&tp, (struct timezone *)NULL) != -1 )
227 {
228 return (val + (tp.tv_usec / 1000));
229 }
230 #elif defined(HAVE_FTIME)
231 struct timeb tp;
232 if ( ftime(&tp) == 0 )
233 {
234 return (val + tp.millitm);
235 }
236 #endif
237
238 return val;
239 }