1. compilation fix for wxDir

2. wxDateTime now calculates week days (_almost_ correctly) and Format()
   seems to work too


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@5007 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 1999-12-17 01:09:10 +00:00
parent 211c225069
commit c5a1681bfe
2 changed files with 200 additions and 134 deletions

View File

@ -275,13 +275,16 @@ bool wxDateTime::Tm::IsValid() const
{
// 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 <= GetNumOfDaysInMonth(year, mon)) &&
(hour < 24) && (min < 60) && (sec < 62) && (msec < 1000);
}
void wxDateTime::Tm::ComputeWeekDay()
{
wxFAIL_MSG(_T("TODO"));
// compute the week day from day/month/year: we use the dumbest algorithm
// possible: just compute our JDN and then use the (simple to derive)
// formula: weekday = (JDN + 1.5) % 7
wday = (wxDateTime::WeekDay)(GetTruncatedJDN(mday, mon, year) + 2) % 7;
}
void wxDateTime::Tm::AddMonths(int monDiff)
@ -542,6 +545,10 @@ wxString wxDateTime::GetWeekDayName(wxDateTime::WeekDay wday, bool abbr)
// and offset it by the number of days needed to get the correct wday
tm.tm_mday += wday;
// call mktime() to normalize it...
(void)mktime(&tm);
// ... and call strftime()
return CallStrftime(abbr ? _T("%a") : _T("%A"), &tm);
}
@ -705,20 +712,33 @@ wxDateTime::Tm wxDateTime::GetTm(const TimeZone& tz) const
{
// we are working with local time
tm = localtime(&time);
// should never happen
wxCHECK_MSG( tm, Tm(), _T("gmtime() failed") );
}
else
{
time += tz.GetOffset();
if ( time >= 0 )
{
tm = gmtime(&time);
}
// should never happen
wxCHECK_MSG( tm, Tm(), _T("gmtime() failed") );
return Tm(*tm, tz);
}
else
{
tm = (struct tm *)NULL;
}
}
if ( tm )
{
return Tm(*tm, tz);
}
//else: use generic code below
}
// remember the time and do the calculations with the date only - this
// eliminates rounding errors of the floating point arithmetics
@ -798,7 +818,6 @@ wxDateTime::Tm wxDateTime::GetTm(const TimeZone& tz) const
tm.hour = timeOnly / 60;
return tm;
}
}
wxDateTime& wxDateTime::SetYear(int year)
@ -1058,37 +1077,72 @@ wxString wxDateTime::Format(const wxChar *format, const TimeZone& tz) const
{
// we are working with local time
tm = localtime(&time);
// should never happen
wxCHECK_MSG( tm, wxEmptyString, _T("localtime() failed") );
}
else
{
time += tz.GetOffset();
if ( time >= 0 )
{
tm = gmtime(&time);
}
// should never happen
wxCHECK_MSG( tm, _T(""), _T("gmtime() failed") );
return CallStrftime(format, tm);
wxCHECK_MSG( tm, wxEmptyString, _T("gmtime() failed") );
}
else
{
// use a hack and still use strftime(): make a copy of the format and
// replace all occurences of YEAR in it with some unique string not
// appearing anywhere else in it, then use strftime() to format the
// date in year YEAR and then replace YEAR back by the real year and
// the unique replacement string back with YEAR where YEAR is any year
// in the range supported by strftime() (1970 - 2037) which is equal to
// the real year modulo 28 (so the week days coincide for them)
tm = (struct tm *)NULL;
}
}
if ( tm )
{
return CallStrftime(format, tm);
}
//else: use generic code below
}
// use a hack and still use strftime(): first find the YEAR which is a year
// in the strftime() range (1970 - 2038) whose Jan 1 falls on the same week
// day as the Jan 1 of the real year. Then make a copy of the format and
// replace all occurences of YEAR in it with some unique string not
// appearing anywhere else in it, then use strftime() to format the date in
// year YEAR and then replace YEAR back by the real year and the unique
// replacement string back with YEAR. Notice that "all occurences of YEAR"
// means all occurences of 4 digit as well as 2 digit form!
// NB: may be it would be simpler to "honestly" reimplement strftime()?
// find the YEAR: normally, for any year X, Jan 1 or the year X + 28 is the
// same weekday as Jan 1 of X (because the weekday advances by 1 for each
// normal X and by 2 for each leap X, hence by 5 every 4 years or by 35
// which is 0 mod 7 every 28 years) but this rule breaks down if there are
// years between X and Y which are divisible by 4 but not leap (i.e.
// divisible by 100 but not 400), hence the correction.
// find the YEAR
int yearReal = GetYear(tz);
int year = 1970 + yearReal % 28;
wxString strYear;
strYear.Printf(_T("%d"), year);
int nCenturiesInBetween = (year / 100) - (yearReal / 100);
int nLostWeekDays = nCenturiesInBetween - (nCenturiesInBetween / 400);
// find a string not occuring in format (this is surely not optimal way
// we have to gain back the "lost" weekdays...
while ( (nLostWeekDays % 7) != 0 )
{
nLostWeekDays += year++ % 4 ? 1 : 2;
}
// at any rate, we can't go further than 1997 + 28!
wxASSERT_MSG( year < 2030, _T("logic error in wxDateTime::Format") );
wxString strYear, strYear2;
strYear.Printf(_T("%d"), year);
strYear2.Printf(_T("%d"), year % 100);
// find two strings not occuring in format (this is surely not optimal way
// of doing it... improvements welcome!)
wxString fmt = format;
wxString replacement = (wxChar)-1;
@ -1097,8 +1151,16 @@ wxString wxDateTime::Format(const wxChar *format, const TimeZone& tz) const
replacement << (wxChar)-1;
}
wxString replacement2 = (wxChar)-2;
while ( fmt.Find(replacement) != wxNOT_FOUND )
{
replacement << (wxChar)-2;
}
// replace all occurences of year with it
bool wasReplaced = fmt.Replace(strYear, replacement) > 0;
if ( !wasReplaced )
wasReplaced = fmt.Replace(strYear2, replacement2) > 0;
// use strftime() to format the same date but in supported year
wxDateTime dt(*this);
@ -1106,16 +1168,20 @@ wxString wxDateTime::Format(const wxChar *format, const TimeZone& tz) const
wxString str = dt.Format(format, tz);
// now replace the occurence of 1999 with the real year
wxString strYearReal;
strYearReal.Printf(_T("%d"), yearReal);
wxString strYearReal, strYearReal2;
strYearReal.Printf(_T("%04d"), yearReal);
strYearReal2.Printf(_T("%02d"), yearReal % 100);
str.Replace(strYear, strYearReal);
str.Replace(strYear2, strYearReal2);
// and replace back all occurences of replacement string
if ( wasReplaced )
{
str.Replace(replacement2, strYear2);
str.Replace(replacement, strYear);
}
return str;
}
}
// ============================================================================

View File

@ -149,7 +149,7 @@
static inline FIND_DATA FindFirst(const wxString& spec,
FIND_STRUCT *finddata)
{
return ::FindFirstFile(filespec, &finddata);
return ::FindFirstFile(spec, finddata);
}
static inline bool FindNext(FIND_DATA fd, FIND_STRUCT *finddata)