+
+wxDateTime& wxDateTime::SetYear(int year)
+{
+ wxASSERT_MSG( IsValid(), wxT("invalid wxDateTime") );
+
+ Tm tm(GetTm());
+ tm.year = year;
+ Set(tm);
+
+ return *this;
+}
+
+wxDateTime& wxDateTime::SetMonth(Month month)
+{
+ wxASSERT_MSG( IsValid(), wxT("invalid wxDateTime") );
+
+ Tm tm(GetTm());
+ tm.mon = month;
+ Set(tm);
+
+ return *this;
+}
+
+wxDateTime& wxDateTime::SetDay(wxDateTime_t mday)
+{
+ wxASSERT_MSG( IsValid(), wxT("invalid wxDateTime") );
+
+ Tm tm(GetTm());
+ tm.mday = mday;
+ Set(tm);
+
+ return *this;
+}
+
+wxDateTime& wxDateTime::SetHour(wxDateTime_t hour)
+{
+ wxASSERT_MSG( IsValid(), wxT("invalid wxDateTime") );
+
+ Tm tm(GetTm());
+ tm.hour = hour;
+ Set(tm);
+
+ return *this;
+}
+
+wxDateTime& wxDateTime::SetMinute(wxDateTime_t min)
+{
+ wxASSERT_MSG( IsValid(), wxT("invalid wxDateTime") );
+
+ Tm tm(GetTm());
+ tm.min = min;
+ Set(tm);
+
+ return *this;
+}
+
+wxDateTime& wxDateTime::SetSecond(wxDateTime_t sec)
+{
+ wxASSERT_MSG( IsValid(), wxT("invalid wxDateTime") );
+
+ Tm tm(GetTm());
+ tm.sec = sec;
+ Set(tm);
+
+ return *this;
+}
+
+wxDateTime& wxDateTime::SetMillisecond(wxDateTime_t millisecond)
+{
+ wxASSERT_MSG( IsValid(), wxT("invalid wxDateTime") );
+
+ // we don't need to use GetTm() for this one
+ m_time -= m_time % 1000l;
+ m_time += millisecond;
+
+ return *this;
+}
+
+// ----------------------------------------------------------------------------
+// wxDateTime arithmetics
+// ----------------------------------------------------------------------------
+
+wxDateTime& wxDateTime::Add(const wxDateSpan& diff)
+{
+ Tm tm(GetTm());
+
+ 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);
+
+ wxASSERT_MSG( IsSameTime(tm),
+ wxT("Add(wxDateSpan) shouldn't modify time") );
+
+ return *this;
+}
+
+wxDateSpan wxDateTime::DiffAsDateSpan(const wxDateTime& dt) const
+{
+ wxASSERT_MSG( IsValid() && dt.IsValid(), wxT("invalid wxDateTime"));
+
+ // If dt is larger than this, calculations below needs to be inverted.
+ int inv = 1;
+ if ( dt > *this )
+ inv = -1;
+
+ int y = GetYear() - dt.GetYear();
+ int m = GetMonth() - dt.GetMonth();
+ int d = GetDay() - dt.GetDay();
+
+ // If month diff is negative, dt is the year before, so decrease year
+ // and set month diff to its inverse, e.g. January - December should be 1,
+ // not -11.
+ if ( m * inv < 0 || (m == 0 && d * inv < 0))
+ {
+ m += inv * MONTHS_IN_YEAR;
+ y -= inv;
+ }
+
+ // Same logic for days as for months above.
+ if ( d * inv < 0 )
+ {
+ // Use number of days in month from the month which end date we're
+ // crossing. That is month before this for positive diff, and this
+ // month for negative diff.
+ // If we're on january and using previous month, we get december
+ // previous year, but don't care, december has same amount of days
+ // every year.
+ wxDateTime::Month monthfordays = GetMonth();
+ if (inv > 0 && monthfordays == wxDateTime::Jan)
+ monthfordays = wxDateTime::Dec;
+ else if (inv > 0)
+ monthfordays = static_cast<wxDateTime::Month>(monthfordays - 1);
+
+ d += inv * wxDateTime::GetNumberOfDays(monthfordays, GetYear());
+ m -= inv;
+ }
+
+ int w = d / DAYS_PER_WEEK;
+
+ // Remove weeks from d, since wxDateSpan only keep days as the ones
+ // not in complete weeks
+ d -= w * DAYS_PER_WEEK;
+
+ return wxDateSpan(y, m, w, d);
+}
+
+// ----------------------------------------------------------------------------
+// Weekday and monthday stuff
+// ----------------------------------------------------------------------------
+
+// convert Sun, Mon, ..., Sat into 6, 0, ..., 5
+static inline int ConvertWeekDayToMondayBase(int wd)
+{
+ return wd == wxDateTime::Sun ? 6 : wd - 1;
+}
+
+/* static */
+wxDateTime
+wxDateTime::SetToWeekOfYear(int year, wxDateTime_t numWeek, WeekDay wd)
+{
+ wxASSERT_MSG( numWeek > 0,
+ wxT("invalid week number: weeks are counted from 1") );
+
+ // Jan 4 always lies in the 1st week of the year
+ wxDateTime dt(4, Jan, year);
+ dt.SetToWeekDayInSameWeek(wd);
+ dt += wxDateSpan::Weeks(numWeek - 1);
+
+ return dt;
+}
+
+#if WXWIN_COMPATIBILITY_2_6
+// use a separate function to avoid warnings about using deprecated
+// SetToTheWeek in GetWeek below
+static wxDateTime
+SetToTheWeek(int year,
+ wxDateTime::wxDateTime_t numWeek,
+ wxDateTime::WeekDay weekday,
+ wxDateTime::WeekFlags flags)
+{
+ // Jan 4 always lies in the 1st week of the year
+ wxDateTime dt(4, wxDateTime::Jan, year);
+ dt.SetToWeekDayInSameWeek(weekday, flags);
+ dt += wxDateSpan::Weeks(numWeek - 1);
+
+ return dt;
+}
+
+bool wxDateTime::SetToTheWeek(wxDateTime_t numWeek,
+ WeekDay weekday,
+ WeekFlags flags)
+{
+ int year = GetYear();
+ *this = ::SetToTheWeek(year, numWeek, weekday, flags);
+ if ( GetYear() != year )
+ {
+ // oops... numWeek was too big
+ return false;
+ }
+
+ return true;
+}
+
+wxDateTime wxDateTime::GetWeek(wxDateTime_t numWeek,
+ WeekDay weekday,
+ WeekFlags flags) const
+{
+ return ::SetToTheWeek(GetYear(), numWeek, weekday, flags);
+}
+#endif // WXWIN_COMPATIBILITY_2_6
+
+wxDateTime& wxDateTime::SetToLastMonthDay(Month month,
+ int year)
+{
+ // take the current month/year if none specified
+ if ( year == Inv_Year )
+ year = GetYear();
+ if ( month == Inv_Month )
+ month = GetMonth();
+
+ return Set(GetNumOfDaysInMonth(year, month), month, year);
+}
+
+wxDateTime& wxDateTime::SetToWeekDayInSameWeek(WeekDay weekday, WeekFlags flags)
+{
+ wxDATETIME_CHECK( weekday != Inv_WeekDay, wxT("invalid weekday") );
+
+ int wdayDst = weekday,
+ wdayThis = GetWeekDay();
+ if ( wdayDst == wdayThis )
+ {
+ // nothing to do
+ return *this;
+ }
+
+ if ( flags == Default_First )
+ {
+ flags = GetCountry() == USA ? Sunday_First : Monday_First;
+ }
+
+ // the logic below based on comparing weekday and wdayThis works if Sun (0)
+ // is the first day in the week, but breaks down for Monday_First case so
+ // we adjust the week days in this case
+ if ( flags == Monday_First )
+ {
+ if ( wdayThis == Sun )
+ wdayThis += 7;
+ if ( wdayDst == Sun )
+ wdayDst += 7;
+ }
+ //else: Sunday_First, nothing to do
+
+ // go forward or back in time to the day we want
+ if ( wdayDst < wdayThis )
+ {
+ return Subtract(wxDateSpan::Days(wdayThis - wdayDst));
+ }
+ else // weekday > wdayThis
+ {
+ return Add(wxDateSpan::Days(wdayDst - wdayThis));
+ }
+}
+
+wxDateTime& wxDateTime::SetToNextWeekDay(WeekDay weekday)
+{
+ wxDATETIME_CHECK( weekday != Inv_WeekDay, wxT("invalid weekday") );
+
+ int diff;
+ WeekDay wdayThis = GetWeekDay();
+ if ( weekday == wdayThis )
+ {
+ // nothing to do
+ return *this;
+ }
+ else if ( weekday < wdayThis )
+ {
+ // need to advance a week
+ diff = 7 - (wdayThis - weekday);
+ }
+ else // weekday > wdayThis
+ {
+ diff = weekday - wdayThis;
+ }
+
+ return Add(wxDateSpan::Days(diff));
+}
+
+wxDateTime& wxDateTime::SetToPrevWeekDay(WeekDay weekday)
+{
+ wxDATETIME_CHECK( weekday != Inv_WeekDay, wxT("invalid weekday") );
+
+ int diff;
+ WeekDay wdayThis = GetWeekDay();
+ if ( weekday == wdayThis )
+ {
+ // nothing to do
+ return *this;
+ }
+ else if ( weekday > wdayThis )
+ {
+ // need to go to previous week
+ diff = 7 - (weekday - wdayThis);
+ }
+ else // weekday < wdayThis
+ {
+ diff = wdayThis - weekday;
+ }
+
+ return Subtract(wxDateSpan::Days(diff));
+}
+
+bool wxDateTime::SetToWeekDay(WeekDay weekday,
+ int n,
+ Month month,
+ int year)
+{
+ wxCHECK_MSG( weekday != Inv_WeekDay, false, wxT("invalid weekday") );
+
+ // we don't check explicitly that -5 <= n <= 5 because we will return false
+ // anyhow in such case - but may be should still give an assert for it?
+
+ // take the current month/year if none specified
+ ReplaceDefaultYearMonthWithCurrent(&year, &month);
+
+ wxDateTime dt;
+
+ // TODO this probably could be optimised somehow...
+
+ if ( n > 0 )
+ {
+ // get the first day of the month
+ dt.Set(1, month, year);
+
+ // get its wday
+ WeekDay wdayFirst = dt.GetWeekDay();
+
+ // go to the first weekday of the month
+ int diff = weekday - wdayFirst;
+ if ( diff < 0 )
+ diff += 7;
+
+ // add advance n-1 weeks more
+ diff += 7*(n - 1);
+
+ dt += wxDateSpan::Days(diff);
+ }
+ else // count from the end of the month
+ {
+ // get the last day of the month
+ dt.SetToLastMonthDay(month, year);
+
+ // get its wday
+ WeekDay wdayLast = dt.GetWeekDay();
+
+ // go to the last weekday of the month
+ int diff = wdayLast - weekday;
+ if ( diff < 0 )
+ diff += 7;
+
+ // and rewind n-1 weeks from there
+ diff += 7*(-n - 1);
+
+ dt -= wxDateSpan::Days(diff);
+ }
+
+ // check that it is still in the same month
+ if ( dt.GetMonth() == month )
+ {
+ *this = dt;
+
+ return true;
+ }
+ else
+ {
+ // no such day in this month
+ return false;
+ }
+}
+
+static inline
+wxDateTime::wxDateTime_t GetDayOfYearFromTm(const wxDateTime::Tm& tm)
+{
+ return (wxDateTime::wxDateTime_t)(gs_cumulatedDays[wxDateTime::IsLeapYear(tm.year)][tm.mon] + tm.mday);
+}
+
+wxDateTime::wxDateTime_t wxDateTime::GetDayOfYear(const TimeZone& tz) const
+{
+ return GetDayOfYearFromTm(GetTm(tz));
+}
+
+wxDateTime::wxDateTime_t
+wxDateTime::GetWeekOfYear(wxDateTime::WeekFlags flags, const TimeZone& tz) const
+{
+ if ( flags == Default_First )
+ {
+ flags = GetCountry() == USA ? Sunday_First : Monday_First;
+ }
+
+ Tm tm(GetTm(tz));
+ wxDateTime_t nDayInYear = GetDayOfYearFromTm(tm);
+
+ int wdTarget = GetWeekDay(tz);
+ int wdYearStart = wxDateTime(1, Jan, GetYear()).GetWeekDay();
+ int week;
+ if ( flags == Sunday_First )
+ {
+ // FIXME: First week is not calculated correctly.
+ week = (nDayInYear - wdTarget + 7) / 7;
+ if ( wdYearStart == Wed || wdYearStart == Thu )
+ week++;
+ }
+ else // week starts with monday
+ {
+ // adjust the weekdays to non-US style.
+ wdYearStart = ConvertWeekDayToMondayBase(wdYearStart);
+ wdTarget = ConvertWeekDayToMondayBase(wdTarget);
+
+ // quoting from http://www.cl.cam.ac.uk/~mgk25/iso-time.html:
+ //
+ // Week 01 of a year is per definition the first week that has the
+ // Thursday in this year, which is equivalent to the week that
+ // contains the fourth day of January. In other words, the first
+ // week of a new year is the week that has the majority of its
+ // days in the new year. Week 01 might also contain days from the
+ // previous year and the week before week 01 of a year is the last
+ // week (52 or 53) of the previous year even if it contains days
+ // from the new year. A week starts with Monday (day 1) and ends
+ // with Sunday (day 7).
+ //
+
+ // if Jan 1 is Thursday or less, it is in the first week of this year
+ if ( wdYearStart < 4 )
+ {
+ // count the number of entire weeks between Jan 1 and this date
+ week = (nDayInYear + wdYearStart + 6 - wdTarget)/7;
+
+ // be careful to check for overflow in the next year
+ if ( week == 53 && tm.mday - wdTarget > 28 )
+ week = 1;
+ }
+ else // Jan 1 is in the last week of the previous year
+ {
+ // check if we happen to be at the last week of previous year:
+ if ( tm.mon == Jan && tm.mday < 8 - wdYearStart )
+ week = wxDateTime(31, Dec, GetYear()-1).GetWeekOfYear();
+ else
+ week = (nDayInYear + wdYearStart - 1 - wdTarget)/7;
+ }
+ }
+
+ return (wxDateTime::wxDateTime_t)week;
+}
+
+wxDateTime::wxDateTime_t wxDateTime::GetWeekOfMonth(wxDateTime::WeekFlags flags,
+ const TimeZone& tz) const
+{
+ Tm tm = GetTm(tz);
+ const wxDateTime dateFirst = wxDateTime(1, tm.mon, tm.year);
+ const wxDateTime::WeekDay wdFirst = dateFirst.GetWeekDay();
+
+ if ( flags == Default_First )
+ {
+ flags = GetCountry() == USA ? Sunday_First : Monday_First;
+ }
+
+ // compute offset of dateFirst from the beginning of the week
+ int firstOffset;
+ if ( flags == Sunday_First )
+ firstOffset = wdFirst - Sun;
+ else
+ firstOffset = wdFirst == Sun ? DAYS_PER_WEEK - 1 : wdFirst - Mon;
+
+ return (wxDateTime::wxDateTime_t)((tm.mday - 1 + firstOffset)/7 + 1);
+}
+
+wxDateTime& wxDateTime::SetToYearDay(wxDateTime::wxDateTime_t yday)
+{
+ int year = GetYear();
+ wxDATETIME_CHECK( (0 < yday) && (yday <= GetNumberOfDays(year)),
+ wxT("invalid year day") );
+
+ bool isLeap = IsLeapYear(year);
+ for ( Month mon = Jan; mon < Inv_Month; wxNextMonth(mon) )
+ {
+ // for Dec, we can't compare with gs_cumulatedDays[mon + 1], but we
+ // don't need it neither - because of the CHECK above we know that
+ // yday lies in December then
+ if ( (mon == Dec) || (yday <= gs_cumulatedDays[isLeap][mon + 1]) )
+ {
+ Set((wxDateTime::wxDateTime_t)(yday - gs_cumulatedDays[isLeap][mon]), mon, year);
+
+ break;
+ }
+ }
+
+ return *this;
+}
+
+// ----------------------------------------------------------------------------
+// Julian day number conversion and related stuff
+// ----------------------------------------------------------------------------
+
+double wxDateTime::GetJulianDayNumber() const
+{
+ return m_time.ToDouble() / MILLISECONDS_PER_DAY + EPOCH_JDN + 0.5;
+}
+
+double wxDateTime::GetRataDie() const
+{
+ // March 1 of the year 0 is Rata Die day -306 and JDN 1721119.5
+ return GetJulianDayNumber() - 1721119.5 - 306;
+}
+
+// ----------------------------------------------------------------------------
+// timezone and DST stuff
+// ----------------------------------------------------------------------------
+
+int wxDateTime::IsDST(wxDateTime::Country country) const
+{
+ wxCHECK_MSG( country == Country_Default, -1,
+ wxT("country support not implemented") );
+
+ // use the C RTL for the dates in the standard range
+ time_t timet = GetTicks();
+ if ( timet != (time_t)-1 )
+ {
+ struct tm tmstruct;
+ tm *tm = wxLocaltime_r(&timet, &tmstruct);
+
+ wxCHECK_MSG( tm, -1, wxT("wxLocaltime_r() failed") );
+
+ return tm->tm_isdst;
+ }
+ else
+ {
+ int year = GetYear();
+
+ if ( !IsDSTApplicable(year, country) )
+ {
+ // no DST time in this year in this country
+ return -1;
+ }
+
+ return IsBetween(GetBeginDST(year, country), GetEndDST(year, country));
+ }
+}
+
+wxDateTime& wxDateTime::MakeTimezone(const TimeZone& tz, bool noDST)
+{
+ long secDiff = wxGetTimeZone() + tz.GetOffset();
+
+ // we need to know whether DST is or not in effect for this date unless
+ // the test disabled by the caller
+ if ( !noDST && (IsDST() == 1) )
+ {
+ // FIXME we assume that the DST is always shifted by 1 hour
+ secDiff -= 3600;
+ }
+
+ return Add(wxTimeSpan::Seconds(secDiff));
+}
+
+wxDateTime& wxDateTime::MakeFromTimezone(const TimeZone& tz, bool noDST)
+{
+ long secDiff = wxGetTimeZone() + tz.GetOffset();
+
+ // we need to know whether DST is or not in effect for this date unless
+ // the test disabled by the caller
+ if ( !noDST && (IsDST() == 1) )
+ {
+ // FIXME we assume that the DST is always shifted by 1 hour
+ secDiff -= 3600;
+ }
+
+ return Subtract(wxTimeSpan::Seconds(secDiff));
+}
+
+// ============================================================================
+// 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.size();
+ 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.Clear();
+
+ const size_t countAuth = ms_authorities.size();
+ for ( size_t nAuth = 0; nAuth < countAuth; nAuth++ )
+ {
+ ms_authorities[nAuth]->DoGetHolidaysInRange(dtStart, dtEnd, hol);
+
+ WX_APPEND_ARRAY(holidays, hol);
+ }
+
+ holidays.Sort(wxDateTimeCompareFunc);
+
+ return holidays.size();
+}
+
+/* static */
+void wxDateTimeHolidayAuthority::ClearAllAuthorities()
+{
+ WX_CLEAR_ARRAY(ms_authorities);
+}
+
+/* static */
+void wxDateTimeHolidayAuthority::AddAuthority(wxDateTimeHolidayAuthority *auth)
+{
+ ms_authorities.push_back(auth);
+}
+
+wxDateTimeHolidayAuthority::~wxDateTimeHolidayAuthority()
+{
+ // required here for Darwin
+}
+
+// ----------------------------------------------------------------------------
+// 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( wxT("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();
+}
+
+// ============================================================================
+// other helper functions
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// iteration helpers: can be used to write a for loop over enum variable like
+// this:
+// for ( m = wxDateTime::Jan; m < wxDateTime::Inv_Month; wxNextMonth(m) )
+// ----------------------------------------------------------------------------
+
+WXDLLIMPEXP_BASE void wxNextMonth(wxDateTime::Month& m)
+{
+ wxASSERT_MSG( m < wxDateTime::Inv_Month, wxT("invalid month") );
+
+ // no wrapping or the for loop above would never end!
+ m = (wxDateTime::Month)(m + 1);
+}
+
+WXDLLIMPEXP_BASE void wxPrevMonth(wxDateTime::Month& m)
+{
+ wxASSERT_MSG( m < wxDateTime::Inv_Month, wxT("invalid month") );
+
+ m = m == wxDateTime::Jan ? wxDateTime::Inv_Month
+ : (wxDateTime::Month)(m - 1);
+}
+
+WXDLLIMPEXP_BASE void wxNextWDay(wxDateTime::WeekDay& wd)
+{
+ wxASSERT_MSG( wd < wxDateTime::Inv_WeekDay, wxT("invalid week day") );
+
+ // no wrapping or the for loop above would never end!
+ wd = (wxDateTime::WeekDay)(wd + 1);
+}
+
+WXDLLIMPEXP_BASE void wxPrevWDay(wxDateTime::WeekDay& wd)
+{
+ wxASSERT_MSG( wd < wxDateTime::Inv_WeekDay, wxT("invalid week day") );
+
+ wd = wd == wxDateTime::Sun ? wxDateTime::Inv_WeekDay
+ : (wxDateTime::WeekDay)(wd - 1);
+}
+
+#ifdef __WINDOWS__
+
+wxDateTime& wxDateTime::SetFromMSWSysTime(const SYSTEMTIME& st)
+{
+ return Set(st.wDay,
+ static_cast<wxDateTime::Month>(wxDateTime::Jan + st.wMonth - 1),
+ st.wYear,
+ st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
+}
+
+wxDateTime& wxDateTime::SetFromMSWSysDate(const SYSTEMTIME& st)
+{
+ return Set(st.wDay,
+ static_cast<wxDateTime::Month>(wxDateTime::Jan + st.wMonth - 1),
+ st.wYear,
+ 0, 0, 0, 0);
+}
+
+void wxDateTime::GetAsMSWSysTime(SYSTEMTIME* st) const
+{
+ const wxDateTime::Tm tm(GetTm());
+
+ st->wYear = (WXWORD)tm.year;
+ st->wMonth = (WXWORD)(tm.mon - wxDateTime::Jan + 1);
+ st->wDay = tm.mday;
+
+ st->wDayOfWeek = 0;
+ st->wHour = tm.hour;
+ st->wMinute = tm.min;
+ st->wSecond = tm.sec;
+ st->wMilliseconds = tm.msec;
+}
+
+void wxDateTime::GetAsMSWSysDate(SYSTEMTIME* st) const
+{
+ const wxDateTime::Tm tm(GetTm());
+
+ st->wYear = (WXWORD)tm.year;
+ st->wMonth = (WXWORD)(tm.mon - wxDateTime::Jan + 1);
+ st->wDay = tm.mday;
+
+ st->wDayOfWeek =
+ st->wHour =
+ st->wMinute =
+ st->wSecond =
+ st->wMilliseconds = 0;
+}
+
+#endif // __WINDOWS__
+
+#endif // wxUSE_DATETIME