1. wxDateTimeHolidayAuthority class for calculating the holidays added

2. wxCalendarCtrl adjustments and some new features


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@5182 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2000-01-02 23:17:55 +00:00
parent c88275cb7d
commit 4f6aed9c6a
11 changed files with 817 additions and 60 deletions

View File

@@ -67,6 +67,7 @@
#include "wx/string.h"
#include "wx/intl.h"
#include "wx/log.h"
#include "wx/module.h"
#endif // WX_PRECOMP
#include "wx/thread.h"
@@ -99,6 +100,31 @@
#endif
#endif // !WX_TIMEZONE
// ----------------------------------------------------------------------------
// private classes
// ----------------------------------------------------------------------------
class wxDateTimeHolidaysModule : public wxModule
{
public:
virtual bool OnInit()
{
wxDateTimeHolidayAuthority::AddAuthority(new wxDateTimeWorkDays);
return TRUE;
}
virtual void OnExit()
{
wxDateTimeHolidayAuthority::ClearAllAuthorities();
}
private:
DECLARE_DYNAMIC_CLASS(wxDateTimeHolidaysModule)
};
IMPLEMENT_DYNAMIC_CLASS(wxDateTimeHolidaysModule, wxModule)
// ----------------------------------------------------------------------------
// constants
// ----------------------------------------------------------------------------
@@ -160,6 +186,18 @@ wxDateTime::Country wxDateTime::ms_country = wxDateTime::Country_Unknown;
// private functions
// ----------------------------------------------------------------------------
// debugger helper: shows what the date really is
#ifdef __WXDEBUG__
extern const wxChar *wxDumpDate(const wxDateTime* dt)
{
static wxChar buf[20];
wxStrcpy(buf, dt->Format(_T("%Y-%m-%d (%a) %H:%M:%S")));
return buf;
}
#endif // Debug
// get the number of days in the given month of the given year
static inline
wxDateTime::wxDateTime_t GetNumOfDaysInMonth(int year, wxDateTime::Month month)
@@ -437,6 +475,9 @@ void wxDateTime::Tm::AddMonths(int monDiff)
mon = (wxDateTime::Month)(mon + monDiff);
wxASSERT_MSG( mon >= 0 && mon < MONTHS_IN_YEAR, _T("logic error") );
// NB: we don't check here that the resulting date is valid, this function
// is private and the caller must check it if needed
}
void wxDateTime::Tm::AddDays(int dayDiff)
@@ -1358,6 +1399,20 @@ wxDateTime& wxDateTime::Add(const wxDateSpan& diff)
tm.year += diff.GetYears();
tm.AddMonths(diff.GetMonths());
// check that the resulting date is valid
if ( tm.mday > GetNumOfDaysInMonth(tm.year, tm.mon) )
{
// We suppose that when adding one month to Jan 31 we want to get Feb
// 28 (or 29), i.e. adding a month to the last day of the month should
// give the last day of the next month which is quite logical.
//
// Unfortunately, there is no logic way to understand what should
// Jan 30 + 1 month be - Feb 28 too or Feb 27 (assuming non leap year)?
// We make it Feb 28 (last day too), but it is highly questionable.
tm.mday = GetNumOfDaysInMonth(tm.year, tm.mon);
}
tm.AddDays(diff.GetTotalDays());
Set(tm);
@@ -1372,6 +1427,23 @@ wxDateTime& wxDateTime::Add(const wxDateSpan& diff)
// Weekday and monthday stuff
// ----------------------------------------------------------------------------
bool wxDateTime::SetToTheWeek(wxDateTime_t numWeek, WeekDay weekday)
{
int year = GetYear();
// Jan 4 always lies in the 1st week of the year
Set(4, Jan, year);
SetToWeekDayInSameWeek(weekday) += wxDateSpan::Weeks(numWeek);
if ( GetYear() != year )
{
// oops... numWeek was too big
return FALSE;
}
return TRUE;
}
wxDateTime& wxDateTime::SetToLastMonthDay(Month month,
int year)
{
@@ -1396,11 +1468,11 @@ wxDateTime& wxDateTime::SetToWeekDayInSameWeek(WeekDay weekday)
}
else if ( weekday < wdayThis )
{
return Substract(wxTimeSpan::Days(wdayThis - weekday));
return Substract(wxDateSpan::Days(wdayThis - weekday));
}
else // weekday > wdayThis
{
return Add(wxTimeSpan::Days(weekday - wdayThis));
return Add(wxDateSpan::Days(weekday - wdayThis));
}
}
@@ -1425,7 +1497,7 @@ wxDateTime& wxDateTime::SetToNextWeekDay(WeekDay weekday)
diff = weekday - wdayThis;
}
return Add(wxTimeSpan::Days(diff));
return Add(wxDateSpan::Days(diff));
}
wxDateTime& wxDateTime::SetToPrevWeekDay(WeekDay weekday)
@@ -1449,7 +1521,7 @@ wxDateTime& wxDateTime::SetToPrevWeekDay(WeekDay weekday)
diff = wdayThis - weekday;
}
return Substract(wxTimeSpan::Days(diff));
return Substract(wxDateSpan::Days(diff));
}
bool wxDateTime::SetToWeekDay(WeekDay weekday,
@@ -3240,6 +3312,15 @@ const wxChar *wxDateTime::ParseTime(const wxChar *time)
return result;
}
// ----------------------------------------------------------------------------
// Workdays and holidays support
// ----------------------------------------------------------------------------
bool wxDateTime::IsWorkDay(Country WXUNUSED(country)) const
{
return !wxDateTimeHolidayAuthority::IsHoliday(*this);
}
// ============================================================================
// wxTimeSpan
// ============================================================================
@@ -3325,3 +3406,121 @@ wxString wxTimeSpan::Format(const wxChar *format) const
return str;
}
// ============================================================================
// wxDateTimeHolidayAuthority and related classes
// ============================================================================
#include "wx/arrimpl.cpp"
WX_DEFINE_OBJARRAY(wxDateTimeArray)
static int wxCMPFUNC_CONV
wxDateTimeCompareFunc(wxDateTime **first, wxDateTime **second)
{
wxDateTime dt1 = **first,
dt2 = **second;
return dt1 == dt2 ? 0 : dt1 < dt2 ? -1 : +1;
}
// ----------------------------------------------------------------------------
// wxDateTimeHolidayAuthority
// ----------------------------------------------------------------------------
wxHolidayAuthoritiesArray wxDateTimeHolidayAuthority::ms_authorities;
/* static */
bool wxDateTimeHolidayAuthority::IsHoliday(const wxDateTime& dt)
{
size_t count = ms_authorities.GetCount();
for ( size_t n = 0; n < count; n++ )
{
if ( ms_authorities[n]->DoIsHoliday(dt) )
{
return TRUE;
}
}
return FALSE;
}
/* static */
size_t
wxDateTimeHolidayAuthority::GetHolidaysInRange(const wxDateTime& dtStart,
const wxDateTime& dtEnd,
wxDateTimeArray& holidays)
{
wxDateTimeArray hol;
holidays.Empty();
size_t count = ms_authorities.GetCount();
for ( size_t n = 0; n < count; n++ )
{
ms_authorities[n]->DoGetHolidaysInRange(dtStart, dtEnd, hol);
WX_APPEND_ARRAY(holidays, hol);
}
holidays.Sort(wxDateTimeCompareFunc);
return holidays.GetCount();
}
/* static */
void wxDateTimeHolidayAuthority::ClearAllAuthorities()
{
WX_CLEAR_ARRAY(ms_authorities);
}
/* static */
void wxDateTimeHolidayAuthority::AddAuthority(wxDateTimeHolidayAuthority *auth)
{
ms_authorities.Add(auth);
}
// ----------------------------------------------------------------------------
// wxDateTimeWorkDays
// ----------------------------------------------------------------------------
bool wxDateTimeWorkDays::DoIsHoliday(const wxDateTime& dt) const
{
wxDateTime::WeekDay wd = dt.GetWeekDay();
return (wd == wxDateTime::Sun) || (wd == wxDateTime::Sat);
}
size_t wxDateTimeWorkDays::DoGetHolidaysInRange(const wxDateTime& dtStart,
const wxDateTime& dtEnd,
wxDateTimeArray& holidays) const
{
if ( dtStart > dtEnd )
{
wxFAIL_MSG( _T("invalid date range in GetHolidaysInRange") );
return 0u;
}
holidays.Empty();
// instead of checking all days, start with the first Sat after dtStart and
// end with the last Sun before dtEnd
wxDateTime dtSatFirst = dtStart.GetNextWeekDay(wxDateTime::Sat),
dtSatLast = dtEnd.GetPrevWeekDay(wxDateTime::Sat),
dtSunFirst = dtStart.GetNextWeekDay(wxDateTime::Sun),
dtSunLast = dtEnd.GetPrevWeekDay(wxDateTime::Sun),
dt;
for ( dt = dtSatFirst; dt <= dtSatLast; dt += wxDateSpan::Week() )
{
holidays.Add(dt);
}
for ( dt = dtSunFirst; dt <= dtSunLast; dt += wxDateSpan::Week() )
{
holidays.Add(dt);
}
return holidays.GetCount();
}