]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/common/time.cpp
test for timegm() added
[wxWidgets.git] / src / common / time.cpp
... / ...
CommitLineData
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/*
17Provides an object that represents a Time, stored as the number of
18seconds 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
49IMPLEMENT_DYNAMIC_CLASS(wxTime, wxObject)
50#endif
51
52
53extern bool wxGetLocalTime(long *timeZone, int *dstObserved);
54extern long wxGetCurrentTime(void);
55
56static long TIME_ZONE; /* seconds west of GMT */
57static int DST_OBSERVED; /* flags U.S. daylight saving time observed */
58
59static bool wxTimeInitialized = FALSE;
60
61wxTime::tFormat wxTime::Format = wxTime::wx12h;
62wxTime::tPrecision wxTime::Precision = wxTime::wxStdMinSec;
63
64static const unsigned long seconds_in_day = 24*60*60L;
65static const wxDate refDate(1,1,1901);
66// static const wxDate maxDate(49709L); /* ((2**32)-1)/seconds_in_day -1 */
67
68wxTime 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
94wxTime::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
112wxTime::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
128wxTime::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__
158wxTime::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
172bool wxTime::IsBetween(const wxTime& a, const wxTime& b) const
173{
174 return *this >= a && *this <= b;
175}
176
177hourTy 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
186hourTy wxTime::GetHourGMT() const
187/*
188 Return the hour of this Time in GMT.
189*/
190{
191 return (hourTy)((sec % 86400) / 3600);
192}
193
194wxTime 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
211wxTime 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
221bool 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
243wxTime 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
253minuteTy 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
262minuteTy wxTime::GetMinuteGMT() const
263/*
264 Return the minute of this wxTime in GMT.
265*/
266{
267 return (minuteTy)(((sec % 86400) % 3600) / 60);
268}
269
270secondTy wxTime::GetSecond() const
271/*
272 Return the second of this wxTime.
273*/
274{
275 return (secondTy)(((sec % 86400) % 3600) % 60);
276}
277
278secondTy wxTime::GetSecondGMT() const
279/*
280 Return the minute of this wxTime in GMT.
281*/
282{
283 return (secondTy)(((sec % 86400) % 3600) % 60);
284}
285
286int wxTime::GetDay() const
287{
288 wxDate da((wxDate) *this);
289 return da.GetDay();
290}
291
292int wxTime::GetDayOfWeek() const
293{
294 wxDate da((wxDate) *this);
295 return da.GetDayOfWeek();
296}
297
298int wxTime::GetMonth() const
299{
300 wxDate da((wxDate) *this);
301 return da.GetMonth();
302}
303
304int wxTime::GetYear() const
305{
306 wxDate da((wxDate) *this);
307 return da.GetYear();
308}
309
310wxTime wxTime::Max(const wxTime& t) const
311{
312 if (t < *this) return *this;
313 return t;
314}
315
316wxTime wxTime::Min(const wxTime& t) const
317{
318 if (t > *this) return *this;
319 return t;
320}
321
322#ifndef __SALFORDC__
323wxTime::operator wxChar *(void)
324{
325 return FormatTime();
326}
327#endif
328
329void wxTime::SetFormat(const wxTime::tFormat lFormat,
330 const wxTime::tPrecision lPrecision) {
331
332 wxTime::Format = lFormat;
333 wxTime::Precision = lPrecision;
334}
335
336wxChar *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/*
367int 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
376void wxTime::deepenShallowCopy() {}
377
378unsigned wxTime::hash() const { return sec; }
379
380bool wxTime::isEqual(const Object& ob) const
381{
382 return ob.isSpecies(classDesc) && *this==castdown(ob);
383}
384
385const Class* wxTime::species() const { return &classDesc; }
386
387void 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
398wxTime::wxTime(OIOin& strm)
399 : BASE(strm)
400{
401 unsigned long usec;
402 strm >> sec >> usec;
403}
404
405void wxTime::storer(OIOout& strm) const
406{
407 BASE::storer(strm);
408 strm << sec << 0l;
409}
410
411
412wxTime::wxTime(OIOifd& fd)
413 : BASE(fd)
414{
415 unsigned long usec;
416 fd >> sec >> usec;
417}
418
419void wxTime::storer(OIOofd& fd) const
420{
421 BASE::storer(fd);
422 fd << sec << 0l;
423}
424*/
425
426#endif