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