merged 2.2 branch

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@7748 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Bryan Petty
2000-07-15 19:51:35 +00:00
parent 8a693e6e04
commit f6bcfd974e
1835 changed files with 237729 additions and 67990 deletions

View File

@@ -78,6 +78,7 @@
#include <ctype.h>
#include "wx/datetime.h"
#include "wx/timer.h" // for wxGetLocalTimeMillis()
// ----------------------------------------------------------------------------
// conditional compilation
@@ -98,8 +99,8 @@
#if defined(__BORLANDC__) || defined(__MINGW32__) || defined(__VISAGECPP__)
#define WX_TIMEZONE _timezone
#elif defined(__MWERKS__)
long wxmw_timezone = 28800;
#define WX_TIMEZONE wxmw_timezone ;
long wxmw_timezone = 28800;
#define WX_TIMEZONE wxmw_timezone;
#else // unknown platform - try timezone
#define WX_TIMEZONE timezone
#endif
@@ -390,13 +391,17 @@ static wxDateTime::WeekDay GetWeekDayFromName(const wxString& name, int flags)
return wd;
}
// scans all digits and returns the resulting number
static bool GetNumericToken(const wxChar*& p, unsigned long *number)
// scans all digits (but no more than len) and returns the resulting number
static bool GetNumericToken(size_t len, const wxChar*& p, unsigned long *number)
{
size_t n = 1;
wxString s;
while ( wxIsdigit(*p) )
{
s += *p++;
if ( len && ++n > len )
break;
}
return !!s && s.ToULong(number);
@@ -1032,6 +1037,12 @@ wxDateTime wxDateTime::GetEndDST(int year, Country country)
// constructors and assignment operators
// ----------------------------------------------------------------------------
// return the current time with ms precision
/* static */ wxDateTime wxDateTime::UNow()
{
return wxDateTime(wxGetLocalTimeMillis());
}
// the values in the tm structure contain the local time
wxDateTime& wxDateTime::Set(const struct tm& tm)
{
@@ -1207,7 +1218,7 @@ wxDateTime::Tm wxDateTime::GetTm(const TimeZone& tz) const
tm = localtime(&time);
// should never happen
wxCHECK_MSG( tm, Tm(), _T("gmtime() failed") );
wxCHECK_MSG( tm, Tm(), _T("localtime() failed") );
}
else
{
@@ -1232,7 +1243,11 @@ wxDateTime::Tm wxDateTime::GetTm(const TimeZone& tz) const
if ( tm )
{
return Tm(*tm, tz);
// adjust the milliseconds
Tm tm2(*tm, tz);
long timeOnly = (m_time % MILLISECONDS_PER_DAY).ToLong();
tm2.msec = (wxDateTime_t)(timeOnly % 1000);
return tm2;
}
//else: use generic code below
}
@@ -1474,7 +1489,7 @@ wxDateTime& wxDateTime::SetToWeekDayInSameWeek(WeekDay weekday)
}
else if ( weekday < wdayThis )
{
return Substract(wxDateSpan::Days(wdayThis - weekday));
return Subtract(wxDateSpan::Days(wdayThis - weekday));
}
else // weekday > wdayThis
{
@@ -1527,7 +1542,7 @@ wxDateTime& wxDateTime::SetToPrevWeekDay(WeekDay weekday)
diff = wdayThis - weekday;
}
return Substract(wxDateSpan::Days(diff));
return Subtract(wxDateSpan::Days(diff));
}
bool wxDateTime::SetToWeekDay(WeekDay weekday,
@@ -1745,7 +1760,7 @@ wxDateTime& wxDateTime::MakeTimezone(const TimeZone& tz, bool noDST)
secDiff -= 3600;
}
return Substract(wxTimeSpan::Seconds(secDiff));
return Subtract(wxTimeSpan::Seconds(secDiff));
}
// ----------------------------------------------------------------------------
@@ -1756,8 +1771,10 @@ wxString wxDateTime::Format(const wxChar *format, const TimeZone& tz) const
{
wxCHECK_MSG( format, _T(""), _T("NULL format in wxDateTime::Format") );
// we have to use our own implementation if the date is out of range of
// strftime() or if we use non standard specificators
time_t time = GetTicks();
if ( time != (time_t)-1 )
if ( (time != (time_t)-1) && !wxStrstr(format, _T("%l")) )
{
// use strftime()
tm *tm;
@@ -1799,7 +1816,8 @@ wxString wxDateTime::Format(const wxChar *format, const TimeZone& tz) const
}
// we only parse ANSI C format specifications here, no POSIX 2
// complications, no GNU extensions
// complications, no GNU extensions but we do add support for a "%l" format
// specifier allowing to get the number of milliseconds
Tm tm = GetTm(tz);
// used for calls to strftime() when we only deal with time
@@ -1833,6 +1851,7 @@ wxString wxDateTime::Format(const wxChar *format, const TimeZone& tz) const
break;
case _T('j'): // day of year has 3 digits
case _T('l'): // milliseconds have 3 digits
fmt = _T("%03d");
break;
@@ -2019,6 +2038,10 @@ wxString wxDateTime::Format(const wxChar *format, const TimeZone& tz) const
res += wxString::Format(fmt, GetDayOfYear(tz));
break;
case _T('l'): // milliseconds (NOT STANDARD)
res += wxString::Format(fmt, GetMillisecond(tz));
break;
case _T('m'): // month as a number (01-12)
res += wxString::Format(fmt, tm.mon + 1);
break;
@@ -2466,7 +2489,17 @@ const wxChar *wxDateTime::ParseFormat(const wxChar *date,
}
// start of a format specification
switch ( *++fmt )
// parse the optional width
size_t width = 0;
while ( isdigit(*++fmt) )
{
width *= 10;
width += *fmt - _T('0');
}
// then the format itself
switch ( *fmt )
{
case _T('a'): // a weekday name
case _T('A'):
@@ -2539,7 +2572,8 @@ const wxChar *wxDateTime::ParseFormat(const wxChar *date,
break;
case _T('d'): // day of a month (01-31)
if ( !GetNumericToken(input, &num) || (num > 31) || (num < 1) )
if ( !GetNumericToken(width, input, &num) ||
(num > 31) || (num < 1) )
{
// no match
return (wxChar *)NULL;
@@ -2552,7 +2586,7 @@ const wxChar *wxDateTime::ParseFormat(const wxChar *date,
break;
case _T('H'): // hour in 24h format (00-23)
if ( !GetNumericToken(input, &num) || (num > 23) )
if ( !GetNumericToken(width, input, &num) || (num > 23) )
{
// no match
return (wxChar *)NULL;
@@ -2563,7 +2597,7 @@ const wxChar *wxDateTime::ParseFormat(const wxChar *date,
break;
case _T('I'): // hour in 12h format (01-12)
if ( !GetNumericToken(input, &num) || !num || (num > 12) )
if ( !GetNumericToken(width, input, &num) || !num || (num > 12) )
{
// no match
return (wxChar *)NULL;
@@ -2575,7 +2609,7 @@ const wxChar *wxDateTime::ParseFormat(const wxChar *date,
break;
case _T('j'): // day of the year
if ( !GetNumericToken(input, &num) || !num || (num > 366) )
if ( !GetNumericToken(width, input, &num) || !num || (num > 366) )
{
// no match
return (wxChar *)NULL;
@@ -2586,7 +2620,7 @@ const wxChar *wxDateTime::ParseFormat(const wxChar *date,
break;
case _T('m'): // month as a number (01-12)
if ( !GetNumericToken(input, &num) || !num || (num > 12) )
if ( !GetNumericToken(width, input, &num) || !num || (num > 12) )
{
// no match
return (wxChar *)NULL;
@@ -2597,7 +2631,7 @@ const wxChar *wxDateTime::ParseFormat(const wxChar *date,
break;
case _T('M'): // minute as a decimal number (00-59)
if ( !GetNumericToken(input, &num) || (num > 59) )
if ( !GetNumericToken(width, input, &num) || (num > 59) )
{
// no match
return (wxChar *)NULL;
@@ -2661,7 +2695,7 @@ const wxChar *wxDateTime::ParseFormat(const wxChar *date,
}
case _T('S'): // second as a decimal number (00-61)
if ( !GetNumericToken(input, &num) || (num > 61) )
if ( !GetNumericToken(width, input, &num) || (num > 61) )
{
// no match
return (wxChar *)NULL;
@@ -2691,7 +2725,7 @@ const wxChar *wxDateTime::ParseFormat(const wxChar *date,
break;
case _T('w'): // weekday as a number (0-6), Sunday = 0
if ( !GetNumericToken(input, &num) || (wday > 6) )
if ( !GetNumericToken(width, input, &num) || (wday > 6) )
{
// no match
return (wxChar *)NULL;
@@ -2820,18 +2854,21 @@ const wxChar *wxDateTime::ParseFormat(const wxChar *date,
break;
case _T('y'): // year without century (00-99)
if ( !GetNumericToken(input, &num) || (num > 99) )
if ( !GetNumericToken(width, input, &num) || (num > 99) )
{
// no match
return (wxChar *)NULL;
}
haveYear = TRUE;
year = 1900 + (wxDateTime_t)num;
// TODO should have an option for roll over date instead of
// hard coding it here
year = (num > 30 ? 1900 : 2000) + (wxDateTime_t)num;
break;
case _T('Y'): // year with century
if ( !GetNumericToken(input, &num) )
if ( !GetNumericToken(width, input, &num) )
{
// no match
return (wxChar *)NULL;
@@ -2870,7 +2907,11 @@ const wxChar *wxDateTime::ParseFormat(const wxChar *date,
// take this date as default
tmDef = dateDef.GetTm();
}
#ifdef __WIN16__
else if ( m_time != 0 )
#else
else if ( m_time != wxLongLong(0) )
#endif
{
// if this date is valid, don't change it
tmDef = GetTm();
@@ -3016,7 +3057,9 @@ const wxChar *wxDateTime::ParseDate(const wxChar *date)
int year = 0;
// tokenize the string
wxStringTokenizer tok(p, _T(",/-\t\n "));
size_t nPosCur = 0;
static const wxChar *dateDelimiters = _T(".,/-\t\n ");
wxStringTokenizer tok(p, dateDelimiters);
while ( tok.HasMoreTokens() )
{
wxString token = tok.GetNextToken();
@@ -3098,7 +3141,8 @@ const wxChar *wxDateTime::ParseDate(const wxChar *date)
haveMon = TRUE;
mon = (wxDateTime::Month)val;
// month 1 is Jan
mon = (wxDateTime::Month)(val - 1);
}
else
{
@@ -3116,7 +3160,7 @@ const wxChar *wxDateTime::ParseDate(const wxChar *date)
if ( (day <= 12) && !haveMon )
{
// exchange day and month
mon = (wxDateTime::Month)day;
mon = (wxDateTime::Month)(day - 1);
haveMon = TRUE;
}
@@ -3136,8 +3180,9 @@ const wxChar *wxDateTime::ParseDate(const wxChar *date)
}
else // not a number
{
mon = GetMonthFromName(token, Name_Full | Name_Abbr);
if ( mon != Inv_Month )
// be careful not to overwrite the current mon value
Month mon2 = GetMonthFromName(token, Name_Full | Name_Abbr);
if ( mon2 != Inv_Month )
{
// it's a month
if ( haveMon )
@@ -3145,6 +3190,8 @@ const wxChar *wxDateTime::ParseDate(const wxChar *date)
break;
}
mon = mon2;
haveMon = TRUE;
}
else
@@ -3219,19 +3266,21 @@ const wxChar *wxDateTime::ParseDate(const wxChar *date)
}
}
}
nPosCur = tok.GetPosition();
}
// either no more tokens or the scan was stopped by something we couldn't
// parse - in any case, see if we can construct a date from what we have
if ( !haveDay && !haveWDay )
{
wxLogDebug(_T("no day, no weekday hence no date."));
wxLogDebug(_T("ParseDate: no day, no weekday hence no date."));
return (wxChar *)NULL;
}
if ( haveWDay && (haveMon || haveYear || haveDay) &&
!(haveMon && haveMon && haveYear) )
!(haveDay && haveMon && haveYear) )
{
// without adjectives (which we don't support here) the week day only
// makes sense completely separately or with the full date
@@ -3239,6 +3288,37 @@ const wxChar *wxDateTime::ParseDate(const wxChar *date)
return (wxChar *)NULL;
}
if ( !haveWDay && haveYear && !(haveDay && haveMon) )
{
// may be we have month and day instead of day and year?
if ( haveDay && !haveMon )
{
if ( day <= 12 )
{
// exchange day and month
mon = (wxDateTime::Month)(day - 1);
// we're in the current year then
if ( year <= GetNumOfDaysInMonth(Inv_Year, mon) )
{
day = year;
haveMon = TRUE;
haveYear = FALSE;
}
//else: no, can't exchange, leave haveMon == FALSE
}
}
if ( !haveMon )
{
// if we give the year, month and day must be given too
wxLogDebug(_T("ParseDate: day and month should be specified if year is."));
return (wxChar *)NULL;
}
}
if ( !haveMon )
{
mon = GetCurrentMonth();
@@ -3259,6 +3339,8 @@ const wxChar *wxDateTime::ParseDate(const wxChar *date)
if ( GetWeekDay() != wday )
{
// inconsistency detected
wxLogDebug(_T("ParseDate: inconsistent day/weekday."));
return (wxChar *)NULL;
}
}
@@ -3270,8 +3352,16 @@ const wxChar *wxDateTime::ParseDate(const wxChar *date)
SetToWeekDayInSameWeek(wday);
}
// return the pointer to the next char
return p + wxStrlen(p) - wxStrlen(tok.GetString());
// return the pointer to the first unparsed char
p += nPosCur;
if ( nPosCur && wxStrchr(dateDelimiters, *(p - 1)) )
{
// if we couldn't parse the token after the delimiter, put back the
// delimiter as well
p--;
}
return p;
}
const wxChar *wxDateTime::ParseTime(const wxChar *time)
@@ -3381,46 +3471,46 @@ wxString wxTimeSpan::Format(const wxChar *format) const
wxString str;
str.Alloc(wxStrlen(format));
for ( const wxChar *pch = format; pch; pch++ )
for ( const wxChar *pch = format; *pch; pch++ )
{
wxChar ch = *pch;
if ( ch == '%' )
if ( ch == _T('%') )
{
wxString tmp;
ch = *pch++;
ch = *++pch; // get the format spec char
switch ( ch )
{
default:
wxFAIL_MSG( _T("invalid format character") );
// fall through
case '%':
case _T('%'):
// will get to str << ch below
break;
case 'D':
case _T('D'):
tmp.Printf(_T("%d"), GetDays());
break;
case 'E':
case _T('E'):
tmp.Printf(_T("%d"), GetWeeks());
break;
case 'H':
case _T('H'):
tmp.Printf(_T("%02d"), GetHours());
break;
case 'l':
case _T('l'):
tmp.Printf(_T("%03ld"), GetMilliseconds().ToLong());
break;
case 'M':
case _T('M'):
tmp.Printf(_T("%02d"), GetMinutes());
break;
case 'S':
case _T('S'):
tmp.Printf(_T("%02ld"), GetSeconds().ToLong());
break;
}
@@ -3446,7 +3536,7 @@ wxString wxTimeSpan::Format(const wxChar *format) const
#include "wx/arrimpl.cpp"
WX_DEFINE_OBJARRAY(wxDateTimeArray)
WX_DEFINE_OBJARRAY(wxDateTimeArray);
static int wxCMPFUNC_CONV
wxDateTimeCompareFunc(wxDateTime **first, wxDateTime **second)