X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/5f287370dd4e5e89d16076958e64bd3870e3a392..f59d80ca00e0ef9963c771a26decd605a85d5596:/src/common/datetime.cpp diff --git a/src/common/datetime.cpp b/src/common/datetime.cpp index 47607ede47..8ca53f3b25 100644 --- a/src/common/datetime.cpp +++ b/src/common/datetime.cpp @@ -92,7 +92,7 @@ #endif // broken strptime() #ifndef WX_TIMEZONE - #if defined(__MINGW32__) || defined(__VISAGECPP__) + #if defined(__BORLANDC__) || defined(__MINGW32__) || defined(__VISAGECPP__) #define WX_TIMEZONE _timezone #else // unknown platform - try timezone #define WX_TIMEZONE timezone @@ -584,7 +584,6 @@ wxDateTime::Month wxDateTime::GetCurrentMonth(wxDateTime::Calendar cal) { case Gregorian: return Now().GetMonth(); - break; case Julian: wxFAIL_MSG(_T("TODO")); @@ -612,7 +611,6 @@ wxDateTime::wxDateTime_t wxDateTime::GetNumberOfDays(int year, Calendar cal) case Gregorian: case Julian: return IsLeapYear(year) ? 366 : 365; - break; default: wxFAIL_MSG(_T("unsupported calendar")); @@ -835,7 +833,8 @@ wxDateTime wxDateTime::GetBeginDST(int year, Country country) dt += wxTimeSpan::Hours(1); - dt.MakeGMT(); + // disable DST tests because it could result in an infinite recursion! + dt.MakeGMT(TRUE); } else switch ( country ) { @@ -935,7 +934,8 @@ wxDateTime wxDateTime::GetEndDST(int year, Country country) dt += wxTimeSpan::Hours(1); - dt.MakeGMT(); + // disable DST tests because it could result in an infinite recursion! + dt.MakeGMT(TRUE); } else switch ( country ) { @@ -1117,7 +1117,7 @@ wxDateTime& wxDateTime::Set(double jdn) jdn *= MILLISECONDS_PER_DAY; - m_time = jdn; + m_time.Assign(jdn); return *this; } @@ -1128,6 +1128,9 @@ wxDateTime& wxDateTime::Set(double jdn) wxDateTime::Tm wxDateTime::GetTm(const TimeZone& tz) const { +#ifdef __VMS__ + int time2; +#endif wxASSERT_MSG( IsValid(), _T("invalid wxDateTime") ); time_t time = GetTicks(); @@ -1146,7 +1149,12 @@ wxDateTime::Tm wxDateTime::GetTm(const TimeZone& tz) const else { time += tz.GetOffset(); - if ( time >= 0 ) +#ifdef __VMS__ /* time is unsigned so VMS gives a warning on the original */ + time2 = (int) time; + if ( time2 >= 0 ) +#else + if ( time >= 0 ) +#endif { tm = gmtime(&time); @@ -1499,7 +1507,7 @@ wxDateTime::wxDateTime_t wxDateTime::GetDayOfYear(const TimeZone& tz) const wxDateTime::wxDateTime_t wxDateTime::GetWeekOfYear(const TimeZone& tz) const { -#if 0 +#if 1 // the first week of the year is the one which contains Jan, 4 (according // to ISO standard rule), so the year day N0 = 4 + 7*W always lies in the // week W+1. As any day N = 7*W + 4 + (N - 4)%7, it lies in the same week @@ -1521,8 +1529,9 @@ wxDateTime::wxDateTime_t wxDateTime::GetWeekOfYear(const TimeZone& tz) const } return week; -#else // this seems to be a bit simpler and I believe is also correct - return (WeekDay)((GetDayOfYear() - (GetWeekDay() - 1 + 7) % 7 + 7) / 7); +#else // 0 + // an attempt at doing it simpler - but this doesn't quite work... + return (WeekDay)((GetDayOfYear(tz) - (GetWeekDay(tz) - 1 + 7) % 7 + 7) / 7); #endif // 0/1 } @@ -1545,7 +1554,7 @@ wxDateTime::wxDateTime_t wxDateTime::GetWeekOfMonth(const TimeZone& tz) const wxDateTime& wxDateTime::SetToYearDay(wxDateTime::wxDateTime_t yday) { int year = GetYear(); - wxCHECK_MSG( (0 < yday) && (yday < GetNumberOfDays(year)), + wxCHECK_MSG( (0 < yday) && (yday <= GetNumberOfDays(year)), ms_InvDateTime, _T("invalid year day") ); bool isLeap = IsLeapYear(year); @@ -1622,12 +1631,13 @@ int wxDateTime::IsDST(wxDateTime::Country country) const } } -wxDateTime& wxDateTime::MakeTimezone(const TimeZone& tz) +wxDateTime& wxDateTime::MakeTimezone(const TimeZone& tz, bool noDST) { int secDiff = GetTimeZone() + tz.GetOffset(); - // we need to know whether DST is or not in effect for this date - if ( IsDST() == 1 ) + // 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; @@ -1642,6 +1652,9 @@ wxDateTime& wxDateTime::MakeTimezone(const TimeZone& tz) wxString wxDateTime::Format(const wxChar *format, const TimeZone& tz) const { +#ifdef __VMS__ + int time2; +#endif wxCHECK_MSG( format, _T(""), _T("NULL format in wxDateTime::Format") ); time_t time = GetTicks(); @@ -1661,7 +1674,12 @@ wxString wxDateTime::Format(const wxChar *format, const TimeZone& tz) const { time += tz.GetOffset(); +#ifdef __VMS__ /* time is unsigned so VMS gives a warning on the original */ + time2 = (int) time; + if ( time2 >= 0 ) +#else if ( time >= 0 ) +#endif { tm = gmtime(&time); @@ -2277,7 +2295,7 @@ const wxChar *wxDateTime::ParseRfc822Date(const wxChar* date) // the spec was correct Set(day, mon, year, hour, min, sec); - MakeTimezone(60*offset); + MakeTimezone((wxDateTime_t)(60*offset)); return p; } @@ -2381,7 +2399,7 @@ const wxChar *wxDateTime::ParseFormat(const wxChar *date, // this is the format which corresponds to ctime() output // and strptime("%c") should parse it, so try it first - static const wxChar *fmtCtime = _T("%a %b %e %H:%M:%S %Y"); + static const wxChar *fmtCtime = _T("%a %b %d %H:%M:%S %Y"); const wxChar *result = dt.ParseFormat(input, fmtCtime); if ( !result ) @@ -2400,6 +2418,19 @@ const wxChar *wxDateTime::ParseFormat(const wxChar *date, return (wxChar *)NULL; } + Tm tm = dt.GetTm(); + + haveDay = haveMon = haveYear = + haveHour = haveMin = haveSec = TRUE; + + hour = tm.hour; + min = tm.min; + sec = tm.sec; + + year = tm.year; + mon = tm.mon; + mday = tm.mday; + input = result; } break; @@ -2459,7 +2490,7 @@ const wxChar *wxDateTime::ParseFormat(const wxChar *date, } haveMon = TRUE; - mon = (Month)num; + mon = (Month)(num - 1); break; case _T('M'): // minute as a decimal number (00-59) @@ -2554,6 +2585,7 @@ const wxChar *wxDateTime::ParseFormat(const wxChar *date, min = tm.min; sec = tm.sec; } + break; case _T('w'): // weekday as a number (0-6), Sunday = 0 if ( !GetNumericToken(input, &num) || (wday > 6) ) @@ -2593,18 +2625,27 @@ const wxChar *wxDateTime::ParseFormat(const wxChar *date, { wxDateTime dt; - wxString fmtDate; + wxString fmtDate, fmtDateAlt; if ( IsWestEuropeanCountry(GetCountry()) || GetCountry() == Russia ) { fmtDate = _T("%d/%m/%y"); + fmtDateAlt = _T("%m/%d/%y"); } else // assume USA { fmtDate = _T("%m/%d/%y"); + fmtDateAlt = _T("%d/%m/%y"); } const wxChar *result = dt.ParseFormat(input, fmtDate); + + if ( !result ) + { + // ok, be nice and try another one + result = dt.ParseFormat(input, fmtDateAlt); + } + if ( !result ) { // bad luck @@ -2687,14 +2728,14 @@ const wxChar *wxDateTime::ParseFormat(const wxChar *date, break; case _T('Y'): // year with century - if ( !GetNumericToken(input, &num) || !num || (num > 366) ) + if ( !GetNumericToken(input, &num) ) { // no match return (wxChar *)NULL; } - haveYDay = TRUE; - yday = (wxDateTime_t)num; + haveYear = TRUE; + year = (wxDateTime_t)num; break; case _T('Z'): // timezone name @@ -2726,7 +2767,7 @@ const wxChar *wxDateTime::ParseFormat(const wxChar *date, // take this date as default tmDef = dateDef.GetTm(); } - else if ( IsValid() ) + else if ( m_time != 0 ) { // if this date is valid, don't change it tmDef = GetTm(); @@ -2750,11 +2791,25 @@ const wxChar *wxDateTime::ParseFormat(const wxChar *date, // also always ignore the week day if ( haveMon && haveDay ) { + if ( mday > GetNumOfDaysInMonth(tm.year, mon) ) + { + wxLogDebug(_T("bad month day in wxDateTime::ParseFormat")); + + return (wxChar *)NULL; + } + tm.mon = mon; tm.mday = mday; } else if ( haveYDay ) { + if ( yday > GetNumberOfDays(tm.year) ) + { + wxLogDebug(_T("bad year day in wxDateTime::ParseFormat")); + + return (wxChar *)NULL; + } + Tm tm2 = wxDateTime(1, Jan, tm.year).SetToYearDay(yday).GetTm(); tm.mon = tm2.mon;