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