]>
git.saurik.com Git - wxWidgets.git/blob - src/common/date.cpp
1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxDate class
5 // Originally inspired by Steve Marcus (CIS 72007,1233) 6/16/91
6 // Enhanced by Eric Simon (CIS 70540,1522) 6/29/91
7 // Further Enhanced by Chris Hill (CIS 72030,2606) 7/11/91
8 // Still Further Enhanced by Hill & Simon v3.10 8/05/91
9 // Version 4 by Charles D. Price 6/27/92
10 // Integrated into wxWindows by Julian Smart 9th July 1995
14 // Copyright: (c) Julian Smart and Markus Holzem
15 // Licence: wxWindows licence
16 /////////////////////////////////////////////////////////////////////////////
19 #pragma implementation "date.h"
22 // For compilers that support precompilation, includes "wx.h".
23 #include "wx/wxprec.h"
38 #include "wx/ioswrap.h"
45 static const wxChar
*dayname
[] = {
46 wxT("Sunday"), wxT("Monday"), wxT("Tuesday"), wxT("Wednesday"),
47 wxT("Thursday"), wxT("Friday"), wxT("Saturday")
50 static const wxChar
*mname
[] = {
51 wxT("January"), wxT("February"), wxT("March"), wxT("April"), wxT("May"), wxT("June"),
52 wxT("July"), wxT("August"), wxT("September"), wxT("October"), wxT("November"), wxT("December")
55 static int GauDays
[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
57 #if !USE_SHARED_LIBRARY
58 IMPLEMENT_DYNAMIC_CLASS(wxDate
, wxObject
)
61 ////////////////////////////////////////////////////////////
63 ////////////////////////////////////////////////////////////
69 month
= day
= year
= day_of_week
= 0;
73 wxDate::wxDate (long j
) : julian(j
)
80 wxDate::wxDate (int m
, int d
, int y
) : month(m
), day(d
), year(y
)
87 wxDate::wxDate (const wxString
& dat
)
91 if (wxStrcmp(dat
, wxT("TODAY")) == 0 || wxStrcmp(dat
, wxT("today")) == 0)
93 // Sets the current date
101 wxChar
*save_ptr
, *token
= wxStrtok(buf
,wxT("/-"),&save_ptr
);
102 month
= wxAtoi(token
);
103 day
= wxAtoi(wxStrtok((wxChar
*) NULL
,wxT("/-"),&save_ptr
));
104 year
= wxAtoi(wxStrtok((wxChar
*) NULL
,wxT(" "),&save_ptr
));
110 wxDate::wxDate (const wxDate
&dt
)
112 DisplayFormat
=dt
.DisplayFormat
;
113 DisplayOptions
=dt
.DisplayOptions
;
120 void wxDate::operator = (const wxDate
&dt
)
122 DisplayFormat
=dt
.DisplayFormat
;
123 DisplayOptions
=dt
.DisplayOptions
;
127 mdy_to_julian (); // wxUSE_TIMEDATE
130 void wxDate::operator = (const wxString
& dat
)
134 if (wxStrcmp(dat
, wxT("TODAY")) == 0 || wxStrcmp(dat
, wxT("today")) == 0)
136 // Sets the current date
144 wxChar
*save_ptr
, *token
= wxStrtok(buf
,wxT("/-"),&save_ptr
);
145 month
= wxAtoi(token
);
146 day
= wxAtoi(wxStrtok((wxChar
*) NULL
,wxT("/-"),&save_ptr
));
147 year
= wxAtoi(wxStrtok((wxChar
*) NULL
,wxT(" "),&save_ptr
));
153 //////////////////////////////////////////////////////////////
154 // Conversion operations
155 //////////////////////////////////////////////////////////////
158 wxDate::operator wxString( void )
164 //////////////////////////////////////////////////////////////
166 //////////////////////////////////////////////////////////////
168 wxDate
wxDate::operator + (long i
)
170 wxDate
dp(julian
+ i
);
174 wxDate
wxDate::operator + (int i
)
176 wxDate
dp(julian
+ (long)i
);
180 wxDate
wxDate::operator - (long i
)
182 wxDate
dp(julian
- i
);
186 wxDate
wxDate::operator - (int i
)
188 wxDate
dp(julian
- (long)i
);
192 long wxDate::operator - (const wxDate
&dt
)
194 return ( julian
- dt
.julian
);
197 wxDate
&wxDate::operator += (long i
)
204 wxDate
&wxDate::operator -= (long i
)
211 wxDate
&wxDate::operator ++()
218 wxDate
&wxDate::operator ++(int)
225 wxDate
&wxDate::operator --()
232 wxDate
&wxDate::operator --(int)
239 //////////////////////////////////////////////////////////////
241 //////////////////////////////////////////////////////////////
243 bool WXDLLEXPORT
operator < (const wxDate
&dt1
, const wxDate
&dt2
)
245 return ( dt1
.julian
< dt2
.julian
);
248 bool WXDLLEXPORT
operator <= (const wxDate
&dt1
, const wxDate
&dt2
)
250 return ( (dt1
.julian
== dt2
.julian
) || (dt1
.julian
< dt2
.julian
) );
253 bool WXDLLEXPORT
operator > (const wxDate
&dt1
, const wxDate
&dt2
)
255 return ( dt1
.julian
> dt2
.julian
);
258 bool WXDLLEXPORT
operator >= (const wxDate
&dt1
, const wxDate
&dt2
)
260 return ( (dt1
.julian
== dt2
.julian
) || (dt1
.julian
> dt2
.julian
) );
263 bool WXDLLEXPORT
operator == (const wxDate
&dt1
, const wxDate
&dt2
)
265 return ( dt1
.julian
== dt2
.julian
);
268 bool WXDLLEXPORT
operator != (const wxDate
&dt1
, const wxDate
&dt2
)
270 return ( dt1
.julian
!= dt2
.julian
);
274 #if wxUSE_STD_IOSTREAM
276 ////////////////////////////////////////////////////////////////
277 // Ostream operations
278 ////////////////////////////////////////////////////////////////
280 ostream WXDLLEXPORT
& operator << (ostream
&os
, const wxDate
&dt
)
282 return os
<< dt
.FormatDate().mb_str();
287 //////////////////////////////////////////////////////////////
288 // Conversion routines
289 //////////////////////////////////////////////////////////////
291 void wxDate::julian_to_wday (void)
293 // Correction by Peter Stadel <peters@jetcity.com>
294 day_of_week
= ((julian
- 2) % 7L);
296 day_of_week = (int) ((julian + 2) % 7 + 1);
300 void wxDate::julian_to_mdy ()
302 long a
,b
,c
,d
,e
,z
,alpha
;
304 // dealing with Gregorian calendar reform
308 alpha
= (long) ((z
-1867216.25) / 36524.25);
309 a
= z
+ 1 + alpha
- alpha
/4;
311 b
= ( a
> 1721423 ? a
+ 1524 : a
+ 1158 );
312 c
= (long) ((b
- 122.1) / 365.25);
313 d
= (long) (365.25 * c
);
314 e
= (long) ((b
- d
) / 30.6001);
315 day
= (int)(b
- d
- (long)(30.6001 * e
));
316 month
= (int)((e
< 13.5) ? e
- 1 : e
- 13);
317 year
= (int)((month
> 2.5 ) ? (c
- 4716) : c
- 4715);
321 void wxDate::mdy_to_julian (void)
324 int work_month
=month
, work_day
=day
, work_year
=year
;
325 // correct for negative year
329 { work_year
--; work_month
+=12; }
331 // deal with Gregorian calendar
332 if (work_year
*10000. + work_month
*100. + work_day
>= 15821015.)
334 a
= (int)(work_year
/100.);
337 julian
= (long) (365.25*work_year
) +
338 (long) (30.6001 * (work_month
+1)) + work_day
+ 1720994L + b
;
342 ////////////////////////////////////////////////////////////////
344 ////////////////////////////////////////////////////////////////
346 wxString
wxDate::FormatDate (int type
) const
348 int actualType
= type
;
349 if (actualType
== -1)
350 actualType
= DisplayFormat
;
354 memset( buf
, '\0', sizeof(buf
) );
355 switch ( actualType
)
358 if ( (day_of_week
< 1) || (day_of_week
> 7) )
359 wxStrcpy(buf
, _("invalid day"));
361 wxStrncpy( buf
, wxGetTranslation(dayname
[day_of_week
-1]),
362 (DisplayOptions
& wxDATE_ABBR
) ? ABBR_LENGTH
: 9);
363 return wxString(buf
);
366 if ( (month
< 1) || (month
> 12) )
367 wxStrcpy(buf
, _("invalid month"));
369 wxStrncpy( buf
, wxGetTranslation(mname
[month
-1]),
370 (DisplayOptions
& wxDATE_ABBR
) ? ABBR_LENGTH
: 9);
371 return wxString(buf
);
374 if ( (month
< 1) || (month
> 12) || (day_of_week
< 0) ||
377 wxStrcpy(buf
, _("invalid date"));
378 return wxString(buf
);
380 wxStrncpy( buf
, wxGetTranslation(dayname
[day_of_week
-1]),
381 (DisplayOptions
& wxDATE_ABBR
) ? ABBR_LENGTH
: 9);
382 wxStrcat( buf
, wxT(", "));
383 wxStrncat( buf
, wxGetTranslation(mname
[month
-1]),
384 (DisplayOptions
& wxDATE_ABBR
) ? ABBR_LENGTH
: 9);
385 wxStrcat( buf
, wxT(" "));
386 wxSprintf( buf
+wxStrlen(buf
), wxT("%d, %d"), day
, abs(year
) );
388 wxStrcat(buf
,_(" B.C."));
389 return wxString(buf
);
392 if ( (month
< 1) || (month
> 12) || (day_of_week
< 0) ||
395 wxStrcpy(buf
, _("invalid date"));
396 return wxString(buf
);
398 wxSprintf(buf
,wxT("%d "), day
);
399 wxStrncat(buf
, wxGetTranslation(mname
[month
-1]),
400 (DisplayOptions
& wxDATE_ABBR
) ? ABBR_LENGTH
: 9);
401 wxSprintf( buf
+wxStrlen(buf
), wxT(" %d"), abs(year
) );
403 wxStrcat(buf
, _(" B.C."));
404 return wxString(buf
);
408 if (day
==0 || month
==0 || year
==0)
409 wxStrcpy(buf
, _("invalid date"));
411 wxSprintf( buf
+wxStrlen(buf
), wxT("%1d/%1d/%02d"), month
, day
,
412 (DisplayOptions
& wxNO_CENTURY
) && (abs(year
) > 1899)
413 ? (abs(year
) - (abs(year
) / 100 * 100))
415 return wxString(buf
);
417 return wxString(wxT(""));
420 void wxDate::SetFormat( int format
)
422 DisplayFormat
= format
;
425 int wxDate::SetOption( int option
, bool action
)
431 DisplayOptions
|= wxNO_CENTURY
;
434 DisplayOptions
&= (~wxNO_CENTURY
);
439 DisplayOptions
|= wxDATE_ABBR
;
442 DisplayOptions
&= (~wxDATE_ABBR
);
451 ///////////////////////////////////////////////////////////////
452 // Miscellaneous Routines
453 ///////////////////////////////////////////////////////////////
455 long wxDate::GetJulianDate( void ) const
460 int wxDate::GetDayOfYear( void ) const
462 wxDate
temp( 1, 1, year
);
464 return (int) (julian
- temp
.julian
+ 1);
468 bool wxDate::IsLeapYear( void ) const
470 return ( (year
>= 1582) ?
471 (year
% 4 == 0 && year
% 100 != 0 || year
% 400 == 0 ):
475 // Version 4.0 Extension to Public Interface - CDP
477 wxDate
& wxDate::Set()
481 struct _dosdate_t sDate
;
482 _dos_getdate(&sDate
);
490 time_t now
= time((time_t *) NULL
);
491 struct tm
*localTime
= localtime(&now
);
493 month
= localTime
->tm_mon
+ 1;
494 day
= localTime
->tm_mday
;
495 year
= localTime
->tm_year
+ 1900;
508 year
= nYear
< 0 ? 9999 : nYear
;
509 year
= nYear
> 9999 ? 0 : nYear
;
510 day
= nDay
< GetDaysInMonth() ? nDay
: GetDaysInMonth();
526 int wxDate::GetDaysInMonth()
528 return GauDays
[month
-1] + (month
==2 && IsLeapYear());
531 int wxDate::GetFirstDayOfMonth() const
533 return wxDate(month
, 1, year
).GetDayOfWeek();
536 int wxDate::GetDay() const
541 int wxDate::GetDayOfWeek() const
546 int wxDate::GetYear() const
551 int wxDate::GetMonth() const
556 wxDate
& wxDate::AddWeeks(int nCount
)
558 Set(julian
+ (long)nCount
*7);
562 wxDate
& wxDate::AddMonths(int nCount
)
579 wxDate
& wxDate::AddYears(int nCount
)
586 int wxDate::GetWeekOfMonth()
588 // Abs day includes the days from previous month that fills up
589 // the begin. of the week.
590 int nAbsDay
= day
+ GetFirstDayOfMonth()-1;
591 return (nAbsDay
-GetDayOfWeek())/7 + 1;
594 int wxDate::GetWeekOfYear()
596 wxDate
doTemp(1, 1, year
);
597 return (int)(((julian
- doTemp
.julian
+1)/7) + 1);
600 wxDate
wxDate::GetMonthStart()
602 return(wxDate(month
, 1, year
));
605 wxDate
wxDate::GetMonthEnd()
607 return(wxDate(month
+1, 1, year
)-1);
610 wxDate
wxDate::GetYearStart()
612 return(wxDate(1, 1, year
));
615 wxDate
wxDate::GetYearEnd()
617 return(wxDate(1, 1, year
+1)-1);
620 wxString
wxDate::GetMonthName()
622 return(FormatDate(wxMONTH
));
625 wxString
wxDate::GetDayOfWeekName()
627 return(FormatDate(wxDAY
));
630 bool wxDate::IsBetween(const wxDate
& first
, const wxDate
& second
) const
632 return (julian
>= first
.julian
&& julian
<= second
.julian
);
635 // This function is from NIHCL
636 wxDate
wxDate::Previous(int dayOfWeek
) const
638 int this_day_Of_Week
, desired_day_Of_Week
;
641 // Set the desired and current day of week to start at 0 (Monday)
642 // and end at 6 (Sunday).
644 desired_day_Of_Week
= dayOfWeek
- 1; // These functions return a value
645 this_day_Of_Week
= GetDayOfWeek() - 1; // from 1-7. Subtract 1 for 0-6.
648 // Have to determine how many days difference from current day back to
649 // desired, if any. Special calculation under the 'if' statement to
650 // effect the wraparound counting from Monday (0) back to Sunday (6).
652 if (desired_day_Of_Week
> this_day_Of_Week
)
653 this_day_Of_Week
+= 7 - desired_day_Of_Week
;
655 this_day_Of_Week
-= desired_day_Of_Week
;
656 j
-= this_day_Of_Week
; // Adjust j to set it at the desired day of week.