]>
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"
50 static const char *dayname
[] = {"Sunday","Monday","Tuesday","Wednesday",
51 "Thursday","Friday","Saturday"} ;
53 static const char *mname
[] = {"January","February","March","April","May",
54 "June","July","August","September","October","November","December"};
56 static int GauDays
[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
58 #if !USE_SHARED_LIBRARY
59 IMPLEMENT_DYNAMIC_CLASS(wxDate
, wxObject
)
62 ////////////////////////////////////////////////////////////
64 ////////////////////////////////////////////////////////////
70 month
= day
= year
= day_of_week
= 0;
74 wxDate::wxDate (long j
) : julian(j
)
81 wxDate::wxDate (int m
, int d
, int y
) : month(m
), day(d
), year(y
)
88 wxDate::wxDate (const wxString
& dat
)
92 if (strcmp(dat
, "TODAY") == 0 || strcmp(dat
, "today") == 0)
94 // Sets the current date
100 strcpy(buf
, (char *) (const char *)dat
);
102 char *token
= strtok(buf
,"/-");
104 day
= atoi(strtok(NULL
,"/-"));
105 year
= atoi(strtok(NULL
," "));
111 wxDate::wxDate (const wxDate
&dt
)
113 DisplayFormat
=dt
.DisplayFormat
;
114 DisplayOptions
=dt
.DisplayOptions
;
121 void wxDate::operator = (const wxDate
&dt
)
123 DisplayFormat
=dt
.DisplayFormat
;
124 DisplayOptions
=dt
.DisplayOptions
;
131 void wxDate::operator = (const wxString
& dat
)
135 if (strcmp(dat
, "TODAY") == 0 || strcmp(dat
, "today") == 0)
137 // Sets the current date
143 strcpy(buf
, (char *)(const char *)dat
);
145 char *token
= strtok(buf
,"/-");
147 day
= atoi(strtok(NULL
,"/-"));
148 year
= atoi(strtok(NULL
," "));
154 //////////////////////////////////////////////////////////////
155 // Conversion operations
156 //////////////////////////////////////////////////////////////
158 wxDate::operator wxString( void )
163 //////////////////////////////////////////////////////////////
165 //////////////////////////////////////////////////////////////
167 wxDate
wxDate::operator + (long i
)
169 wxDate
dp(julian
+ i
);
173 wxDate
wxDate::operator + (int i
)
175 wxDate
dp(julian
+ (long)i
);
179 wxDate
wxDate::operator - (long i
)
181 wxDate
dp(julian
- i
);
185 wxDate
wxDate::operator - (int i
)
187 wxDate
dp(julian
- (long)i
);
191 long wxDate::operator - (const wxDate
&dt
)
193 return ( julian
- dt
.julian
);
196 wxDate
&wxDate::operator += (long i
)
203 wxDate
&wxDate::operator -= (long i
)
210 wxDate
&wxDate::operator ++()
217 wxDate
&wxDate::operator ++(int)
224 wxDate
&wxDate::operator --()
231 wxDate
&wxDate::operator --(int)
238 //////////////////////////////////////////////////////////////
240 //////////////////////////////////////////////////////////////
242 bool operator < (const wxDate
&dt1
, const wxDate
&dt2
)
244 return ( dt1
.julian
< dt2
.julian
);
247 bool operator <= (const wxDate
&dt1
, const wxDate
&dt2
)
249 return ( (dt1
.julian
== dt2
.julian
) || (dt1
.julian
< dt2
.julian
) );
252 bool operator > (const wxDate
&dt1
, const wxDate
&dt2
)
254 return ( dt1
.julian
> dt2
.julian
);
257 bool operator >= (const wxDate
&dt1
, const wxDate
&dt2
)
259 return ( (dt1
.julian
== dt2
.julian
) || (dt1
.julian
> dt2
.julian
) );
262 bool operator == (const wxDate
&dt1
, const wxDate
&dt2
)
264 return ( dt1
.julian
== dt2
.julian
);
267 bool operator != (const wxDate
&dt1
, const wxDate
&dt2
)
269 return ( dt1
.julian
!= dt2
.julian
);
272 ////////////////////////////////////////////////////////////////
273 // Ostream operations
274 ////////////////////////////////////////////////////////////////
276 ostream
&operator << (ostream
&os
, const wxDate
&dt
)
278 return os
<< (const char *) dt
.FormatDate();
281 //////////////////////////////////////////////////////////////
282 // Conversion routines
283 //////////////////////////////////////////////////////////////
285 void wxDate::julian_to_wday (void)
287 day_of_week
= (int) ((julian
+ 2) % 7 + 1);
290 void wxDate::julian_to_mdy ()
292 long a
,b
,c
,d
,e
,z
,alpha
;
294 // dealing with Gregorian calendar reform
298 alpha
= (long) ((z
-1867216.25) / 36524.25);
299 a
= z
+ 1 + alpha
- alpha
/4;
301 b
= ( a
> 1721423 ? a
+ 1524 : a
+ 1158 );
302 c
= (long) ((b
- 122.1) / 365.25);
303 d
= (long) (365.25 * c
);
304 e
= (long) ((b
- d
) / 30.6001);
305 day
= (int)(b
- d
- (long)(30.6001 * e
));
306 month
= (int)((e
< 13.5) ? e
- 1 : e
- 13);
307 year
= (int)((month
> 2.5 ) ? (c
- 4716) : c
- 4715);
311 void wxDate::mdy_to_julian (void)
314 int work_month
=month
, work_day
=day
, work_year
=year
;
315 // correct for negative year
319 { work_year
--; work_month
+=12; }
321 // deal with Gregorian calendar
322 if (work_year
*10000. + work_month
*100. + work_day
>= 15821015.)
324 a
= (int)(work_year
/100.);
327 julian
= (long) (365.25*work_year
) +
328 (long) (30.6001 * (work_month
+1)) + work_day
+ 1720994L + b
;
332 ////////////////////////////////////////////////////////////////
334 ////////////////////////////////////////////////////////////////
336 wxString
wxDate::FormatDate (int type
) const
338 int actualType
= type
;
339 if (actualType
== -1)
340 actualType
= DisplayFormat
;
344 memset( buf
, '\0', sizeof(buf
) );
345 switch ( actualType
)
348 if ( (day_of_week
< 1) || (day_of_week
> 7) )
349 strcpy(buf
,"invalid day");
351 strncpy( buf
, dayname
[day_of_week
-1],
352 (DisplayOptions
& wxDATE_ABBR
) ? ABBR_LENGTH
: 9);
353 return wxString(buf
);
356 if ( (month
< 1) || (month
> 12) )
357 strcpy(buf
,"invalid month");
359 strncpy( buf
, mname
[month
-1],
360 (DisplayOptions
& wxDATE_ABBR
) ? ABBR_LENGTH
: 9);
361 return wxString(buf
);
364 if ( (month
< 1) || (month
> 12) || (day_of_week
< 0) ||
367 strcpy(buf
,"invalid date");
368 return wxString(buf
);
370 strncpy( buf
, dayname
[day_of_week
-1],
371 (DisplayOptions
& wxDATE_ABBR
) ? ABBR_LENGTH
: 9);
373 strncat( buf
, mname
[month
-1],
374 (DisplayOptions
& wxDATE_ABBR
) ? ABBR_LENGTH
: 9);
376 sprintf( buf
+strlen(buf
), "%d, %d", day
, abs(year
) );
379 return wxString(buf
);
382 if ( (month
< 1) || (month
> 12) || (day_of_week
< 0) ||
385 strcpy(buf
,"invalid date");
386 return wxString(buf
);
388 sprintf(buf
,"%d ", day
);
389 strncat(buf
, mname
[month
-1],
390 (DisplayOptions
& wxDATE_ABBR
) ? ABBR_LENGTH
: 9);
391 sprintf( buf
+strlen(buf
), " %d", abs(year
) );
394 return wxString(buf
);
398 if (day
==0 || month
==0 || year
==0)
399 strcpy(buf
,"invalid date");
401 sprintf( buf
+strlen(buf
), "%1d/%1d/%02d", month
, day
,
402 (DisplayOptions
& wxNO_CENTURY
) && (abs(year
) > 1899)
403 ? (abs(year
) - (abs(year
) / 100 * 100))
405 return wxString(buf
);
410 void wxDate::SetFormat( int format
)
412 DisplayFormat
= format
;
415 int wxDate::SetOption( int option
, bool action
)
421 DisplayOptions
|= wxNO_CENTURY
;
424 DisplayOptions
&= (~wxNO_CENTURY
);
429 DisplayOptions
|= wxDATE_ABBR
;
432 DisplayOptions
&= (~wxDATE_ABBR
);
441 ///////////////////////////////////////////////////////////////
442 // Miscellaneous Routines
443 ///////////////////////////////////////////////////////////////
445 long wxDate::GetJulianDate( void ) const
450 int wxDate::GetDayOfYear( void ) const
452 wxDate
temp( 1, 1, year
);
454 return (int) (julian
- temp
.julian
+ 1);
458 bool wxDate::IsLeapYear( void ) const
460 return ( (year
>= 1582) ?
461 (year
% 4 == 0 && year
% 100 != 0 || year
% 400 == 0 ):
465 // Version 4.0 Extension to Public Interface - CDP
467 wxDate
& wxDate::Set()
471 struct _dosdate_t sDate
;
472 _dos_getdate(&sDate
);
480 time_t now
= time(NULL
);
481 struct tm
*localTime
= localtime(&now
);
483 month
= localTime
->tm_mon
+ 1;
484 day
= localTime
->tm_mday
;
485 year
= localTime
->tm_year
+ 1900;
498 year
= nYear
< 0 ? 9999 : nYear
;
499 year
= nYear
> 9999 ? 0 : nYear
;
500 day
= nDay
< GetDaysInMonth() ? nDay
: GetDaysInMonth();
516 int wxDate::GetDaysInMonth()
518 return GauDays
[month
-1] + (month
==2 && IsLeapYear());
521 int wxDate::GetFirstDayOfMonth() const
523 return wxDate(month
, 1, year
).GetDayOfWeek();
526 int wxDate::GetDay() const
531 int wxDate::GetDayOfWeek() const
536 int wxDate::GetYear() const
541 int wxDate::GetMonth() const
546 wxDate
& wxDate::AddWeeks(int nCount
)
548 Set(julian
+ (long)nCount
*7);
552 wxDate
& wxDate::AddMonths(int nCount
)
569 wxDate
& wxDate::AddYears(int nCount
)
576 int wxDate::GetWeekOfMonth()
578 // Abs day includes the days from previous month that fills up
579 // the begin. of the week.
580 int nAbsDay
= day
+ GetFirstDayOfMonth()-1;
581 return (nAbsDay
-GetDayOfWeek())/7 + 1;
584 int wxDate::GetWeekOfYear()
586 wxDate
doTemp(1, 1, year
);
587 return (int)(((julian
- doTemp
.julian
+1)/7) + 1);
590 wxDate
wxDate::GetMonthStart()
592 return(wxDate(month
, 1, year
));
595 wxDate
wxDate::GetMonthEnd()
597 return(wxDate(month
+1, 1, year
)-1);
600 wxDate
wxDate::GetYearStart()
602 return(wxDate(1, 1, year
));
605 wxDate
wxDate::GetYearEnd()
607 return(wxDate(1, 1, year
+1)-1);
610 wxString
wxDate::GetMonthName()
612 return(FormatDate(wxMONTH
));
615 wxString
wxDate::GetDayOfWeekName()
617 return(FormatDate(wxDAY
));
620 bool wxDate::IsBetween(const wxDate
& first
, const wxDate
& second
) const
622 return (julian
>= first
.julian
&& julian
<= second
.julian
);
625 // This function is from NIHCL
626 wxDate
wxDate::Previous(int dayOfWeek
) const
628 int this_day_Of_Week
, desired_day_Of_Week
;
631 // Set the desired and current day of week to start at 0 (Monday)
632 // and end at 6 (Sunday).
634 desired_day_Of_Week
= dayOfWeek
- 1; // These functions return a value
635 this_day_Of_Week
= GetDayOfWeek() - 1; // from 1-7. Subtract 1 for 0-6.
638 // Have to determine how many days difference from current day back to
639 // desired, if any. Special calculation under the 'if' statement to
640 // effect the wraparound counting from Monday (0) back to Sunday (6).
642 if (desired_day_Of_Week
> this_day_Of_Week
)
643 this_day_Of_Week
+= 7 - desired_day_Of_Week
;
645 this_day_Of_Week
-= desired_day_Of_Week
;
646 j
-= this_day_Of_Week
; // Adjust j to set it at the desired day of week.