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