]> git.saurik.com Git - wxWidgets.git/blame - src/common/time.cpp
wxDateTime::ParseFormat() and ParseTime() added (compile but don't work)
[wxWidgets.git] / src / common / time.cpp
CommitLineData
c801d85f
KB
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
3f4a0c5b 9// Licence: wxWindows license
c801d85f
KB
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
9838df2c 30#if wxUSE_TIMEDATE
c801d85f
KB
31
32#include "wx/time.h"
33#include "wx/date.h"
34#include "wx/utils.h"
3f4a0c5b
VZ
35#include "wx/intl.h"
36
be087207
RR
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
c801d85f
KB
44#endif
45
c801d85f 46#include <string.h>
300b1288 47#include <time.h>
c801d85f 48
c801d85f 49IMPLEMENT_DYNAMIC_CLASS(wxTime, wxObject)
c801d85f
KB
50
51
300b1288
GRG
52#ifndef WX_TIMEZONE
53 #define WX_TIMEZONE _timezone
54#endif
55
56extern long wxGetUTCTime(void);
57bool 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
c801d85f
KB
76
77static long TIME_ZONE; /* seconds west of GMT */
78static int DST_OBSERVED; /* flags U.S. daylight saving time observed */
79
80static bool wxTimeInitialized = FALSE;
81
3f4a0c5b 82wxTime::tFormat wxTime::Format = wxTime::wx12h;
300b1288 83wxTime::tPrecision wxTime::Precision = wxTime::wxStdMinSec;
c801d85f
KB
84
85static const unsigned long seconds_in_day = 24*60*60L;
86static const wxDate refDate(1,1,1901);
87// static const wxDate maxDate(49709L); /* ((2**32)-1)/seconds_in_day -1 */
88
89wxTime wxTime::GetLocalTime(const wxDate& date, hourTy h, minuteTy m, secondTy s)
90/*
3f4a0c5b
VZ
91 Return a local wxTime for the specified Standard Time date, hour, minute,
92 and second.
c801d85f
KB
93*/
94{
95 if (!wxTimeInitialized)
96 {
300b1288 97 wxGetTZandDST(&TIME_ZONE, &DST_OBSERVED);
3f4a0c5b 98 wxTimeInitialized = TRUE;
c801d85f
KB
99 }
100/*
3f4a0c5b
VZ
101 if (!date.IsBetween(refDate,maxDate))
102 setError(NIHCL_DATERANGE,DEFAULT,
103 date.dayOfMonth(),date.nameOfMonth(),date.year());
c801d85f
KB
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
115wxTime::wxTime()
116/*
3f4a0c5b 117 Construct a wxTime for this instant.
c801d85f
KB
118*/
119{
120 if (!wxTimeInitialized)
121 {
300b1288 122 wxGetTZandDST(&TIME_ZONE, &DST_OBSERVED);
3f4a0c5b 123 wxTimeInitialized = TRUE;
c801d85f 124 }
300b1288 125 sec = wxGetUTCTime();
ce3ed50d
JS
126#ifdef __SALFORDC__
127 sec += (unsigned long) 2177452800; /* seconds from 1/1/01 to 1/1/70 */
128#else
1f0299c1 129 sec += 2177452800UL; /* seconds from 1/1/01 to 1/1/70 */
ce3ed50d 130#endif
c801d85f
KB
131}
132
133wxTime::wxTime(hourTy h, minuteTy m, secondTy s, bool dst)
134/*
3f4a0c5b
VZ
135 Construct a wxTime for today at the specified (local) hour, minute, and
136 second.
c801d85f
KB
137*/
138{
139 if (!wxTimeInitialized)
140 {
300b1288 141 wxGetTZandDST(&TIME_ZONE, &DST_OBSERVED);
3f4a0c5b 142 wxTimeInitialized = TRUE;
c801d85f
KB
143 }
144
145 sec = wxTime(wxDate(),h,m,s,dst).sec;
146}
147
148
149wxTime::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 {
300b1288 157 wxGetTZandDST(&TIME_ZONE, &DST_OBSERVED);
3f4a0c5b 158 wxTimeInitialized = TRUE;
c801d85f
KB
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,
3f4a0c5b 171 date.dayOfMonth(),date.nameOfMonth(),date.year(),
9b64e798 172 h,m,s,(dst?_("DST"):""));
c801d85f
KB
173*/
174 }
175 sec += TIME_ZONE; // adjust to GMT
176}
177
ce3ed50d 178#ifndef __SALFORDC__
c801d85f
KB
179wxTime::operator wxDate() const
180/*
3f4a0c5b 181 Convert a wxTime to a local wxDate
c801d85f
KB
182*/
183{
184// return wxDate((int)(GetLocalTime().sec/seconds_in_day)); 4.2 cc bug
3f4a0c5b 185 long daycount = (long)(GetLocalTime().sec/seconds_in_day);
c801d85f
KB
186
187 wxDate date(1,1,1901);
188 date += daycount;
189 return date;
190}
ce3ed50d 191#endif
c801d85f
KB
192
193bool wxTime::IsBetween(const wxTime& a, const wxTime& b) const
194{
195 return *this >= a && *this <= b;
196}
197
198hourTy wxTime::GetHour() const
199/*
3f4a0c5b 200 Return the hour of this wxTime in local time; i.e., adjust for
c801d85f
KB
201 time zone and Daylight Savings Time.
202*/
203{
3f4a0c5b 204 return GetLocalTime().GetHourGMT();
c801d85f
KB
205}
206
207hourTy wxTime::GetHourGMT() const
208/*
209 Return the hour of this Time in GMT.
210*/
211{
3f4a0c5b 212 return (hourTy)((sec % 86400) / 3600);
c801d85f
KB
213}
214
215wxTime wxTime::GetBeginDST(unsigned year)
216/*
3f4a0c5b 217 Return the local Standard Time at which Daylight Savings Time
c801d85f
KB
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
3f4a0c5b
VZ
225 DSTtime = GetLocalTime(wxDate(4,30,year).Previous(1),2);
226 if (year==1974) DSTtime = GetLocalTime(wxDate(1,6,1974),2);
c801d85f
KB
227 if (year==1975) DSTtime = GetLocalTime(wxDate(2,23,1975),2);
228 }
229 return DSTtime;
230}
231
232wxTime wxTime::GetEndDST(unsigned year)
233/*
234 Return the local Standard Time at which Daylight Savings Time
235 ends in the specified year.
236*/
237{
3f4a0c5b
VZ
238 wxTime STDtime(GetLocalTime(wxDate(10,31,year).Previous(1),2-1));
239 return STDtime;
c801d85f
KB
240}
241
242bool 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.
3f4a0c5b
VZ
251 // Need to convert to julian date (which starts at 1/1/4713 B.C.)
252 wxDate date(1,1,1901);
c801d85f
KB
253 date += daycount;
254
255 unsigned year = date.GetYear();
3f4a0c5b 256 if (DST_OBSERVED)
c801d85f
KB
257 {
258 if (*this >= GetBeginDST(year))
259 if (*this < GetEndDST(year)) return TRUE;
260 }
261 return FALSE;
262}
263
264wxTime wxTime::GetLocalTime() const
265/*
266 Adjusts this GM Time for local time zone and Daylight Savings Time.
267*/
268{
3f4a0c5b 269 wxTime local_time(sec-TIME_ZONE);
c801d85f
KB
270 if (local_time.IsDST()) local_time.sec += 3600;
271 return local_time;
272}
273
274minuteTy wxTime::GetMinute() const
275/*
276 Return the minute of this wxTime in local time; i.e., adjust
3f4a0c5b 277 for time zone and Daylight Savings Time.
c801d85f
KB
278*/
279{
280 return GetLocalTime().GetMinuteGMT();
281}
282
283minuteTy wxTime::GetMinuteGMT() const
284/*
285 Return the minute of this wxTime in GMT.
286*/
287{
3f4a0c5b 288 return (minuteTy)(((sec % 86400) % 3600) / 60);
c801d85f
KB
289}
290
291secondTy wxTime::GetSecond() const
292/*
293 Return the second of this wxTime.
294*/
295{
3f4a0c5b 296 return (secondTy)(((sec % 86400) % 3600) % 60);
c801d85f
KB
297}
298
aa0b7e1e
JS
299secondTy wxTime::GetSecondGMT() const
300/*
301 Return the minute of this wxTime in GMT.
302*/
303{
304 return (secondTy)(((sec % 86400) % 3600) % 60);
305}
306
307int wxTime::GetDay() const
308{
309 wxDate da((wxDate) *this);
310 return da.GetDay();
311}
312
313int wxTime::GetDayOfWeek() const
314{
315 wxDate da((wxDate) *this);
316 return da.GetDayOfWeek();
317}
318
319int wxTime::GetMonth() const
320{
321 wxDate da((wxDate) *this);
322 return da.GetMonth();
323}
324
325int wxTime::GetYear() const
326{
327 wxDate da((wxDate) *this);
328 return da.GetYear();
329}
330
c801d85f
KB
331wxTime wxTime::Max(const wxTime& t) const
332{
333 if (t < *this) return *this;
334 return t;
335}
336
337wxTime wxTime::Min(const wxTime& t) const
338{
339 if (t > *this) return *this;
3f4a0c5b 340 return t;
c801d85f
KB
341}
342
ce3ed50d 343#ifndef __SALFORDC__
84fff0b3 344wxTime::operator wxChar *(void)
c801d85f
KB
345{
346 return FormatTime();
347}
ce3ed50d 348#endif
c801d85f
KB
349
350void wxTime::SetFormat(const wxTime::tFormat lFormat,
3f4a0c5b 351 const wxTime::tPrecision lPrecision) {
c801d85f 352
3f4a0c5b
VZ
353 wxTime::Format = lFormat;
354 wxTime::Precision = lPrecision;
c801d85f
KB
355}
356
84fff0b3
OK
357wxChar *wxTime::FormatTime() const {
358 static wxChar timeBuf[30];
3f4a0c5b
VZ
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:
223d09f6 371 wxSprintf(timeBuf,wxT("%2d:%02d:%02d"),hh,GetMinute(),GetSecond());
3f4a0c5b
VZ
372 break;
373 case wxStdMin:
223d09f6 374 wxSprintf(timeBuf,wxT("%2d:%02d"),hh,GetMinute());
3f4a0c5b
VZ
375 break;
376 }
377
378 if (Format == wx12h)
379 if (GetHour() <= 12)
84fff0b3 380 wxStrcat(timeBuf,_("am"));
3f4a0c5b 381 else
84fff0b3 382 wxStrcat(timeBuf,_("pm"));
3f4a0c5b
VZ
383
384 return timeBuf;
c801d85f
KB
385}
386
387/*
388int wxTime::compare(const Object& ob) const
389{
3f4a0c5b 390 assertArgSpecies(ob,classDesc,"compare");
c801d85f
KB
391 register clockTy t = castdown(ob).sec;
392 if (sec < t) return -1;
393 if (sec > t) return 1;
394 return 0;
395}
396
397void wxTime::deepenShallowCopy() {}
398
399unsigned wxTime::hash() const { return sec; }
400
401bool wxTime::isEqual(const Object& ob) const
402{
403 return ob.isSpecies(classDesc) && *this==castdown(ob);
404}
405
406const Class* wxTime::species() const { return &classDesc; }
407
408void 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() << ':'
3f4a0c5b 414 << setfill('0') << setw(2) << GetSecond() << ' ';
1a5a8367
DP
415 if (hh < 12) strm << _("am");
416 else strm << _("pm");
c801d85f
KB
417}
418
419wxTime::wxTime(OIOin& strm)
3f4a0c5b 420 : BASE(strm)
c801d85f 421{
3f4a0c5b
VZ
422 unsigned long usec;
423 strm >> sec >> usec;
c801d85f
KB
424}
425
426void wxTime::storer(OIOout& strm) const
427{
428 BASE::storer(strm);
429 strm << sec << 0l;
430}
431
432
433wxTime::wxTime(OIOifd& fd)
3f4a0c5b 434 : BASE(fd)
c801d85f 435{
3f4a0c5b
VZ
436 unsigned long usec;
437 fd >> sec >> usec;
c801d85f
KB
438}
439
440void wxTime::storer(OIOofd& fd) const
441{
3f4a0c5b
VZ
442 BASE::storer(fd);
443 fd << sec << 0l;
c801d85f
KB
444}
445*/
446
447#endif