]>
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"
49 static const wxChar
*dayname
[] = {
50 _T("Sunday"), _T("Monday"), _T("Tuesday"), _T("Wednesday"),
51 _T("Thursday"), _T("Friday"), _T("Saturday")
54 static const wxChar
*mname
[] = {
55 _T("January"), _T("February"), _T("March"), _T("April"), _T("May"), _T("June"),
56 _T("July"), _T("August"), _T("September"), _T("October"), _T("November"), _T("December")
59 static int GauDays
[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
61 #if !USE_SHARED_LIBRARY
62 IMPLEMENT_DYNAMIC_CLASS(wxDate
, wxObject
)
65 ////////////////////////////////////////////////////////////
67 ////////////////////////////////////////////////////////////
73 month
= day
= year
= day_of_week
= 0;
77 wxDate::wxDate (long j
) : julian(j
)
84 wxDate::wxDate (int m
, int d
, int y
) : month(m
), day(d
), year(y
)
91 wxDate::wxDate (const wxString
& dat
)
95 if (wxStrcmp(dat
, _T("TODAY")) == 0 || wxStrcmp(dat
, _T("today")) == 0)
97 // Sets the current date
103 wxStrcpy(buf
, WXSTRINGCAST dat
);
105 wxChar
*save_ptr
, *token
= wxStrtok(buf
,_T("/-"),&save_ptr
);
106 month
= wxAtoi(token
);
107 day
= wxAtoi(wxStrtok((wxChar
*) NULL
,_T("/-"),&save_ptr
));
108 year
= wxAtoi(wxStrtok((wxChar
*) NULL
,_T(" "),&save_ptr
));
114 wxDate::wxDate (const wxDate
&dt
)
116 DisplayFormat
=dt
.DisplayFormat
;
117 DisplayOptions
=dt
.DisplayOptions
;
124 void wxDate::operator = (const wxDate
&dt
)
126 DisplayFormat
=dt
.DisplayFormat
;
127 DisplayOptions
=dt
.DisplayOptions
;
131 mdy_to_julian (); // wxUSE_TIMEDATE
134 void wxDate::operator = (const wxString
& dat
)
138 if (wxStrcmp(dat
, _T("TODAY")) == 0 || wxStrcmp(dat
, _T("today")) == 0)
140 // Sets the current date
146 wxStrcpy(buf
, WXSTRINGCAST dat
);
148 wxChar
*save_ptr
, *token
= wxStrtok(buf
,_T("/-"),&save_ptr
);
149 month
= wxAtoi(token
);
150 day
= wxAtoi(wxStrtok((wxChar
*) NULL
,_T("/-"),&save_ptr
));
151 year
= wxAtoi(wxStrtok((wxChar
*) NULL
,_T(" "),&save_ptr
));
157 //////////////////////////////////////////////////////////////
158 // Conversion operations
159 //////////////////////////////////////////////////////////////
162 wxDate::operator wxString( void )
168 //////////////////////////////////////////////////////////////
170 //////////////////////////////////////////////////////////////
172 wxDate
wxDate::operator + (long i
)
174 wxDate
dp(julian
+ i
);
178 wxDate
wxDate::operator + (int i
)
180 wxDate
dp(julian
+ (long)i
);
184 wxDate
wxDate::operator - (long i
)
186 wxDate
dp(julian
- i
);
190 wxDate
wxDate::operator - (int i
)
192 wxDate
dp(julian
- (long)i
);
196 long wxDate::operator - (const wxDate
&dt
)
198 return ( julian
- dt
.julian
);
201 wxDate
&wxDate::operator += (long i
)
208 wxDate
&wxDate::operator -= (long i
)
215 wxDate
&wxDate::operator ++()
222 wxDate
&wxDate::operator ++(int)
229 wxDate
&wxDate::operator --()
236 wxDate
&wxDate::operator --(int)
243 //////////////////////////////////////////////////////////////
245 //////////////////////////////////////////////////////////////
247 bool WXDLLEXPORT
operator < (const wxDate
&dt1
, const wxDate
&dt2
)
249 return ( dt1
.julian
< dt2
.julian
);
252 bool WXDLLEXPORT
operator <= (const wxDate
&dt1
, const wxDate
&dt2
)
254 return ( (dt1
.julian
== dt2
.julian
) || (dt1
.julian
< dt2
.julian
) );
257 bool WXDLLEXPORT
operator > (const wxDate
&dt1
, const wxDate
&dt2
)
259 return ( dt1
.julian
> dt2
.julian
);
262 bool WXDLLEXPORT
operator >= (const wxDate
&dt1
, const wxDate
&dt2
)
264 return ( (dt1
.julian
== dt2
.julian
) || (dt1
.julian
> dt2
.julian
) );
267 bool WXDLLEXPORT
operator == (const wxDate
&dt1
, const wxDate
&dt2
)
269 return ( dt1
.julian
== dt2
.julian
);
272 bool WXDLLEXPORT
operator != (const wxDate
&dt1
, const wxDate
&dt2
)
274 return ( dt1
.julian
!= dt2
.julian
);
277 ////////////////////////////////////////////////////////////////
278 // Ostream operations
279 ////////////////////////////////////////////////////////////////
281 ostream WXDLLEXPORT
& operator << (ostream
&os
, const wxDate
&dt
)
283 return os
<< dt
.FormatDate().mb_str();
286 //////////////////////////////////////////////////////////////
287 // Conversion routines
288 //////////////////////////////////////////////////////////////
290 void wxDate::julian_to_wday (void)
292 // Correction by Peter Stadel <peters@jetcity.com>
293 day_of_week
= ((julian
- 2) % 7L);
295 day_of_week = (int) ((julian + 2) % 7 + 1);
299 void wxDate::julian_to_mdy ()
301 long a
,b
,c
,d
,e
,z
,alpha
;
303 // dealing with Gregorian calendar reform
307 alpha
= (long) ((z
-1867216.25) / 36524.25);
308 a
= z
+ 1 + alpha
- alpha
/4;
310 b
= ( a
> 1721423 ? a
+ 1524 : a
+ 1158 );
311 c
= (long) ((b
- 122.1) / 365.25);
312 d
= (long) (365.25 * c
);
313 e
= (long) ((b
- d
) / 30.6001);
314 day
= (int)(b
- d
- (long)(30.6001 * e
));
315 month
= (int)((e
< 13.5) ? e
- 1 : e
- 13);
316 year
= (int)((month
> 2.5 ) ? (c
- 4716) : c
- 4715);
320 void wxDate::mdy_to_julian (void)
323 int work_month
=month
, work_day
=day
, work_year
=year
;
324 // correct for negative year
328 { work_year
--; work_month
+=12; }
330 // deal with Gregorian calendar
331 if (work_year
*10000. + work_month
*100. + work_day
>= 15821015.)
333 a
= (int)(work_year
/100.);
336 julian
= (long) (365.25*work_year
) +
337 (long) (30.6001 * (work_month
+1)) + work_day
+ 1720994L + b
;
341 ////////////////////////////////////////////////////////////////
343 ////////////////////////////////////////////////////////////////
345 wxString
wxDate::FormatDate (int type
) const
347 int actualType
= type
;
348 if (actualType
== -1)
349 actualType
= DisplayFormat
;
353 memset( buf
, '\0', sizeof(buf
) );
354 switch ( actualType
)
357 if ( (day_of_week
< 1) || (day_of_week
> 7) )
358 wxStrcpy(buf
, _("invalid day"));
360 wxStrncpy( buf
, wxGetTranslation(dayname
[day_of_week
-1]),
361 (DisplayOptions
& wxDATE_ABBR
) ? ABBR_LENGTH
: 9);
362 return wxString(buf
);
365 if ( (month
< 1) || (month
> 12) )
366 wxStrcpy(buf
, _("invalid month"));
368 wxStrncpy( buf
, wxGetTranslation(mname
[month
-1]),
369 (DisplayOptions
& wxDATE_ABBR
) ? ABBR_LENGTH
: 9);
370 return wxString(buf
);
373 if ( (month
< 1) || (month
> 12) || (day_of_week
< 0) ||
376 wxStrcpy(buf
, _("invalid date"));
377 return wxString(buf
);
379 wxStrncpy( buf
, wxGetTranslation(dayname
[day_of_week
-1]),
380 (DisplayOptions
& wxDATE_ABBR
) ? ABBR_LENGTH
: 9);
381 wxStrcat( buf
, _T(", "));
382 wxStrncat( buf
, wxGetTranslation(mname
[month
-1]),
383 (DisplayOptions
& wxDATE_ABBR
) ? ABBR_LENGTH
: 9);
384 wxStrcat( buf
, _T(" "));
385 wxSprintf( buf
+wxStrlen(buf
), _T("%d, %d"), day
, abs(year
) );
387 wxStrcat(buf
,_(" B.C."));
388 return wxString(buf
);
391 if ( (month
< 1) || (month
> 12) || (day_of_week
< 0) ||
394 wxStrcpy(buf
, _("invalid date"));
395 return wxString(buf
);
397 wxSprintf(buf
,_T("%d "), day
);
398 wxStrncat(buf
, wxGetTranslation(mname
[month
-1]),
399 (DisplayOptions
& wxDATE_ABBR
) ? ABBR_LENGTH
: 9);
400 wxSprintf( buf
+wxStrlen(buf
), _T(" %d"), abs(year
) );
402 wxStrcat(buf
, _(" B.C."));
403 return wxString(buf
);
407 if (day
==0 || month
==0 || year
==0)
408 wxStrcpy(buf
, _("invalid date"));
410 wxSprintf( buf
+wxStrlen(buf
), _T("%1d/%1d/%02d"), month
, day
,
411 (DisplayOptions
& wxNO_CENTURY
) && (abs(year
) > 1899)
412 ? (abs(year
) - (abs(year
) / 100 * 100))
414 return wxString(buf
);
416 return wxString(_T(""));
419 void wxDate::SetFormat( int format
)
421 DisplayFormat
= format
;
424 int wxDate::SetOption( int option
, bool action
)
430 DisplayOptions
|= wxNO_CENTURY
;
433 DisplayOptions
&= (~wxNO_CENTURY
);
438 DisplayOptions
|= wxDATE_ABBR
;
441 DisplayOptions
&= (~wxDATE_ABBR
);
450 ///////////////////////////////////////////////////////////////
451 // Miscellaneous Routines
452 ///////////////////////////////////////////////////////////////
454 long wxDate::GetJulianDate( void ) const
459 int wxDate::GetDayOfYear( void ) const
461 wxDate
temp( 1, 1, year
);
463 return (int) (julian
- temp
.julian
+ 1);
467 bool wxDate::IsLeapYear( void ) const
469 return ( (year
>= 1582) ?
470 (year
% 4 == 0 && year
% 100 != 0 || year
% 400 == 0 ):
474 // Version 4.0 Extension to Public Interface - CDP
476 wxDate
& wxDate::Set()
480 struct _dosdate_t sDate
;
481 _dos_getdate(&sDate
);
489 time_t now
= time((time_t *) NULL
);
490 struct tm
*localTime
= localtime(&now
);
492 month
= localTime
->tm_mon
+ 1;
493 day
= localTime
->tm_mday
;
494 year
= localTime
->tm_year
+ 1900;
507 year
= nYear
< 0 ? 9999 : nYear
;
508 year
= nYear
> 9999 ? 0 : nYear
;
509 day
= nDay
< GetDaysInMonth() ? nDay
: GetDaysInMonth();
525 int wxDate::GetDaysInMonth()
527 return GauDays
[month
-1] + (month
==2 && IsLeapYear());
530 int wxDate::GetFirstDayOfMonth() const
532 return wxDate(month
, 1, year
).GetDayOfWeek();
535 int wxDate::GetDay() const
540 int wxDate::GetDayOfWeek() const
545 int wxDate::GetYear() const
550 int wxDate::GetMonth() const
555 wxDate
& wxDate::AddWeeks(int nCount
)
557 Set(julian
+ (long)nCount
*7);
561 wxDate
& wxDate::AddMonths(int nCount
)
578 wxDate
& wxDate::AddYears(int nCount
)
585 int wxDate::GetWeekOfMonth()
587 // Abs day includes the days from previous month that fills up
588 // the begin. of the week.
589 int nAbsDay
= day
+ GetFirstDayOfMonth()-1;
590 return (nAbsDay
-GetDayOfWeek())/7 + 1;
593 int wxDate::GetWeekOfYear()
595 wxDate
doTemp(1, 1, year
);
596 return (int)(((julian
- doTemp
.julian
+1)/7) + 1);
599 wxDate
wxDate::GetMonthStart()
601 return(wxDate(month
, 1, year
));
604 wxDate
wxDate::GetMonthEnd()
606 return(wxDate(month
+1, 1, year
)-1);
609 wxDate
wxDate::GetYearStart()
611 return(wxDate(1, 1, year
));
614 wxDate
wxDate::GetYearEnd()
616 return(wxDate(1, 1, year
+1)-1);
619 wxString
wxDate::GetMonthName()
621 return(FormatDate(wxMONTH
));
624 wxString
wxDate::GetDayOfWeekName()
626 return(FormatDate(wxDAY
));
629 bool wxDate::IsBetween(const wxDate
& first
, const wxDate
& second
) const
631 return (julian
>= first
.julian
&& julian
<= second
.julian
);
634 // This function is from NIHCL
635 wxDate
wxDate::Previous(int dayOfWeek
) const
637 int this_day_Of_Week
, desired_day_Of_Week
;
640 // Set the desired and current day of week to start at 0 (Monday)
641 // and end at 6 (Sunday).
643 desired_day_Of_Week
= dayOfWeek
- 1; // These functions return a value
644 this_day_Of_Week
= GetDayOfWeek() - 1; // from 1-7. Subtract 1 for 0-6.
647 // Have to determine how many days difference from current day back to
648 // desired, if any. Special calculation under the 'if' statement to
649 // effect the wraparound counting from Monday (0) back to Sunday (6).
651 if (desired_day_Of_Week
> this_day_Of_Week
)
652 this_day_Of_Week
+= 7 - desired_day_Of_Week
;
654 this_day_Of_Week
-= desired_day_Of_Week
;
655 j
-= this_day_Of_Week
; // Adjust j to set it at the desired day of week.