+// ----------------------------------------------------------------------------
+// struct Tm
+// ----------------------------------------------------------------------------
+
+wxDateTime::Tm::Tm()
+{
+ year = (wxDateTime_t)wxDateTime::Inv_Year;
+ mon = wxDateTime::Inv_Month;
+ mday = 0;
+ hour = min = sec = 0;
+ wday = wxDateTime::Inv_WeekDay;
+}
+
+wxDateTime::Tm::Tm(const struct tm& tm)
+{
+ sec = tm.tm_sec;
+ min = tm.tm_min;
+ hour = tm.tm_hour;
+ mday = tm.tm_mday;
+ mon = tm.tm_mon;
+ year = 1900 + tm.tm_year;
+ wday = tm.tm_wday;
+ yday = tm.tm_yday;
+}
+
+bool wxDateTime::Tm::IsValid() const
+{
+ // we allow for the leap seconds, although we don't use them (yet)
+ return (year != wxDateTime::Inv_Year) && (mon < 12) &&
+ (mday < gs_daysInMonth[IsLeapYear(year)][mon]) &&
+ (hour < 24) && (min < 60) && (sec < 62);
+}
+
+void wxDateTime::Tm::ComputeWeekDay()
+{
+ wxFAIL_MSG(_T("TODO"));
+}
+
+// ----------------------------------------------------------------------------
+// static functions
+// ----------------------------------------------------------------------------
+
+/* static */
+bool wxDateTime::IsLeapYear(int year, wxDateTime::Calendar cal)
+{
+ if ( cal == Gregorian )
+ {
+ // in Gregorian calendar leap years are those divisible by 4 except
+ // those divisible by 100 unless they're also divisible by 400
+ // (in some countries, like Russia and Greece, additional corrections
+ // exist, but they won't manifest themselves until 2700)
+ return (year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0));
+ }
+ else if ( cal == Julian )
+ {
+ // in Julian calendar the rule is simpler
+ return year % 4 == 0;
+ }
+ else
+ {
+ wxFAIL_MSG(_T("unknown calendar"));
+
+ return FALSE;
+ }
+}
+
+/* static */
+void wxDateTime::SetCountry(wxDateTime::Country country)
+{
+ ms_country = country;
+}
+
+/* static */
+int wxDateTime::ConvertYearToBC(int year)
+{
+ // year 0 is BC 1
+ return year > 0 ? year : year - 1;
+}
+
+/* static */
+int wxDateTime::GetCurrentYear(wxDateTime::Calendar cal)
+{
+ switch ( cal )
+ {
+ case Gregorian:
+ return Now().GetYear();
+
+ case Julian:
+ wxFAIL_MSG(_T("TODO"));
+ break;
+
+ default:
+ wxFAIL_MSG(_T("unsupported calendar"));
+ break;
+ }
+
+ return Inv_Year;
+}
+
+/* static */
+wxDateTime::Month wxDateTime::GetCurrentMonth(wxDateTime::Calendar cal)
+{
+ switch ( cal )
+ {
+ case Gregorian:
+ return Now().GetMonth();
+ break;
+
+ case Julian:
+ wxFAIL_MSG(_T("TODO"));
+ break;
+
+ default:
+ wxFAIL_MSG(_T("unsupported calendar"));
+ break;
+ }
+
+ return Inv_Month;
+}
+
+/* static */
+wxDateTime::wxDateTime_t wxDateTime::GetNumberOfDays(wxDateTime::Month month,
+ int year,
+ wxDateTime::Calendar cal)
+{
+ wxCHECK_MSG( month < 12, 0, _T("invalid month") );
+
+ if ( cal == Gregorian || cal == Julian )
+ {
+ if ( year == Inv_Year )
+ {
+ // take the current year if none given
+ year = GetCurrentYear();
+ }
+
+ return gs_daysInMonth[IsLeapYear(year)][month];
+ }
+ else
+ {
+ wxFAIL_MSG(_T("unsupported calendar"));
+
+ return 0;
+ }
+}
+
+/* static */
+wxString wxDateTime::GetMonthName(wxDateTime::Month month, bool abbr)
+{
+ wxCHECK_MSG( month != Inv_Month, _T(""), _T("invalid month") );
+
+ tm tm = { 0, 0, 0, 1, month, 76 }; // any year will do
+
+ return CallStrftime(abbr ? _T("%b") : _T("%B"), &tm);
+}
+
+/* static */
+wxString wxDateTime::GetWeekDayName(wxDateTime::WeekDay wday, bool abbr)
+{
+ wxCHECK_MSG( wday != Inv_WeekDay, _T(""), _T("invalid weekday") );
+
+ // take some arbitrary Sunday
+ tm tm = { 0, 0, 0, 28, Nov, 99 };
+
+ // and offset it by the number of days needed to get
+ tm.tm_mday += wday;
+
+ return CallStrftime(abbr ? _T("%a") : _T("%A"), &tm);
+}
+