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