Added some Motif wxGLCanvas support; some more Motif bugs cured; print dialogs
[wxWidgets.git] / src / common / time.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: time.cpp
3 // Purpose: wxTime class, from NIHCL
4 // Author: Julian Smart, after K. E. Gorlen
5 // Modified by:
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart and Markus Holzem
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "time.h"
14 #endif
15
16 /*
17 Provides an object that represents a Time, stored as the number of
18 seconds since January 1, 1901, GMT.
19 */
20
21 // For compilers that support precompilation, includes "wx.h".
22 #include "wx/wxprec.h"
23
24 #ifdef __BORLANDC__
25 #pragma hdrstop
26 #endif
27
28 #include "wx/setup.h"
29
30 #if wxUSE_TIMEDATE
31
32 #include "wx/time.h"
33 #include "wx/date.h"
34 #include "wx/utils.h"
35 #include <wx/intl.h>
36
37 #if wxUSE_IOSTREAMH
38 #include <iostream.h>
39 #include <iomanip.h>
40 #else
41 #include <iostream>
42 #include <iomanip>
43 # ifdef _MSC_VER
44 using namespace std;
45 # endif
46 #endif
47
48 #include <string.h>
49
50 #if !USE_SHARED_LIBRARY
51 IMPLEMENT_DYNAMIC_CLASS(wxTime, wxObject)
52 #endif
53
54
55 extern bool wxGetLocalTime(long *timeZone, int *dstObserved);
56 extern long wxGetCurrentTime(void);
57
58 static long TIME_ZONE; /* seconds west of GMT */
59 static int DST_OBSERVED; /* flags U.S. daylight saving time observed */
60
61 static bool wxTimeInitialized = FALSE;
62
63 wxTime::tFormat wxTime::Format = wxTime::wx12h;
64 wxTime::tPrecision wxTime::Precision = wxTime::wxStdMinSec;
65
66 static const unsigned long seconds_in_day = 24*60*60L;
67 static const wxDate refDate(1,1,1901);
68 // static const wxDate maxDate(49709L); /* ((2**32)-1)/seconds_in_day -1 */
69
70 wxTime wxTime::GetLocalTime(const wxDate& date, hourTy h, minuteTy m, secondTy s)
71 /*
72 Return a local wxTime for the specified Standard Time date, hour, minute,
73 and second.
74 */
75 {
76 if (!wxTimeInitialized)
77 {
78 wxGetLocalTime(&TIME_ZONE, &DST_OBSERVED);
79 wxTimeInitialized = TRUE;
80 }
81 /*
82 if (!date.IsBetween(refDate,maxDate))
83 setError(NIHCL_DATERANGE,DEFAULT,
84 date.dayOfMonth(),date.nameOfMonth(),date.year());
85 */
86 // The following line causes an error in GCC 2.1
87 // long daysBetween = date-refDate;
88 // ... but this seems to get round it.
89 wxDate tmp1(date);
90 wxDate tmp2(refDate);
91 long daysBetween = tmp1 - tmp2;
92
93 return wxTime(seconds_in_day*daysBetween + 60*60L*h + 60*m + s);
94 }
95
96 wxTime::wxTime()
97 /*
98 Construct a wxTime for this instant.
99 */
100 {
101 if (!wxTimeInitialized)
102 {
103 wxGetLocalTime(&TIME_ZONE, &DST_OBSERVED);
104 wxTimeInitialized = TRUE;
105 }
106 sec = wxGetCurrentTime();
107 #ifdef __SALFORDC__
108 sec += (unsigned long) 2177452800; /* seconds from 1/1/01 to 1/1/70 */
109 #else
110 sec += 2177452800UL; /* seconds from 1/1/01 to 1/1/70 */
111 #endif
112 }
113
114 wxTime::wxTime(hourTy h, minuteTy m, secondTy s, bool dst)
115 /*
116 Construct a wxTime for today at the specified (local) hour, minute, and
117 second.
118 */
119 {
120 if (!wxTimeInitialized)
121 {
122 wxGetLocalTime(&TIME_ZONE, &DST_OBSERVED);
123 wxTimeInitialized = TRUE;
124 }
125
126 sec = wxTime(wxDate(),h,m,s,dst).sec;
127 }
128
129
130 wxTime::wxTime(const wxDate& date, hourTy h, minuteTy m, secondTy s, bool dst)
131 /*
132 Construct a wxTime for the specified (local) Date, hour, minute, and
133 second.
134 */
135 {
136 if (!wxTimeInitialized)
137 {
138 wxGetLocalTime(&TIME_ZONE, &DST_OBSERVED);
139 wxTimeInitialized = TRUE;
140 }
141 sec = GetLocalTime(date,h,m,s).sec-3600;
142 if (IsDST())
143 {
144 sec += 3600;
145 if (IsDST() || dst) sec -= 3600;
146 }
147 else
148 {
149 sec += 3600;
150 /*
151 if (IsDST()) setError(NIHCL_BADTIME,DEFAULT,
152 date.dayOfMonth(),date.nameOfMonth(),date.year(),
153 h,m,s,(dst?_("DST"):""));
154 */
155 }
156 sec += TIME_ZONE; // adjust to GMT
157 }
158
159 #ifndef __SALFORDC__
160 wxTime::operator wxDate() const
161 /*
162 Convert a wxTime to a local wxDate
163 */
164 {
165 // return wxDate((int)(GetLocalTime().sec/seconds_in_day)); 4.2 cc bug
166 long daycount = (long)(GetLocalTime().sec/seconds_in_day);
167
168 wxDate date(1,1,1901);
169 date += daycount;
170 return date;
171 }
172 #endif
173
174 bool wxTime::IsBetween(const wxTime& a, const wxTime& b) const
175 {
176 return *this >= a && *this <= b;
177 }
178
179 hourTy wxTime::GetHour() const
180 /*
181 Return the hour of this wxTime in local time; i.e., adjust for
182 time zone and Daylight Savings Time.
183 */
184 {
185 return GetLocalTime().GetHourGMT();
186 }
187
188 hourTy wxTime::GetHourGMT() const
189 /*
190 Return the hour of this Time in GMT.
191 */
192 {
193 return (hourTy)((sec % 86400) / 3600);
194 }
195
196 wxTime wxTime::GetBeginDST(unsigned year)
197 /*
198 Return the local Standard Time at which Daylight Savings Time
199 begins in the specified year.
200 */
201 {
202 // Previous Sunday
203 wxTime DSTtime(GetLocalTime(wxDate(3,31,year).Previous(1)+7,2));
204 if (year<=1986) {
205 // Previous Sunday
206 DSTtime = GetLocalTime(wxDate(4,30,year).Previous(1),2);
207 if (year==1974) DSTtime = GetLocalTime(wxDate(1,6,1974),2);
208 if (year==1975) DSTtime = GetLocalTime(wxDate(2,23,1975),2);
209 }
210 return DSTtime;
211 }
212
213 wxTime wxTime::GetEndDST(unsigned year)
214 /*
215 Return the local Standard Time at which Daylight Savings Time
216 ends in the specified year.
217 */
218 {
219 wxTime STDtime(GetLocalTime(wxDate(10,31,year).Previous(1),2-1));
220 return STDtime;
221 }
222
223 bool wxTime::IsDST() const
224 /*
225 Return TRUE if this local Standard Time should be adjusted
226 for Daylight Savings Time.
227 */
228 {
229 long daycount = (long)(sec/seconds_in_day);
230
231 // At this point, daycount is the number of days from 1/1/1901.
232 // Need to convert to julian date (which starts at 1/1/4713 B.C.)
233 wxDate date(1,1,1901);
234 date += daycount;
235
236 unsigned year = date.GetYear();
237 if (DST_OBSERVED)
238 {
239 if (*this >= GetBeginDST(year))
240 if (*this < GetEndDST(year)) return TRUE;
241 }
242 return FALSE;
243 }
244
245 wxTime wxTime::GetLocalTime() const
246 /*
247 Adjusts this GM Time for local time zone and Daylight Savings Time.
248 */
249 {
250 wxTime local_time(sec-TIME_ZONE);
251 if (local_time.IsDST()) local_time.sec += 3600;
252 return local_time;
253 }
254
255 minuteTy wxTime::GetMinute() const
256 /*
257 Return the minute of this wxTime in local time; i.e., adjust
258 for time zone and Daylight Savings Time.
259 */
260 {
261 return GetLocalTime().GetMinuteGMT();
262 }
263
264 minuteTy wxTime::GetMinuteGMT() const
265 /*
266 Return the minute of this wxTime in GMT.
267 */
268 {
269 return (minuteTy)(((sec % 86400) % 3600) / 60);
270 }
271
272 secondTy wxTime::GetSecond() const
273 /*
274 Return the second of this wxTime.
275 */
276 {
277 return (secondTy)(((sec % 86400) % 3600) % 60);
278 }
279
280 secondTy wxTime::GetSecondGMT() const
281 /*
282 Return the minute of this wxTime in GMT.
283 */
284 {
285 return (secondTy)(((sec % 86400) % 3600) % 60);
286 }
287
288 int wxTime::GetDay() const
289 {
290 wxDate da((wxDate) *this);
291 return da.GetDay();
292 }
293
294 int wxTime::GetDayOfWeek() const
295 {
296 wxDate da((wxDate) *this);
297 return da.GetDayOfWeek();
298 }
299
300 int wxTime::GetMonth() const
301 {
302 wxDate da((wxDate) *this);
303 return da.GetMonth();
304 }
305
306 int wxTime::GetYear() const
307 {
308 wxDate da((wxDate) *this);
309 return da.GetYear();
310 }
311
312 wxTime wxTime::Max(const wxTime& t) const
313 {
314 if (t < *this) return *this;
315 return t;
316 }
317
318 wxTime wxTime::Min(const wxTime& t) const
319 {
320 if (t > *this) return *this;
321 return t;
322 }
323
324 #ifndef __SALFORDC__
325 wxTime::operator char *(void)
326 {
327 return FormatTime();
328 }
329 #endif
330
331 void wxTime::SetFormat(const wxTime::tFormat lFormat,
332 const wxTime::tPrecision lPrecision) {
333
334 wxTime::Format = lFormat;
335 wxTime::Precision = lPrecision;
336 }
337
338 char *wxTime::FormatTime() const {
339 static char timeBuf[30];
340 unsigned hh(GetHour());
341
342 switch (Format) {
343 case wx12h:
344 hh -= 12;
345 break;
346 case wx24h:
347 break;
348 }
349
350 switch (Precision) {
351 case wxStdMinSec:
352 sprintf(timeBuf,"%2d:%02d:%02d",hh,GetMinute(),GetSecond());
353 break;
354 case wxStdMin:
355 sprintf(timeBuf,"%2d:%02d",hh,GetMinute());
356 break;
357 }
358
359 if (Format == wx12h)
360 if (GetHour() <= 12)
361 strcat(timeBuf,_("am"));
362 else
363 strcat(timeBuf,_("pm"));
364
365 return timeBuf;
366 }
367
368 /*
369 int wxTime::compare(const Object& ob) const
370 {
371 assertArgSpecies(ob,classDesc,"compare");
372 register clockTy t = castdown(ob).sec;
373 if (sec < t) return -1;
374 if (sec > t) return 1;
375 return 0;
376 }
377
378 void wxTime::deepenShallowCopy() {}
379
380 unsigned wxTime::hash() const { return sec; }
381
382 bool wxTime::isEqual(const Object& ob) const
383 {
384 return ob.isSpecies(classDesc) && *this==castdown(ob);
385 }
386
387 const Class* wxTime::species() const { return &classDesc; }
388
389 void wxTime::printOn(ostream& strm) const
390 {
391 register unsigned hh = GetHour();
392 wxDate(*this).printOn(strm);
393 strm << ' ' << ((hh <= 12) ? hh : hh-12) << ':'
394 << setfill('0') << setw(2) << GetMinute() << ':'
395 << setfill('0') << setw(2) << GetSecond() << ' ';
396 if (hh < 12) strm << _("am");
397 else strm << _("pm");
398 }
399
400 wxTime::wxTime(OIOin& strm)
401 : BASE(strm)
402 {
403 unsigned long usec;
404 strm >> sec >> usec;
405 }
406
407 void wxTime::storer(OIOout& strm) const
408 {
409 BASE::storer(strm);
410 strm << sec << 0l;
411 }
412
413
414 wxTime::wxTime(OIOifd& fd)
415 : BASE(fd)
416 {
417 unsigned long usec;
418 fd >> sec >> usec;
419 }
420
421 void wxTime::storer(OIOofd& fd) const
422 {
423 BASE::storer(fd);
424 fd << sec << 0l;
425 }
426 */
427
428 #endif