+// ----------------------------------------------------------------------------
+// Weekday and monthday stuff
+// ----------------------------------------------------------------------------
+
+wxDateTime& wxDateTime::SetToLastMonthDay(Month month,
+ int year)
+{
+ // take the current month/year if none specified
+ ReplaceDefaultYearMonthWithCurrent(&year, &month);
+
+ return Set(GetNumOfDaysInMonth(year, month), month, year);
+}
+
+bool wxDateTime::SetToWeekDay(WeekDay weekday,
+ int n,
+ Month month,
+ int year)
+{
+ wxCHECK_MSG( weekday != Inv_WeekDay, FALSE, _T("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
+ {
+ // 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;
+ }
+}
+
+// ----------------------------------------------------------------------------
+// Julian day number conversion and related stuff
+// ----------------------------------------------------------------------------
+
+double wxDateTime::GetJulianDayNumber() const
+{
+ // JDN are always expressed for the GMT dates
+ Tm tm(ToTimezone(GMT0).GetTm(GMT0));
+
+ double result = GetTruncatedJDN(tm.mday, tm.mon, tm.year);
+
+ // add the part GetTruncatedJDN() neglected
+ result += 0.5;
+
+ // and now add the time: 86400 sec = 1 JDN
+ return result + ((double)(60*(60*tm.hour + tm.min) + tm.sec)) / 86400;
+}
+
+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,
+ _T("country support not implemented") );
+
+ // use the C RTL for the dates in the standard range
+ time_t timet = GetTicks();
+ if ( timet != (time_t)-1 )
+ {
+ tm *tm = localtime(&timet);
+
+ wxCHECK_MSG( tm, -1, _T("localtime() failed") );
+
+ return tm->tm_isdst;
+ }
+ else
+ {
+ // wxFAIL_MSG( _T("TODO") );
+
+ return -1;
+ }
+}
+
+wxDateTime& wxDateTime::MakeTimezone(const TimeZone& tz)
+{
+ int secDiff = GetTimeZone() + tz.GetOffset();
+
+ // we need to know whether DST is or not in effect for this date
+ if ( IsDST() == 1 )
+ {
+ // FIXME we assume that the DST is always shifted by 1 hour
+ secDiff -= 3600;
+ }
+
+ return Substract(wxTimeSpan::Seconds(secDiff));
+}
+