]>
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"
51 static const char *dayname
[] = {
52 "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
55 static const char *mname
[] = {
56 "January", "February", "March", "April", "May", "June", "July", "August",
57 "September", "October", "November", "December"
60 static int GauDays
[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
62 #if !USE_SHARED_LIBRARY
63 IMPLEMENT_DYNAMIC_CLASS(wxDate
, wxObject
)
66 ////////////////////////////////////////////////////////////
68 ////////////////////////////////////////////////////////////
74 month
= day
= year
= day_of_week
= 0;
78 wxDate::wxDate (long j
) : julian(j
)
85 wxDate::wxDate (int m
, int d
, int y
) : month(m
), day(d
), year(y
)
92 wxDate::wxDate (const wxString
& dat
)
96 if (strcmp(dat
, "TODAY") == 0 || strcmp(dat
, "today") == 0)
98 // Sets the current date
104 strcpy(buf
, (char *) (const char *)dat
);
106 char *token
= strtok(buf
,"/-");
108 day
= atoi(strtok((char *) NULL
,"/-"));
109 year
= atoi(strtok((char *) NULL
," "));
115 wxDate::wxDate (const wxDate
&dt
)
117 DisplayFormat
=dt
.DisplayFormat
;
118 DisplayOptions
=dt
.DisplayOptions
;
125 void wxDate::operator = (const wxDate
&dt
)
127 DisplayFormat
=dt
.DisplayFormat
;
128 DisplayOptions
=dt
.DisplayOptions
;
135 void wxDate::operator = (const wxString
& dat
)
139 if (strcmp(dat
, "TODAY") == 0 || strcmp(dat
, "today") == 0)
141 // Sets the current date
147 strcpy(buf
, (char *)(const char *)dat
);
149 char *token
= strtok(buf
,"/-");
151 day
= atoi(strtok((char *) NULL
,"/-"));
152 year
= atoi(strtok((char *) NULL
," "));
158 //////////////////////////////////////////////////////////////
159 // Conversion operations
160 //////////////////////////////////////////////////////////////
162 wxDate::operator wxString( void )
167 //////////////////////////////////////////////////////////////
169 //////////////////////////////////////////////////////////////
171 wxDate
wxDate::operator + (long i
)
173 wxDate
dp(julian
+ i
);
177 wxDate
wxDate::operator + (int i
)
179 wxDate
dp(julian
+ (long)i
);
183 wxDate
wxDate::operator - (long i
)
185 wxDate
dp(julian
- i
);
189 wxDate
wxDate::operator - (int i
)
191 wxDate
dp(julian
- (long)i
);
195 long wxDate::operator - (const wxDate
&dt
)
197 return ( julian
- dt
.julian
);
200 wxDate
&wxDate::operator += (long i
)
207 wxDate
&wxDate::operator -= (long i
)
214 wxDate
&wxDate::operator ++()
221 wxDate
&wxDate::operator ++(int)
228 wxDate
&wxDate::operator --()
235 wxDate
&wxDate::operator --(int)
242 //////////////////////////////////////////////////////////////
244 //////////////////////////////////////////////////////////////
246 bool operator < (const wxDate
&dt1
, const wxDate
&dt2
)
248 return ( dt1
.julian
< dt2
.julian
);
251 bool operator <= (const wxDate
&dt1
, const wxDate
&dt2
)
253 return ( (dt1
.julian
== dt2
.julian
) || (dt1
.julian
< dt2
.julian
) );
256 bool operator > (const wxDate
&dt1
, const wxDate
&dt2
)
258 return ( dt1
.julian
> dt2
.julian
);
261 bool operator >= (const wxDate
&dt1
, const wxDate
&dt2
)
263 return ( (dt1
.julian
== dt2
.julian
) || (dt1
.julian
> dt2
.julian
) );
266 bool operator == (const wxDate
&dt1
, const wxDate
&dt2
)
268 return ( dt1
.julian
== dt2
.julian
);
271 bool operator != (const wxDate
&dt1
, const wxDate
&dt2
)
273 return ( dt1
.julian
!= dt2
.julian
);
276 ////////////////////////////////////////////////////////////////
277 // Ostream operations
278 ////////////////////////////////////////////////////////////////
280 ostream
&operator << (ostream
&os
, const wxDate
&dt
)
282 return os
<< (const char *) dt
.FormatDate();
285 //////////////////////////////////////////////////////////////
286 // Conversion routines
287 //////////////////////////////////////////////////////////////
289 void wxDate::julian_to_wday (void)
291 day_of_week
= (int) ((julian
+ 2) % 7 + 1);
294 void wxDate::julian_to_mdy ()
296 long a
,b
,c
,d
,e
,z
,alpha
;
298 // dealing with Gregorian calendar reform
302 alpha
= (long) ((z
-1867216.25) / 36524.25);
303 a
= z
+ 1 + alpha
- alpha
/4;
305 b
= ( a
> 1721423 ? a
+ 1524 : a
+ 1158 );
306 c
= (long) ((b
- 122.1) / 365.25);
307 d
= (long) (365.25 * c
);
308 e
= (long) ((b
- d
) / 30.6001);
309 day
= (int)(b
- d
- (long)(30.6001 * e
));
310 month
= (int)((e
< 13.5) ? e
- 1 : e
- 13);
311 year
= (int)((month
> 2.5 ) ? (c
- 4716) : c
- 4715);
315 void wxDate::mdy_to_julian (void)
318 int work_month
=month
, work_day
=day
, work_year
=year
;
319 // correct for negative year
323 { work_year
--; work_month
+=12; }
325 // deal with Gregorian calendar
326 if (work_year
*10000. + work_month
*100. + work_day
>= 15821015.)
328 a
= (int)(work_year
/100.);
331 julian
= (long) (365.25*work_year
) +
332 (long) (30.6001 * (work_month
+1)) + work_day
+ 1720994L + b
;
336 ////////////////////////////////////////////////////////////////
338 ////////////////////////////////////////////////////////////////
340 wxString
wxDate::FormatDate (int type
) const
342 int actualType
= type
;
343 if (actualType
== -1)
344 actualType
= DisplayFormat
;
348 memset( buf
, '\0', sizeof(buf
) );
349 switch ( actualType
)
352 if ( (day_of_week
< 1) || (day_of_week
> 7) )
353 strcpy(buf
, _("invalid day"));
355 strncpy( buf
, _(dayname
[day_of_week
-1]),
356 (DisplayOptions
& wxDATE_ABBR
) ? ABBR_LENGTH
: 9);
357 return wxString(buf
);
360 if ( (month
< 1) || (month
> 12) )
361 strcpy(buf
, _("invalid month"));
363 strncpy( buf
, _(mname
[month
-1]),
364 (DisplayOptions
& wxDATE_ABBR
) ? ABBR_LENGTH
: 9);
365 return wxString(buf
);
368 if ( (month
< 1) || (month
> 12) || (day_of_week
< 0) ||
371 strcpy(buf
, _("invalid date"));
372 return wxString(buf
);
374 strncpy( buf
, _(dayname
[day_of_week
-1]),
375 (DisplayOptions
& wxDATE_ABBR
) ? ABBR_LENGTH
: 9);
377 strncat( buf
, _(mname
[month
-1]),
378 (DisplayOptions
& wxDATE_ABBR
) ? ABBR_LENGTH
: 9);
380 sprintf( buf
+strlen(buf
), "%d, %d", day
, abs(year
) );
382 strcat(buf
,_(" B.C."));
383 return wxString(buf
);
386 if ( (month
< 1) || (month
> 12) || (day_of_week
< 0) ||
389 strcpy(buf
, _("invalid date"));
390 return wxString(buf
);
392 sprintf(buf
,"%d ", day
);
393 strncat(buf
, _(mname
[month
-1]),
394 (DisplayOptions
& wxDATE_ABBR
) ? ABBR_LENGTH
: 9);
395 sprintf( buf
+strlen(buf
), " %d", abs(year
) );
397 strcat(buf
, _(" B.C."));
398 return wxString(buf
);
402 if (day
==0 || month
==0 || year
==0)
403 strcpy(buf
, _("invalid date"));
405 sprintf( buf
+strlen(buf
), "%1d/%1d/%02d", month
, day
,
406 (DisplayOptions
& wxNO_CENTURY
) && (abs(year
) > 1899)
407 ? (abs(year
) - (abs(year
) / 100 * 100))
409 return wxString(buf
);
414 void wxDate::SetFormat( int format
)
416 DisplayFormat
= format
;
419 int wxDate::SetOption( int option
, bool action
)
425 DisplayOptions
|= wxNO_CENTURY
;
428 DisplayOptions
&= (~wxNO_CENTURY
);
433 DisplayOptions
|= wxDATE_ABBR
;
436 DisplayOptions
&= (~wxDATE_ABBR
);
445 ///////////////////////////////////////////////////////////////
446 // Miscellaneous Routines
447 ///////////////////////////////////////////////////////////////
449 long wxDate::GetJulianDate( void ) const
454 int wxDate::GetDayOfYear( void ) const
456 wxDate
temp( 1, 1, year
);
458 return (int) (julian
- temp
.julian
+ 1);
462 bool wxDate::IsLeapYear( void ) const
464 return ( (year
>= 1582) ?
465 (year
% 4 == 0 && year
% 100 != 0 || year
% 400 == 0 ):
469 // Version 4.0 Extension to Public Interface - CDP
471 wxDate
& wxDate::Set()
475 struct _dosdate_t sDate
;
476 _dos_getdate(&sDate
);
484 time_t now
= time((time_t *) NULL
);
485 struct tm
*localTime
= localtime(&now
);
487 month
= localTime
->tm_mon
+ 1;
488 day
= localTime
->tm_mday
;
489 year
= localTime
->tm_year
+ 1900;
502 year
= nYear
< 0 ? 9999 : nYear
;
503 year
= nYear
> 9999 ? 0 : nYear
;
504 day
= nDay
< GetDaysInMonth() ? nDay
: GetDaysInMonth();
520 int wxDate::GetDaysInMonth()
522 return GauDays
[month
-1] + (month
==2 && IsLeapYear());
525 int wxDate::GetFirstDayOfMonth() const
527 return wxDate(month
, 1, year
).GetDayOfWeek();
530 int wxDate::GetDay() const
535 int wxDate::GetDayOfWeek() const
540 int wxDate::GetYear() const
545 int wxDate::GetMonth() const
550 wxDate
& wxDate::AddWeeks(int nCount
)
552 Set(julian
+ (long)nCount
*7);
556 wxDate
& wxDate::AddMonths(int nCount
)
573 wxDate
& wxDate::AddYears(int nCount
)
580 int wxDate::GetWeekOfMonth()
582 // Abs day includes the days from previous month that fills up
583 // the begin. of the week.
584 int nAbsDay
= day
+ GetFirstDayOfMonth()-1;
585 return (nAbsDay
-GetDayOfWeek())/7 + 1;
588 int wxDate::GetWeekOfYear()
590 wxDate
doTemp(1, 1, year
);
591 return (int)(((julian
- doTemp
.julian
+1)/7) + 1);
594 wxDate
wxDate::GetMonthStart()
596 return(wxDate(month
, 1, year
));
599 wxDate
wxDate::GetMonthEnd()
601 return(wxDate(month
+1, 1, year
)-1);
604 wxDate
wxDate::GetYearStart()
606 return(wxDate(1, 1, year
));
609 wxDate
wxDate::GetYearEnd()
611 return(wxDate(1, 1, year
+1)-1);
614 wxString
wxDate::GetMonthName()
616 return(FormatDate(wxMONTH
));
619 wxString
wxDate::GetDayOfWeekName()
621 return(FormatDate(wxDAY
));
624 bool wxDate::IsBetween(const wxDate
& first
, const wxDate
& second
) const
626 return (julian
>= first
.julian
&& julian
<= second
.julian
);
629 // This function is from NIHCL
630 wxDate
wxDate::Previous(int dayOfWeek
) const
632 int this_day_Of_Week
, desired_day_Of_Week
;
635 // Set the desired and current day of week to start at 0 (Monday)
636 // and end at 6 (Sunday).
638 desired_day_Of_Week
= dayOfWeek
- 1; // These functions return a value
639 this_day_Of_Week
= GetDayOfWeek() - 1; // from 1-7. Subtract 1 for 0-6.
642 // Have to determine how many days difference from current day back to
643 // desired, if any. Special calculation under the 'if' statement to
644 // effect the wraparound counting from Monday (0) back to Sunday (6).
646 if (desired_day_Of_Week
> this_day_Of_Week
)
647 this_day_Of_Week
+= 7 - desired_day_Of_Week
;
649 this_day_Of_Week
-= desired_day_Of_Week
;
650 j
-= this_day_Of_Week
; // Adjust j to set it at the desired day of week.