X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/9a83f860948059b0273b5cc6d9e43fadad3ebfca..eea4d01c65f9b29baa1193db762b4c6b8144af24:/src/common/datetime.cpp diff --git a/src/common/datetime.cpp b/src/common/datetime.cpp index 5de52dd01e..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 @@ -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); } @@ -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" }, @@ -875,7 +858,7 @@ wxString wxDateTime::GetEnglishWeekDayName(WeekDay wday, NameFlags flags) { 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" }, @@ -1630,6 +1613,7 @@ wxDateTime::Tm wxDateTime::GetTm(const TimeZone& tz) const // 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); @@ -2070,16 +2054,22 @@ 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) @@ -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