X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/e538985edcc645878a1bbeb3dc3e898e9d29ad11..abd474ea63667f727940a009cc3e0b23ba9f418f:/src/common/datetime.cpp?ds=sidebyside diff --git a/src/common/datetime.cpp b/src/common/datetime.cpp index 90ac0aedf1..49bfa98e1a 100644 --- a/src/common/datetime.cpp +++ b/src/common/datetime.cpp @@ -117,69 +117,18 @@ wxCUSTOM_TYPE_INFO(wxDateTime, wxToStringConverter , wxFromStringCon #include #endif -#if !defined(WX_TIMEZONE) && !defined(WX_GMTOFF_IN_TM) - #if defined(__WXPALMOS__) - #define WX_GMTOFF_IN_TM - #elif defined(__BORLANDC__) || defined(__MINGW32__) || defined(__VISAGECPP__) - #define WX_TIMEZONE _timezone - #elif defined(__MWERKS__) - long wxmw_timezone = 28800; - #define WX_TIMEZONE wxmw_timezone - #elif defined(__DJGPP__) || defined(__WINE__) - #include - #include - static long wxGetTimeZone() - { - static long timezone = MAXLONG; // invalid timezone - if (timezone == MAXLONG) - { - struct timeb tb; - ftime(&tb); - timezone = tb.timezone; - } - return timezone; - } - #define WX_TIMEZONE wxGetTimeZone() - #elif defined(__DARWIN__) +#if defined(__DJGPP__) || defined(__WINE__) + #include + #include +#endif + +#ifndef WX_GMTOFF_IN_TM + // Define it for some systems which don't (always) use configure but are + // known to have tm_gmtoff field. + #if defined(__WXPALMOS__) || defined(__DARWIN__) #define WX_GMTOFF_IN_TM - #elif defined(__WXWINCE__) && defined(__VISUALC8__) - // _timezone is not present in dynamic run-time library - #if 0 - // Solution (1): use the function equivalent of _timezone - static long wxGetTimeZone() - { - static long s_Timezone = MAXLONG; // invalid timezone - if (s_Timezone == MAXLONG) - { - int t; - _get_timezone(& t); - s_Timezone = (long) t; - } - return s_Timezone; - } - #define WX_TIMEZONE wxGetTimeZone() - #elif 1 - // Solution (2): using GetTimeZoneInformation - static long wxGetTimeZone() - { - static long timezone = MAXLONG; // invalid timezone - if (timezone == MAXLONG) - { - TIME_ZONE_INFORMATION tzi; - ::GetTimeZoneInformation(&tzi); - timezone = tzi.Bias; - } - return timezone; - } - #define WX_TIMEZONE wxGetTimeZone() - #else - // Old method using _timezone: this symbol doesn't exist in the dynamic run-time library (i.e. using /MD) - #define WX_TIMEZONE _timezone - #endif - #else // unknown platform - try timezone - #define WX_TIMEZONE timezone #endif -#endif // !WX_TIMEZONE && !WX_GMTOFF_IN_TM +#endif // NB: VC8 safe time functions could/should be used for wxMSW as well probably #if defined(__WXWINCE__) && defined(__VISUALC8__) @@ -296,8 +245,6 @@ static const int SEC_PER_MIN = 60; static const int MIN_PER_HOUR = 60; -static const int HOURS_PER_DAY = 24; - static const long SECONDS_PER_DAY = 86400l; static const int DAYS_PER_WEEK = 7; @@ -338,8 +285,8 @@ const long wxDateTime::TIME_T_FACTOR = 1000l; // global data // ---------------------------------------------------------------------------- -const char *wxDefaultDateTimeFormat = "%c"; -const char *wxDefaultTimeSpanFormat = "%H:%M:%S"; +const char wxDefaultDateTimeFormat[] = "%c"; +const char wxDefaultTimeSpanFormat[] = "%H:%M:%S"; // in the fine tradition of ANSI C we use our equivalent of (time_t)-1 to // indicate an invalid wxDateTime object @@ -371,7 +318,7 @@ wxDateTime::wxDateTime_t GetNumOfDaysInMonth(int year, wxDateTime::Month month) { // the number of days in month in Julian/Gregorian calendar: the first line // is for normal years, the second one is for the leap ones - static wxDateTime::wxDateTime_t daysInMonth[2][MONTHS_IN_YEAR] = + static const wxDateTime::wxDateTime_t daysInMonth[2][MONTHS_IN_YEAR] = { { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } @@ -385,6 +332,7 @@ wxDateTime::wxDateTime_t GetNumOfDaysInMonth(int year, wxDateTime::Month month) // NOTE: not static because used by datetimefmt.cpp int GetTimeZone() { +#ifdef WX_GMTOFF_IN_TM // set to true when the timezone is set static bool s_timezoneSet = false; static long gmtoffset = LONG_MAX; // invalid timezone @@ -400,17 +348,40 @@ int GetTimeZone() wxLocaltime_r(&t, &tm); s_timezoneSet = true; -#ifdef WX_GMTOFF_IN_TM // note that GMT offset is the opposite of time zone and so to return // consistent results in both WX_GMTOFF_IN_TM and !WX_GMTOFF_IN_TM // cases we have to negate it gmtoffset = -tm.tm_gmtoff; -#else // !WX_GMTOFF_IN_TM - gmtoffset = WX_TIMEZONE; -#endif // WX_GMTOFF_IN_TM/!WX_GMTOFF_IN_TM } - return (int)gmtoffset; +#elif defined(__DJGPP__) || defined(__WINE__) + struct timeb tb; + ftime(&tb); + return tb.timezone*60; +#elif defined(__VISUALC__) + // We must initialize the time zone information before using it (this will + // be done only once internally). + _tzset(); + + // Starting with VC++ 8 timezone variable is deprecated and is not even + // available in some standard library version so use the new function for + // accessing it instead. + #if wxCHECK_VISUALC_VERSION(8) + long t; + _get_timezone(&t); + return t; + #else // VC++ < 8 + return timezone; + #endif +#elif defined(WX_TIMEZONE) // If WX_TIMEZONE was defined by configure, use it. + return WX_TIMEZONE; +#elif defined(__BORLANDC__) || defined(__MINGW32__) || defined(__VISAGECPP__) + return _timezone; +#elif defined(__MWERKS__) + return 28800; +#else // unknown platform -- assume it has timezone + return timezone; +#endif // WX_GMTOFF_IN_TM/!WX_GMTOFF_IN_TM } // return the integral part of the JDN for the midnight of the given date (to @@ -427,7 +398,7 @@ static long GetTruncatedJDN(wxDateTime::wxDateTime_t day, (year > JDN_0_YEAR) || ((year == JDN_0_YEAR) && (mon > JDN_0_MONTH)) || ((year == JDN_0_YEAR) && (mon == JDN_0_MONTH) && (day >= JDN_0_DAY)), - _T("date out of range - can't convert to JDN") + wxT("date out of range - can't convert to JDN") ); // make the year positive to avoid problems with negative numbers division @@ -453,7 +424,7 @@ static long GetTruncatedJDN(wxDateTime::wxDateTime_t day, - JDN_OFFSET; } -#ifdef HAVE_STRFTIME +#ifdef wxHAS_STRFTIME // this function is a wrapper around strftime(3) adding error checking // NOTE: not static because used by datetimefmt.cpp @@ -467,7 +438,7 @@ wxString CallStrftime(const wxString& format, const tm* tm) if ( !wxStrftime(buf, WXSIZEOF(buf), format, tm) ) { // if the format is valid, buffer must be too small? - wxFAIL_MSG(_T("strftime() failed")); + wxFAIL_MSG(wxT("strftime() failed")); buf[0] = '\0'; } @@ -476,7 +447,7 @@ wxString CallStrftime(const wxString& format, const tm* tm) return s; } -#endif // HAVE_STRFTIME +#endif // wxHAS_STRFTIME // if year and/or month have invalid values, replace them with the current ones static void ReplaceDefaultYearMonthWithCurrent(int *year, @@ -526,8 +497,12 @@ wxDateTime::Tm::Tm() { year = (wxDateTime_t)wxDateTime::Inv_Year; mon = wxDateTime::Inv_Month; - mday = 0; - hour = min = sec = msec = 0; + mday = + yday = 0; + hour = + min = + sec = + msec = 0; wday = wxDateTime::Inv_WeekDay; } @@ -547,9 +522,17 @@ wxDateTime::Tm::Tm(const struct tm& tm, const TimeZone& tz) bool wxDateTime::Tm::IsValid() const { + if ( mon == wxDateTime::Inv_Month ) + return false; + + // We need to check this here to avoid crashing in GetNumOfDaysInMonth() if + // somebody passed us "(wxDateTime::Month)1000". + wxCHECK_MSG( mon >= wxDateTime::Jan && mon < wxDateTime::Inv_Month, false, + wxS("Invalid month value") ); + // we allow for the leap seconds, although we don't use them (yet) return (year != wxDateTime::Inv_Year) && (mon != wxDateTime::Inv_Month) && - (mday <= GetNumOfDaysInMonth(year, mon)) && + (mday > 0 && mday <= GetNumOfDaysInMonth(year, mon)) && (hour < 24) && (min < 60) && (sec < 62) && (msec < 1000); } @@ -580,7 +563,7 @@ void wxDateTime::Tm::AddMonths(int monDiff) mon = (wxDateTime::Month)(mon + monDiff); - wxASSERT_MSG( mon >= 0 && mon < MONTHS_IN_YEAR, _T("logic error") ); + wxASSERT_MSG( mon >= 0 && mon < MONTHS_IN_YEAR, wxT("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 @@ -605,7 +588,7 @@ void wxDateTime::Tm::AddDays(int dayDiff) } wxASSERT_MSG( mday > 0 && mday <= GetNumOfDaysInMonth(year, mon), - _T("logic error") ); + wxT("logic error") ); } // ---------------------------------------------------------------------------- @@ -660,7 +643,7 @@ wxDateTime::TimeZone::TimeZone(wxDateTime::TZ tz) break; default: - wxFAIL_MSG( _T("unknown time zone") ); + wxFAIL_MSG( wxT("unknown time zone") ); } } @@ -696,7 +679,7 @@ bool wxDateTime::IsLeapYear(int year, wxDateTime::Calendar cal) } else { - wxFAIL_MSG(_T("unknown calendar")); + wxFAIL_MSG(wxT("unknown calendar")); return false; } @@ -724,11 +707,11 @@ int wxDateTime::GetCurrentYear(wxDateTime::Calendar cal) return Now().GetYear(); case Julian: - wxFAIL_MSG(_T("TODO")); + wxFAIL_MSG(wxT("TODO")); break; default: - wxFAIL_MSG(_T("unsupported calendar")); + wxFAIL_MSG(wxT("unsupported calendar")); break; } @@ -744,11 +727,11 @@ wxDateTime::Month wxDateTime::GetCurrentMonth(wxDateTime::Calendar cal) return Now().GetMonth(); case Julian: - wxFAIL_MSG(_T("TODO")); + wxFAIL_MSG(wxT("TODO")); break; default: - wxFAIL_MSG(_T("unsupported calendar")); + wxFAIL_MSG(wxT("unsupported calendar")); break; } @@ -771,7 +754,7 @@ wxDateTime::wxDateTime_t wxDateTime::GetNumberOfDays(int year, Calendar cal) return IsLeapYear(year) ? 366 : 365; default: - wxFAIL_MSG(_T("unsupported calendar")); + wxFAIL_MSG(wxT("unsupported calendar")); break; } @@ -783,7 +766,7 @@ wxDateTime::wxDateTime_t wxDateTime::GetNumberOfDays(wxDateTime::Month month, int year, wxDateTime::Calendar cal) { - wxCHECK_MSG( month < MONTHS_IN_YEAR, 0, _T("invalid month") ); + wxCHECK_MSG( month < MONTHS_IN_YEAR, 0, wxT("invalid month") ); if ( cal == Gregorian || cal == Julian ) { @@ -797,7 +780,7 @@ wxDateTime::wxDateTime_t wxDateTime::GetNumberOfDays(wxDateTime::Month month, } else { - wxFAIL_MSG(_T("unsupported calendar")); + wxFAIL_MSG(wxT("unsupported calendar")); return 0; } @@ -836,7 +819,7 @@ wxString wxDateTime::GetEnglishMonthName(Month month, NameFlags flags) { wxCHECK_MSG( month != Inv_Month, wxEmptyString, "invalid month" ); - static const char *monthNames[2][MONTHS_IN_YEAR] = + static const char *const monthNames[2][MONTHS_IN_YEAR] = { { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }, @@ -855,8 +838,8 @@ wxString wxDateTime::GetEnglishMonthName(Month month, NameFlags flags) wxString wxDateTime::GetMonthName(wxDateTime::Month month, wxDateTime::NameFlags flags) { -#ifdef HAVE_STRFTIME - wxCHECK_MSG( month != Inv_Month, wxEmptyString, _T("invalid month") ); +#ifdef wxHAS_STRFTIME + wxCHECK_MSG( month != Inv_Month, wxEmptyString, wxT("invalid month") ); // notice that we must set all the fields to avoid confusing libc (GNU one // gets confused to a crash if we don't do this) @@ -864,18 +847,18 @@ wxString wxDateTime::GetMonthName(wxDateTime::Month month, InitTm(tm); tm.tm_mon = month; - return CallStrftime(flags == Name_Abbr ? _T("%b") : _T("%B"), &tm); -#else // !HAVE_STRFTIME + return CallStrftime(flags == Name_Abbr ? wxT("%b") : wxT("%B"), &tm); +#else // !wxHAS_STRFTIME return GetEnglishMonthName(month, flags); -#endif // HAVE_STRFTIME/!HAVE_STRFTIME +#endif // wxHAS_STRFTIME/!wxHAS_STRFTIME } /* static */ wxString wxDateTime::GetEnglishWeekDayName(WeekDay wday, NameFlags flags) { - wxCHECK_MSG( wday != Inv_WeekDay, wxEmptyString, _T("invalid weekday") ); + wxCHECK_MSG( wday != Inv_WeekDay, wxEmptyString, wxT("invalid weekday") ); - static const char *weekdayNames[2][DAYS_PER_400_YEARS] = + static const char *const weekdayNames[2][DAYS_PER_WEEK] = { { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" }, @@ -893,8 +876,8 @@ wxString wxDateTime::GetEnglishWeekDayName(WeekDay wday, NameFlags flags) wxString wxDateTime::GetWeekDayName(wxDateTime::WeekDay wday, wxDateTime::NameFlags flags) { -#ifdef HAVE_STRFTIME - wxCHECK_MSG( wday != Inv_WeekDay, wxEmptyString, _T("invalid weekday") ); +#ifdef wxHAS_STRFTIME + wxCHECK_MSG( wday != Inv_WeekDay, wxEmptyString, wxT("invalid weekday") ); // take some arbitrary Sunday (but notice that the day should be such that // after adding wday to it below we still have a valid date, e.g. don't @@ -912,10 +895,10 @@ wxString wxDateTime::GetWeekDayName(wxDateTime::WeekDay wday, (void)mktime(&tm); // ... and call strftime() - return CallStrftime(flags == Name_Abbr ? _T("%a") : _T("%A"), &tm); -#else // !HAVE_STRFTIME + return CallStrftime(flags == Name_Abbr ? wxT("%a") : wxT("%A"), &tm); +#else // !wxHAS_STRFTIME return GetEnglishWeekDayName(wday, flags); -#endif // HAVE_STRFTIME/!HAVE_STRFTIME +#endif // wxHAS_STRFTIME/!wxHAS_STRFTIME } /* static */ @@ -934,7 +917,7 @@ void wxDateTime::GetAmPmStrings(wxString *am, wxString *pm) // assert, even though it is a perfectly legal use. if ( am ) { - if (wxStrftime(buffer, sizeof(buffer)/sizeof(wxChar), _T("%p"), &tm) > 0) + if (wxStrftime(buffer, WXSIZEOF(buffer), wxT("%p"), &tm) > 0) *am = wxString(buffer); else *am = wxString(); @@ -942,7 +925,7 @@ void wxDateTime::GetAmPmStrings(wxString *am, wxString *pm) if ( pm ) { tm.tm_hour = 13; - if (wxStrftime(buffer, sizeof(buffer)/sizeof(wxChar), _T("%p"), &tm) > 0) + if (wxStrftime(buffer, WXSIZEOF(buffer), wxT("%p"), &tm) > 0) *pm = wxString(buffer); else *pm = wxString(); @@ -967,24 +950,24 @@ wxDateTime::Country wxDateTime::GetCountry() struct tm tmstruct; struct tm *tm = wxLocaltime_r(&t, &tmstruct); - wxString tz = CallStrftime(_T("%Z"), tm); - if ( tz == _T("WET") || tz == _T("WEST") ) + wxString tz = CallStrftime(wxT("%Z"), tm); + if ( tz == wxT("WET") || tz == wxT("WEST") ) { ms_country = UK; } - else if ( tz == _T("CET") || tz == _T("CEST") ) + else if ( tz == wxT("CET") || tz == wxT("CEST") ) { ms_country = Country_EEC; } - else if ( tz == _T("MSK") || tz == _T("MSD") ) + else if ( tz == wxT("MSK") || tz == wxT("MSD") ) { ms_country = Russia; } - else if ( tz == _T("AST") || tz == _T("ADT") || - tz == _T("EST") || tz == _T("EDT") || - tz == _T("CST") || tz == _T("CDT") || - tz == _T("MST") || tz == _T("MDT") || - tz == _T("PST") || tz == _T("PDT") ) + else if ( tz == wxT("AST") || tz == wxT("ADT") || + tz == wxT("EST") || tz == wxT("EDT") || + tz == wxT("CST") || tz == wxT("CDT") || + tz == wxT("MST") || tz == wxT("MDT") || + tz == wxT("PST") || tz == wxT("PDT") ) { ms_country = USA; } @@ -1083,7 +1066,7 @@ wxDateTime wxDateTime::GetBeginDST(int year, Country country) if ( !dt.SetToLastWeekDay(Sun, Mar, year) ) { // weird... - wxFAIL_MSG( _T("no last Sunday in March?") ); + wxFAIL_MSG( wxT("no last Sunday in March?") ); } dt += wxTimeSpan::Hours(1); @@ -1126,7 +1109,7 @@ wxDateTime wxDateTime::GetBeginDST(int year, Country country) if ( !dt.SetToLastWeekDay(Sun, Apr, year) ) { // weird... - wxFAIL_MSG( _T("no first Sunday in April?") ); + wxFAIL_MSG( wxT("no first Sunday in April?") ); } } else if ( year > 2006 ) @@ -1137,7 +1120,7 @@ wxDateTime wxDateTime::GetBeginDST(int year, Country country) if ( !dt.SetToWeekDay(Sun, 2, Mar, year) ) { // weird... - wxFAIL_MSG( _T("no second Sunday in March?") ); + wxFAIL_MSG( wxT("no second Sunday in March?") ); } } else @@ -1145,7 +1128,7 @@ wxDateTime wxDateTime::GetBeginDST(int year, Country country) if ( !dt.SetToWeekDay(Sun, 1, Apr, year) ) { // weird... - wxFAIL_MSG( _T("no first Sunday in April?") ); + wxFAIL_MSG( wxT("no first Sunday in April?") ); } } @@ -1192,7 +1175,7 @@ wxDateTime wxDateTime::GetEndDST(int year, Country country) if ( !dt.SetToLastWeekDay(Sun, Oct, year) ) { // weirder and weirder... - wxFAIL_MSG( _T("no last Sunday in October?") ); + wxFAIL_MSG( wxT("no last Sunday in October?") ); } dt += wxTimeSpan::Hours(1); @@ -1225,7 +1208,7 @@ wxDateTime wxDateTime::GetEndDST(int year, Country country) if ( !dt.SetToWeekDay(Sun, 1, Nov, year) ) { // weird... - wxFAIL_MSG( _T("no first Sunday in November?") ); + wxFAIL_MSG( wxT("no first Sunday in November?") ); } } else @@ -1235,7 +1218,7 @@ wxDateTime wxDateTime::GetEndDST(int year, Country country) if ( !dt.SetToLastWeekDay(Sun, Oct, year) ) { // weirder and weirder... - wxFAIL_MSG( _T("no last Sunday in October?") ); + wxFAIL_MSG( wxT("no last Sunday in October?") ); } } @@ -1282,7 +1265,7 @@ wxDateTime& wxDateTime::Set(const struct tm& tm) tm2.tm_sec)); } - wxFAIL_MSG( _T("mktime() failed") ); + wxFAIL_MSG( wxT("mktime() failed") ); *this = wxInvalidDateTime; @@ -1305,13 +1288,13 @@ wxDateTime& wxDateTime::Set(wxDateTime_t hour, second < 62 && minute < 60 && millisec < 1000, - _T("Invalid time in wxDateTime::Set()") ); + wxT("Invalid time in wxDateTime::Set()") ); // get the current date from system struct tm tmstruct; struct tm *tm = GetTmNow(&tmstruct); - wxDATETIME_CHECK( tm, _T("wxLocaltime_r() failed") ); + wxDATETIME_CHECK( tm, wxT("wxLocaltime_r() failed") ); // make a copy so it isn't clobbered by the call to mktime() below struct tm tm1(*tm); @@ -1345,12 +1328,12 @@ wxDateTime& wxDateTime::Set(wxDateTime_t day, second < 62 && minute < 60 && millisec < 1000, - _T("Invalid time in wxDateTime::Set()") ); + wxT("Invalid time in wxDateTime::Set()") ); ReplaceDefaultYearMonthWithCurrent(&year, &month); wxDATETIME_CHECK( (0 < day) && (day <= GetNumberOfDays(month, year)), - _T("Invalid date in wxDateTime::Set()") ); + wxT("Invalid date in wxDateTime::Set()") ); // the range of time_t type (inclusive) static const int yearMinInRange = 1970; @@ -1489,7 +1472,7 @@ unsigned long wxDateTime::GetAsDOS() const time_t ticks = GetTicks(); struct tm tmstruct; struct tm *tm = wxLocaltime_r(&ticks, &tmstruct); - wxCHECK_MSG( tm, ULONG_MAX, _T("time can't be represented in DOS format") ); + wxCHECK_MSG( tm, ULONG_MAX, wxT("time can't be represented in DOS format") ); long year = tm->tm_year; year -= 80; @@ -1521,7 +1504,7 @@ unsigned long wxDateTime::GetAsDOS() const wxDateTime::Tm wxDateTime::GetTm(const TimeZone& tz) const { - wxASSERT_MSG( IsValid(), _T("invalid wxDateTime") ); + wxASSERT_MSG( IsValid(), wxT("invalid wxDateTime") ); time_t time = GetTicks(); if ( time != (time_t)-1 ) @@ -1535,7 +1518,7 @@ wxDateTime::Tm wxDateTime::GetTm(const TimeZone& tz) const tm = wxLocaltime_r(&time, &tmstruct); // should never happen - wxCHECK_MSG( tm, Tm(), _T("wxLocaltime_r() failed") ); + wxCHECK_MSG( tm, Tm(), wxT("wxLocaltime_r() failed") ); } else { @@ -1550,7 +1533,7 @@ wxDateTime::Tm wxDateTime::GetTm(const TimeZone& tz) const tm = wxGmtime_r(&time, &tmstruct); // should never happen - wxCHECK_MSG( tm, Tm(), _T("wxGmtime_r() failed") ); + wxCHECK_MSG( tm, Tm(), wxT("wxGmtime_r() failed") ); } else { @@ -1593,7 +1576,7 @@ wxDateTime::Tm wxDateTime::GetTm(const TimeZone& tz) const // CREDIT: code below is by Scott E. Lee (but bugs are mine) - wxASSERT_MSG( jdn > -2, _T("JDN out of range") ); + wxASSERT_MSG( jdn > -2, wxT("JDN out of range") ); // calculate the century long temp = (jdn + JDN_OFFSET) * 4 - 1; @@ -1624,12 +1607,13 @@ wxDateTime::Tm wxDateTime::GetTm(const TimeZone& tz) const year -= 4800; // check that the algorithm gave us something reasonable - wxASSERT_MSG( (0 < month) && (month <= 12), _T("invalid month") ); - wxASSERT_MSG( (1 <= day) && (day < 32), _T("invalid day") ); + wxASSERT_MSG( (0 < month) && (month <= 12), wxT("invalid month") ); + wxASSERT_MSG( (1 <= day) && (day < 32), wxT("invalid day") ); // construct Tm from these values Tm tm; tm.year = (int)year; + tm.yday = (wxDateTime_t)(dayOfYear - 1); // use C convention for day number tm.mon = (Month)(month - 1); // algorithm yields 1 for January, not 0 tm.mday = (wxDateTime_t)day; tm.msec = (wxDateTime_t)(timeOnly % 1000); @@ -1650,7 +1634,7 @@ wxDateTime::Tm wxDateTime::GetTm(const TimeZone& tz) const wxDateTime& wxDateTime::SetYear(int year) { - wxASSERT_MSG( IsValid(), _T("invalid wxDateTime") ); + wxASSERT_MSG( IsValid(), wxT("invalid wxDateTime") ); Tm tm(GetTm()); tm.year = year; @@ -1661,7 +1645,7 @@ wxDateTime& wxDateTime::SetYear(int year) wxDateTime& wxDateTime::SetMonth(Month month) { - wxASSERT_MSG( IsValid(), _T("invalid wxDateTime") ); + wxASSERT_MSG( IsValid(), wxT("invalid wxDateTime") ); Tm tm(GetTm()); tm.mon = month; @@ -1672,7 +1656,7 @@ wxDateTime& wxDateTime::SetMonth(Month month) wxDateTime& wxDateTime::SetDay(wxDateTime_t mday) { - wxASSERT_MSG( IsValid(), _T("invalid wxDateTime") ); + wxASSERT_MSG( IsValid(), wxT("invalid wxDateTime") ); Tm tm(GetTm()); tm.mday = mday; @@ -1683,7 +1667,7 @@ wxDateTime& wxDateTime::SetDay(wxDateTime_t mday) wxDateTime& wxDateTime::SetHour(wxDateTime_t hour) { - wxASSERT_MSG( IsValid(), _T("invalid wxDateTime") ); + wxASSERT_MSG( IsValid(), wxT("invalid wxDateTime") ); Tm tm(GetTm()); tm.hour = hour; @@ -1694,7 +1678,7 @@ wxDateTime& wxDateTime::SetHour(wxDateTime_t hour) wxDateTime& wxDateTime::SetMinute(wxDateTime_t min) { - wxASSERT_MSG( IsValid(), _T("invalid wxDateTime") ); + wxASSERT_MSG( IsValid(), wxT("invalid wxDateTime") ); Tm tm(GetTm()); tm.min = min; @@ -1705,7 +1689,7 @@ wxDateTime& wxDateTime::SetMinute(wxDateTime_t min) wxDateTime& wxDateTime::SetSecond(wxDateTime_t sec) { - wxASSERT_MSG( IsValid(), _T("invalid wxDateTime") ); + wxASSERT_MSG( IsValid(), wxT("invalid wxDateTime") ); Tm tm(GetTm()); tm.sec = sec; @@ -1716,7 +1700,7 @@ wxDateTime& wxDateTime::SetSecond(wxDateTime_t sec) wxDateTime& wxDateTime::SetMillisecond(wxDateTime_t millisecond) { - wxASSERT_MSG( IsValid(), _T("invalid wxDateTime") ); + wxASSERT_MSG( IsValid(), wxT("invalid wxDateTime") ); // we don't need to use GetTm() for this one m_time -= m_time % 1000l; @@ -1754,7 +1738,7 @@ wxDateTime& wxDateTime::Add(const wxDateSpan& diff) Set(tm); wxASSERT_MSG( IsSameTime(tm), - _T("Add(wxDateSpan) shouldn't modify time") ); + wxT("Add(wxDateSpan) shouldn't modify time") ); return *this; } @@ -1774,7 +1758,7 @@ wxDateTime wxDateTime::SetToWeekOfYear(int year, wxDateTime_t numWeek, WeekDay wd) { wxASSERT_MSG( numWeek > 0, - _T("invalid week number: weeks are counted from 1") ); + 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); @@ -1838,7 +1822,7 @@ wxDateTime& wxDateTime::SetToLastMonthDay(Month month, wxDateTime& wxDateTime::SetToWeekDayInSameWeek(WeekDay weekday, WeekFlags flags) { - wxDATETIME_CHECK( weekday != Inv_WeekDay, _T("invalid weekday") ); + wxDATETIME_CHECK( weekday != Inv_WeekDay, wxT("invalid weekday") ); int wdayDst = weekday, wdayThis = GetWeekDay(); @@ -1878,7 +1862,7 @@ wxDateTime& wxDateTime::SetToWeekDayInSameWeek(WeekDay weekday, WeekFlags flags) wxDateTime& wxDateTime::SetToNextWeekDay(WeekDay weekday) { - wxDATETIME_CHECK( weekday != Inv_WeekDay, _T("invalid weekday") ); + wxDATETIME_CHECK( weekday != Inv_WeekDay, wxT("invalid weekday") ); int diff; WeekDay wdayThis = GetWeekDay(); @@ -1902,7 +1886,7 @@ wxDateTime& wxDateTime::SetToNextWeekDay(WeekDay weekday) wxDateTime& wxDateTime::SetToPrevWeekDay(WeekDay weekday) { - wxDATETIME_CHECK( weekday != Inv_WeekDay, _T("invalid weekday") ); + wxDATETIME_CHECK( weekday != Inv_WeekDay, wxT("invalid weekday") ); int diff; WeekDay wdayThis = GetWeekDay(); @@ -1929,7 +1913,7 @@ bool wxDateTime::SetToWeekDay(WeekDay weekday, Month month, int year) { - wxCHECK_MSG( weekday != Inv_WeekDay, false, _T("invalid weekday") ); + 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? @@ -2070,23 +2054,29 @@ wxDateTime::wxDateTime_t wxDateTime::GetWeekOfMonth(wxDateTime::WeekFlags flags, const TimeZone& tz) const { Tm tm = GetTm(tz); - wxDateTime dtMonthStart = wxDateTime(1, tm.mon, tm.year); - int nWeek = GetWeekOfYear(flags) - dtMonthStart.GetWeekOfYear(flags) + 1; - if ( nWeek < 0 ) + const wxDateTime dateFirst = wxDateTime(1, tm.mon, tm.year); + const wxDateTime::WeekDay wdFirst = dateFirst.GetWeekDay(); + + if ( flags == Default_First ) { - // this may happen for January when Jan, 1 is the last week of the - // previous year - nWeek += IsLeapYear(tm.year - 1) ? 53 : 52; + flags = GetCountry() == USA ? Sunday_First : Monday_First; } - return (wxDateTime::wxDateTime_t)nWeek; + // 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)), - _T("invalid year day") ); + wxT("invalid year day") ); bool isLeap = IsLeapYear(year); for ( Month mon = Jan; mon < Inv_Month; wxNextMonth(mon) ) @@ -2127,7 +2117,7 @@ double wxDateTime::GetRataDie() const int wxDateTime::IsDST(wxDateTime::Country country) const { wxCHECK_MSG( country == Country_Default, -1, - _T("country support not implemented") ); + wxT("country support not implemented") ); // use the C RTL for the dates in the standard range time_t timet = GetTicks(); @@ -2136,7 +2126,7 @@ int wxDateTime::IsDST(wxDateTime::Country country) const struct tm tmstruct; tm *tm = wxLocaltime_r(&timet, &tmstruct); - wxCHECK_MSG( tm, -1, _T("wxLocaltime_r() failed") ); + wxCHECK_MSG( tm, -1, wxT("wxLocaltime_r() failed") ); return tm->tm_isdst; } @@ -2279,7 +2269,7 @@ size_t wxDateTimeWorkDays::DoGetHolidaysInRange(const wxDateTime& dtStart, { if ( dtStart > dtEnd ) { - wxFAIL_MSG( _T("invalid date range in GetHolidaysInRange") ); + wxFAIL_MSG( wxT("invalid date range in GetHolidaysInRange") ); return 0u; } @@ -2319,7 +2309,7 @@ size_t wxDateTimeWorkDays::DoGetHolidaysInRange(const wxDateTime& dtStart, WXDLLIMPEXP_BASE void wxNextMonth(wxDateTime::Month& m) { - wxASSERT_MSG( m < wxDateTime::Inv_Month, _T("invalid month") ); + wxASSERT_MSG( m < wxDateTime::Inv_Month, wxT("invalid month") ); // no wrapping or the for loop above would never end! m = (wxDateTime::Month)(m + 1); @@ -2327,7 +2317,7 @@ WXDLLIMPEXP_BASE void wxNextMonth(wxDateTime::Month& m) WXDLLIMPEXP_BASE void wxPrevMonth(wxDateTime::Month& m) { - wxASSERT_MSG( m < wxDateTime::Inv_Month, _T("invalid month") ); + wxASSERT_MSG( m < wxDateTime::Inv_Month, wxT("invalid month") ); m = m == wxDateTime::Jan ? wxDateTime::Inv_Month : (wxDateTime::Month)(m - 1); @@ -2335,7 +2325,7 @@ WXDLLIMPEXP_BASE void wxPrevMonth(wxDateTime::Month& m) WXDLLIMPEXP_BASE void wxNextWDay(wxDateTime::WeekDay& wd) { - wxASSERT_MSG( wd < wxDateTime::Inv_WeekDay, _T("invalid week day") ); + 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); @@ -2343,7 +2333,7 @@ WXDLLIMPEXP_BASE void wxNextWDay(wxDateTime::WeekDay& wd) WXDLLIMPEXP_BASE void wxPrevWDay(wxDateTime::WeekDay& wd) { - wxASSERT_MSG( wd < wxDateTime::Inv_WeekDay, _T("invalid week day") ); + wxASSERT_MSG( wd < wxDateTime::Inv_WeekDay, wxT("invalid week day") ); wd = wd == wxDateTime::Sun ? wxDateTime::Inv_WeekDay : (wxDateTime::WeekDay)(wd - 1); @@ -2356,7 +2346,15 @@ wxDateTime& wxDateTime::SetFromMSWSysTime(const SYSTEMTIME& st) return Set(st.wDay, static_cast(wxDateTime::Jan + st.wMonth - 1), st.wYear, - 0, 0, 0); + st.wHour, st.wMinute, st.wSecond, st.wMilliseconds); +} + +wxDateTime& wxDateTime::SetFromMSWSysDate(const SYSTEMTIME& st) +{ + return Set(st.wDay, + static_cast(wxDateTime::Jan + st.wMonth - 1), + st.wYear, + 0, 0, 0, 0); } void wxDateTime::GetAsMSWSysTime(SYSTEMTIME* st) const @@ -2367,12 +2365,28 @@ void wxDateTime::GetAsMSWSysTime(SYSTEMTIME* st) const 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 // __WXMSW__ #endif // wxUSE_DATETIME