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