wxDateTime starting to work, more tests for it and for threads in console sample

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@4779 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
1999-11-30 21:55:00 +00:00
parent ec96574fbd
commit 2f02cb8966
7 changed files with 690 additions and 353 deletions

View File

@@ -105,7 +105,9 @@ threads).
Delete() may be called for thread in any state: running, paused or even not yet created. Moreover,
it must be called if \helpref{Create}{wxthreadcreate} or \helpref{Run}{wxthreadrun} fail to free
the memory occupied by the thread object.
the memory occupied by the thread object. However, you should not call Delete()
on a detached thread which already terminated - doing so will probably result
in a crash because the thread object doesn't exist any more.
For detached threads Delete() will also delete the C++ thread object, but it
will not do this for joinable ones.

View File

@@ -10,8 +10,8 @@
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
#ifndef _WX_TIME_H
#define _WX_TIME_H
#ifndef _WX_DATETIME_H
#define _WX_DATETIME_H
#ifdef __GNUG__
#pragma interface "datetime.h"
@@ -26,6 +26,14 @@ class WXDLLEXPORT wxDateTime;
class WXDLLEXPORT wxTimeSpan;
class WXDLLEXPORT wxDateSpan;
// don't use inline functions in debug builds - we don't care about
// performances and this only leads to increased rebuild time (because every
// time an inline method is changed, all files including the header must be
// rebuilt)
#ifdef __WXDEBUG__
#define inline
#endif // Debug
/*
* TODO Well, everything :-)
*
@@ -350,7 +358,10 @@ public:
static Month GetCurrentMonth(Calendar cal = Gregorian);
// returns TRUE if the given year is a leap year in the given calendar
static bool IsLeapYear(int year, Calendar cal = Gregorian);
static bool IsLeapYear(int year = Inv_Year, Calendar cal = Gregorian);
// get the century (19 for 1999, 20 for 2000 and -5 for 492 BC)
static int GetCentury(int year = Inv_Year);
// returns the number of days in this year (356 or 355 for Gregorian
// calendar usually :-)
@@ -493,12 +504,12 @@ public:
// of the month (see helper function SetToLastWeekDay())
bool SetToWeekDay(WeekDay weekday,
int n = 1,
wxDateTime_t month = Inv_Month,
Month month = Inv_Month,
int year = Inv_Year);
// sets to the last weekday in the given month, year
inline bool SetToLastWeekDay(WeekDay weekday,
wxDateTime_t month = Inv_Month,
Month month = Inv_Month,
int year = Inv_Year);
// sets the date to the given day of the given week in the year,
@@ -506,8 +517,10 @@ public:
// numWeek is > 53)
bool SetToTheWeek(wxDateTime_t numWeek, WeekDay weekday = Mon);
// get the century (19 for 1999, 20 for 2000 and -5 for 492 BC)
int GetCentury() const;
// sets the date to the last day of the given (or current) month or the
// given (or current) year
wxDateTime& SetToLastMonthDay(Month month = Inv_Month,
int year = Inv_Year);
// The definitions below were taken verbatim from
//
@@ -582,7 +595,7 @@ public:
// get the month day (in 1..31 range, 0 if date is invalid)
wxDateTime_t GetDay() const { return GetTm().mday; }
// get the day of the week (Inv_WeekDay if date is invalid)
WeekDay GetDayOfWeek() const { return GetTm().GetWeekDay(); }
WeekDay GetWeekDay() const { return GetTm().GetWeekDay(); }
// get the hour of the day
wxDateTime_t GetHour() const { return GetTm().hour; }
// get the minute
@@ -701,10 +714,17 @@ public:
// get the internal representation
inline wxLongLong GetValue() const;
private:
// a helper function to get the current time_t
static inline time_t GetTimeNow() { return time((time_t *)NULL); }
static time_t GetTimeNow() { return time((time_t *)NULL); }
// another one to get the current time broken down
static struct tm *GetTmNow()
{
time_t t = GetTimeNow();
return localtime(&t);
}
private:
// the current country - as it's the same for all program objects (unless
// it runs on a _really_ big cluster system :-), this is a static member:
// see SetCountry() and GetCountry()
@@ -907,7 +927,25 @@ public:
// ------------------------------------------------------------------------
// this many years/months/weeks/days
wxDateSpan(int years, int months, int weeks, int days);
wxDateSpan(int years = 0, int months = 0, int weeks = 0, int days = 0)
{
m_years = years;
m_months = months;
m_weeks = weeks;
m_days = days;
}
// get an object for the given number of days
static wxDateSpan Days(int days) { return wxDateSpan(0, 0, 0, days); }
// get an object for the given number of weeks
static wxDateSpan Weeks(int weeks) { return wxDateSpan(0, 0, weeks, 0); }
// get an object for the given number of months
static wxDateSpan Months(int mon) { return wxDateSpan(0, mon, 0, 0); }
// get an object for the given number of years
static wxDateSpan Years(int years) { return wxDateSpan(years, 0, 0, 0); }
// default copy ctor is ok
@@ -971,6 +1009,23 @@ WXDLLEXPORT_DATA(extern wxDateSpan) wxMonth;
WXDLLEXPORT_DATA(extern wxDateSpan) wxWeek;
WXDLLEXPORT_DATA(extern wxDateSpan) wxDay;
// ============================================================================
// inline functions implementation
// ============================================================================
// don't include inline functions definitions when we're included from anything
// else than datetime.cpp in debug builds: this minimizes rebuilds if we change
// some inline function and the performance doesn't matter in the debug builds.
#if !defined(__WXDEBUG__) || defined(wxDEFINE_TIME_CONSTANTS)
#define INCLUDED_FROM_WX_DATETIME_H
#include "wx/datetime.inl"
#undef INCLUDED_FROM_WX_DATETIME_H
#endif
// if we defined it to be empty above, restore it now
#undef inline
// ============================================================================
// binary operators
// ============================================================================
@@ -1088,315 +1143,4 @@ inline WXDLLEXPORT wxDateSpan operator+(const wxDateSpan& rt1,
rt1.GetDays() + rt2.GetDays());
}
// ============================================================================
// inline functions implementation
// ============================================================================
// ----------------------------------------------------------------------------
// wxDateTime statics
// ----------------------------------------------------------------------------
/* static */
wxDateTime::Country wxDateTime::GetCountry()
{
return ms_country;
}
// ----------------------------------------------------------------------------
// wxDateTime construction
// ----------------------------------------------------------------------------
// only define this once, when included from datetime.cpp
#ifdef wxDEFINE_TIME_CONSTANTS
const unsigned int wxDateTime::TIME_T_FACTOR = 1000;
#endif // wxDEFINE_TIME_CONSTANTS
wxDateTime::IsInStdRange() const
{
return m_time >= 0l && (m_time / (long)TIME_T_FACTOR) < LONG_MAX;
}
/* static */
wxDateTime wxDateTime::Now()
{
return wxDateTime(GetTimeNow());
}
wxDateTime& wxDateTime::Set(time_t timet)
{
m_time = timet * TIME_T_FACTOR;
return *this;
}
wxDateTime& wxDateTime::SetToCurrent()
{
return Set(GetTimeNow());
}
wxDateTime::wxDateTime(time_t timet)
{
Set(timet);
}
wxDateTime::wxDateTime(const struct tm& tm)
{
Set(tm);
}
wxDateTime::wxDateTime(const Tm& tm)
{
Set(tm);
}
wxDateTime& wxDateTime::Set(const Tm& tm)
{
wxASSERT_MSG( tm.IsValid(), _T("invalid broken down date/time") );
return Set(tm.mday, (Month)tm.mon, tm.year, tm.hour, tm.min, tm.sec);
}
wxDateTime::wxDateTime(wxDateTime_t hour,
wxDateTime_t minute,
wxDateTime_t second,
wxDateTime_t millisec)
{
Set(hour, minute, second, millisec);
}
wxDateTime::wxDateTime(wxDateTime_t day,
Month month,
int year,
wxDateTime_t hour,
wxDateTime_t minute,
wxDateTime_t second,
wxDateTime_t millisec)
{
Set(day, month, year, hour, minute, second, millisec);
}
// ----------------------------------------------------------------------------
// wxDateTime accessors
// ----------------------------------------------------------------------------
wxLongLong wxDateTime::GetValue() const
{
wxASSERT_MSG( IsValid(), "invalid wxDateTime");
return m_time;
}
time_t wxDateTime::GetTicks() const
{
wxASSERT_MSG( IsValid(), "invalid wxDateTime");
if ( !IsInStdRange() )
{
return (time_t)-1;
}
return (time_t)((m_time / (long)TIME_T_FACTOR).GetLo());
}
bool wxDateTime::SetToLastWeekDay(WeekDay weekday,
wxDateTime_t month,
int year)
{
SetToWeekDay(weekday, -1, month, year);
}
// ----------------------------------------------------------------------------
// wxDateTime comparison
// ----------------------------------------------------------------------------
bool wxDateTime::IsEqualTo(const wxDateTime& datetime) const
{
wxASSERT_MSG( IsValid() && datetime.IsValid(), "invalid wxDateTime");
return m_time == datetime.m_time;
}
bool wxDateTime::operator==(const wxDateTime& datetime) const
{
return IsEqualTo(datetime);
}
bool wxDateTime::operator!=(const wxDateTime& datetime) const
{
return !IsEqualTo(datetime);
}
bool wxDateTime::IsEarlierThan(const wxDateTime& datetime) const
{
wxASSERT_MSG( IsValid() && datetime.IsValid(), "invalid wxDateTime");
return m_time < datetime.m_time;
}
bool wxDateTime::IsLaterThan(const wxDateTime& datetime) const
{
wxASSERT_MSG( IsValid() && datetime.IsValid(), "invalid wxDateTime");
return m_time > datetime.m_time;
}
bool wxDateTime::IsStrictlyBetween(const wxDateTime& t1,
const wxDateTime& t2) const
{
// no need for assert, will be checked by the functions we call
return IsLaterThan(t1) && IsEarlierThan(t2);
}
bool wxDateTime::IsBetween(const wxDateTime& t1, const wxDateTime& t2) const
{
// no need for assert, will be checked by the functions we call
return IsEqualTo(t1) || IsEqualTo(t2) || IsStrictlyBetween(t1, t2);
}
// ----------------------------------------------------------------------------
// wxDateTime arithmetics
// ----------------------------------------------------------------------------
wxDateTime& wxDateTime::Add(const wxTimeSpan& diff)
{
wxASSERT_MSG( IsValid(), "invalid wxDateTime");
m_time += diff.GetValue();
return *this;
}
wxDateTime& wxDateTime::operator+=(const wxTimeSpan& diff)
{
return Add(diff);
}
wxDateTime& wxDateTime::Substract(const wxTimeSpan& diff)
{
wxASSERT_MSG( IsValid(), "invalid wxDateTime");
m_time -= diff.GetValue();
return *this;
}
wxDateTime& wxDateTime::operator-=(const wxTimeSpan& diff)
{
return Substract(diff);
}
wxTimeSpan wxDateTime::Substract(const wxDateTime& datetime) const
{
wxASSERT_MSG( IsValid() && datetime.IsValid(), "invalid wxDateTime");
return wxTimeSpan(datetime.GetValue() - GetValue());
}
wxTimeSpan wxDateTime::operator-(const wxDateTime& datetime) const
{
return Substract(datetime);
}
wxDateTime& wxDateTime::Substract(const wxDateSpan& diff)
{
return Add(diff.Negate());
}
wxDateTime& wxDateTime::operator-=(const wxDateSpan& diff)
{
return Substract(diff);
}
wxDateTime& wxDateTime::operator+=(const wxDateSpan& diff)
{
return Add(diff);
}
// ----------------------------------------------------------------------------
// wxTimeSpan
// ----------------------------------------------------------------------------
wxTimeSpan& wxTimeSpan::Add(const wxTimeSpan& diff)
{
m_diff += diff.GetValue();
return *this;
}
wxTimeSpan& wxTimeSpan::Substract(const wxTimeSpan& diff)
{
m_diff -= diff.GetValue();
return *this;
}
wxTimeSpan& wxTimeSpan::Multiply(int n)
{
m_diff *= n;
return *this;
}
wxTimeSpan wxTimeSpan::operator*(int n) const
{
wxTimeSpan result(*this);
result.Multiply(n);
return result;
}
wxTimeSpan wxTimeSpan::Abs() const
{
return wxTimeSpan(GetValue().Abs());
}
bool wxTimeSpan::IsEqualTo(const wxTimeSpan& ts) const
{
return GetValue() == ts.GetValue();
}
bool wxTimeSpan::IsLongerThan(const wxTimeSpan& ts) const
{
return Abs() > ts.Abs();
}
// ----------------------------------------------------------------------------
// wxDateSpan
// ----------------------------------------------------------------------------
wxDateSpan&
wxDateSpan::operator+=(const wxDateSpan& other)
{
m_years += other.m_years;
m_months += other.m_months;
m_weeks += other.m_weeks;
m_days += other.m_days;
return *this;
}
wxDateSpan& wxDateSpan::operator*=(int factor)
{
m_years *= m_years;
m_months *= m_months;
m_weeks *= m_weeks;
m_days *= m_days;
return *this;
}
wxDateSpan wxDateSpan::Negate() const
{
return wxDateSpan(-m_years, -m_months, -m_weeks, -m_days);
}
wxDateSpan& wxDateSpan::Neg()
{
m_years = -m_years;
m_months = -m_months;
m_weeks = -m_weeks;
m_days = -m_days;
return *this;
}
#endif // _WX_TIME_H
#endif // _WX_DATETIME_H

328
include/wx/datetime.inl Normal file
View File

@@ -0,0 +1,328 @@
/////////////////////////////////////////////////////////////////////////////
// Name: wx/datetime.inl
// Purpose: definition of inline functions of wxDateTime and related
// classes declared in datetime.h
// Author: Vadim Zeitlin
// Remarks: having the inline functions here allows us to minimize the
// dependencies (and hence the rebuild time) in debug builds.
// Modified by:
// Created: 30.11.99
// RCS-ID: $Id$
// Copyright: (c) 1999 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_FROM_WX_DATETIME_H
#error "This file is only included by wx/datetime.h, don't include it manually!"
#endif
// ----------------------------------------------------------------------------
// wxDateTime statics
// ----------------------------------------------------------------------------
/* static */
wxDateTime::Country wxDateTime::GetCountry()
{
return ms_country;
}
// ----------------------------------------------------------------------------
// wxDateTime construction
// ----------------------------------------------------------------------------
// only define this once, when included from datetime.cpp
#ifdef wxDEFINE_TIME_CONSTANTS
const unsigned int wxDateTime::TIME_T_FACTOR = 1000;
#endif // wxDEFINE_TIME_CONSTANTS
wxDateTime::IsInStdRange() const
{
return m_time >= 0l && (m_time / (long)TIME_T_FACTOR) < LONG_MAX;
}
/* static */
wxDateTime wxDateTime::Now()
{
return wxDateTime(GetTimeNow());
}
wxDateTime& wxDateTime::Set(time_t timet)
{
// assign first to avoid long multiplication overflow!
m_time = timet;
m_time *= TIME_T_FACTOR;
return *this;
}
wxDateTime& wxDateTime::SetToCurrent()
{
return Set(GetTimeNow());
}
wxDateTime::wxDateTime(time_t timet)
{
Set(timet);
}
wxDateTime::wxDateTime(const struct tm& tm)
{
Set(tm);
}
wxDateTime::wxDateTime(const Tm& tm)
{
Set(tm);
}
wxDateTime& wxDateTime::Set(const Tm& tm)
{
wxASSERT_MSG( tm.IsValid(), _T("invalid broken down date/time") );
return Set(tm.mday, (Month)tm.mon, tm.year, tm.hour, tm.min, tm.sec);
}
wxDateTime::wxDateTime(wxDateTime_t hour,
wxDateTime_t minute,
wxDateTime_t second,
wxDateTime_t millisec)
{
Set(hour, minute, second, millisec);
}
wxDateTime::wxDateTime(wxDateTime_t day,
Month month,
int year,
wxDateTime_t hour,
wxDateTime_t minute,
wxDateTime_t second,
wxDateTime_t millisec)
{
Set(day, month, year, hour, minute, second, millisec);
}
// ----------------------------------------------------------------------------
// wxDateTime accessors
// ----------------------------------------------------------------------------
wxLongLong wxDateTime::GetValue() const
{
wxASSERT_MSG( IsValid(), "invalid wxDateTime");
return m_time;
}
time_t wxDateTime::GetTicks() const
{
wxASSERT_MSG( IsValid(), "invalid wxDateTime");
if ( !IsInStdRange() )
{
return (time_t)-1;
}
return (time_t)((m_time / (long)TIME_T_FACTOR).GetLo());
}
bool wxDateTime::SetToLastWeekDay(WeekDay weekday,
Month month,
int year)
{
return SetToWeekDay(weekday, -1, month, year);
}
// ----------------------------------------------------------------------------
// wxDateTime comparison
// ----------------------------------------------------------------------------
bool wxDateTime::IsEqualTo(const wxDateTime& datetime) const
{
wxASSERT_MSG( IsValid() && datetime.IsValid(), "invalid wxDateTime");
return m_time == datetime.m_time;
}
bool wxDateTime::operator==(const wxDateTime& datetime) const
{
return IsEqualTo(datetime);
}
bool wxDateTime::operator!=(const wxDateTime& datetime) const
{
return !IsEqualTo(datetime);
}
bool wxDateTime::IsEarlierThan(const wxDateTime& datetime) const
{
wxASSERT_MSG( IsValid() && datetime.IsValid(), "invalid wxDateTime");
return m_time < datetime.m_time;
}
bool wxDateTime::IsLaterThan(const wxDateTime& datetime) const
{
wxASSERT_MSG( IsValid() && datetime.IsValid(), "invalid wxDateTime");
return m_time > datetime.m_time;
}
bool wxDateTime::IsStrictlyBetween(const wxDateTime& t1,
const wxDateTime& t2) const
{
// no need for assert, will be checked by the functions we call
return IsLaterThan(t1) && IsEarlierThan(t2);
}
bool wxDateTime::IsBetween(const wxDateTime& t1, const wxDateTime& t2) const
{
// no need for assert, will be checked by the functions we call
return IsEqualTo(t1) || IsEqualTo(t2) || IsStrictlyBetween(t1, t2);
}
// ----------------------------------------------------------------------------
// wxDateTime arithmetics
// ----------------------------------------------------------------------------
wxDateTime& wxDateTime::Add(const wxTimeSpan& diff)
{
wxASSERT_MSG( IsValid(), "invalid wxDateTime");
m_time += diff.GetValue();
return *this;
}
wxDateTime& wxDateTime::operator+=(const wxTimeSpan& diff)
{
return Add(diff);
}
wxDateTime& wxDateTime::Substract(const wxTimeSpan& diff)
{
wxASSERT_MSG( IsValid(), "invalid wxDateTime");
m_time -= diff.GetValue();
return *this;
}
wxDateTime& wxDateTime::operator-=(const wxTimeSpan& diff)
{
return Substract(diff);
}
wxTimeSpan wxDateTime::Substract(const wxDateTime& datetime) const
{
wxASSERT_MSG( IsValid() && datetime.IsValid(), "invalid wxDateTime");
return wxTimeSpan(datetime.GetValue() - GetValue());
}
wxTimeSpan wxDateTime::operator-(const wxDateTime& datetime) const
{
return Substract(datetime);
}
wxDateTime& wxDateTime::Substract(const wxDateSpan& diff)
{
return Add(diff.Negate());
}
wxDateTime& wxDateTime::operator-=(const wxDateSpan& diff)
{
return Substract(diff);
}
wxDateTime& wxDateTime::operator+=(const wxDateSpan& diff)
{
return Add(diff);
}
// ----------------------------------------------------------------------------
// wxTimeSpan
// ----------------------------------------------------------------------------
wxTimeSpan& wxTimeSpan::Add(const wxTimeSpan& diff)
{
m_diff += diff.GetValue();
return *this;
}
wxTimeSpan& wxTimeSpan::Substract(const wxTimeSpan& diff)
{
m_diff -= diff.GetValue();
return *this;
}
wxTimeSpan& wxTimeSpan::Multiply(int n)
{
m_diff *= n;
return *this;
}
wxTimeSpan wxTimeSpan::operator*(int n) const
{
wxTimeSpan result(*this);
result.Multiply(n);
return result;
}
wxTimeSpan wxTimeSpan::Abs() const
{
return wxTimeSpan(GetValue().Abs());
}
bool wxTimeSpan::IsEqualTo(const wxTimeSpan& ts) const
{
return GetValue() == ts.GetValue();
}
bool wxTimeSpan::IsLongerThan(const wxTimeSpan& ts) const
{
return GetValue().Abs() > ts.GetValue().Abs();
}
// ----------------------------------------------------------------------------
// wxDateSpan
// ----------------------------------------------------------------------------
wxDateSpan&
wxDateSpan::operator+=(const wxDateSpan& other)
{
m_years += other.m_years;
m_months += other.m_months;
m_weeks += other.m_weeks;
m_days += other.m_days;
return *this;
}
wxDateSpan& wxDateSpan::operator*=(int factor)
{
m_years *= m_years;
m_months *= m_months;
m_weeks *= m_weeks;
m_days *= m_days;
return *this;
}
wxDateSpan wxDateSpan::Negate() const
{
return wxDateSpan(-m_years, -m_months, -m_weeks, -m_days);
}
wxDateSpan& wxDateSpan::Neg()
{
m_years = -m_years;
m_months = -m_months;
m_weeks = -m_weeks;
m_days = -m_days;
return *this;
}

View File

@@ -24,11 +24,12 @@
// ----------------------------------------------------------------------------
// to avoid compilation problems on 64bit machines with ambiguous method calls
// we will need this
// we will need to define this
#undef wxLongLongIsLong
// NB: we #define and not typedef wxLongLong_t because we want to be able to
// use 'unsigned wxLongLong_t' as well
// use 'unsigned wxLongLong_t' as well and because we use "#ifdef
// wxLongLong_t" below
#if defined(SIZEOF_LONG) && (SIZEOF_LONG == 8)
#define wxLongLong_t long
#define wxLongLongIsLong
@@ -98,7 +99,7 @@ public:
m_ll |= (wxLongLong_t) lo;
}
// default copy ctor is ok in both cases
// default copy ctor is ok
// no dtor
@@ -112,10 +113,10 @@ public:
// accessors
// get high part
long GetHi() const
{ return (long)((m_ll & 0xFFFFFFFF00000000l) >> 32); }
{ return (long)(m_ll >> 32); }
// get low part
unsigned long GetLo() const
{ return (unsigned long) (m_ll & 0x00000000FFFFFFFFl); }
{ return (unsigned long)m_ll; }
// get absolute value
wxLongLongNative& Abs() { if ( m_ll < 0 ) m_ll = -m_ll; return *this; }
@@ -123,6 +124,8 @@ public:
// convert to native long long
wxLongLong_t GetValue() const { return m_ll; }
// don't provide implicit conversion to wxLongLong_t or we will have an
// ambiguity for all arithmetic operations
//operator wxLongLong_t() const { return m_ll; }
// operations
@@ -200,8 +203,12 @@ public:
// multiplication/division
wxLongLongNative operator*(const wxLongLongNative& ll) const
{ return wxLongLongNative(m_ll * ll.m_ll); }
wxLongLongNative operator*(long l) const
{ return wxLongLongNative(m_ll * l); }
wxLongLongNative& operator*=(const wxLongLongNative& ll)
{ m_ll *= ll.m_ll; return *this; }
wxLongLongNative& operator*=(long l)
{ m_ll *= l; return *this; }
wxLongLongNative operator/(const wxLongLongNative& ll) const
{ return wxLongLongNative(m_ll / ll.m_ll); }
@@ -209,6 +216,8 @@ public:
{ return wxLongLongNative(m_ll / l); }
wxLongLongNative& operator/=(const wxLongLongNative& ll)
{ m_ll /= ll.m_ll; return *this; }
wxLongLongNative& operator/=(long l)
{ m_ll /= l; return *this; }
wxLongLongNative operator%(const wxLongLongNative& ll) const
{ return wxLongLongNative(m_ll % ll.m_ll); }

View File

@@ -32,8 +32,8 @@
//#define TEST_ARRAYS
//#define TEST_LOG
//#define TEST_STRINGS
#define TEST_THREADS
//#define TEST_TIME
//#define TEST_THREADS
#define TEST_TIME
//#define TEST_LONGLONG
// ============================================================================
@@ -93,9 +93,26 @@ static void TestSpeed()
static void TestDivision()
{
wxLongLong ll = 0x38417388; // some number < LONG_MAX
#define MAKE_LL(x1, x2, x3, x4) wxLongLong((x1 << 16) | x2, (x3 << 16) | x3)
wxASSERT( (ll / 1000l)*1000l == ll );
// seed pseudo random generator
//srand((unsigned)time(NULL));
size_t nTested = 0;
for ( size_t n = 0; n < 10000; n++ )
{
// get a random wxLongLong (shifting by 12 the MSB ensures that the
// multiplication will not overflow)
wxLongLong ll = MAKE_LL((rand() >> 12), rand(), rand(), rand());
wxASSERT( (ll * 1000l)/1000l == ll );
nTested++;
}
printf("\n*** Tested %u divisions/multiplications: ok\n", nTested);
#undef MAKE_LL
}
#endif // TEST_LONGLONG
@@ -108,6 +125,60 @@ static void TestDivision()
#include <wx/datetime.h>
// this test miscellaneous static wxDateTime functions
static void TestTimeStatic()
{
puts("\n*** wxDateTime static methods test ***");
// some info about the current date
int year = wxDateTime::GetCurrentYear();
printf("Current year %d is %sa leap one and has %d days.\n",
year,
wxDateTime::IsLeapYear(year) ? "" : "not ",
wxDateTime::GetNumberOfDays(year));
wxDateTime::Month month = wxDateTime::GetCurrentMonth();
printf("Current month is '%s' ('%s') and it has %d days\n",
wxDateTime::GetMonthName(month, TRUE).c_str(),
wxDateTime::GetMonthName(month).c_str(),
wxDateTime::GetNumberOfDays(month));
// leap year logic
static const nYears = 5;
static const int years[2][nYears] =
{
// first line: the years to test
{ 1990, 1976, 2000, 2030, 1984, },
// second line: TRUE if leap, FALSE otherwise
{ FALSE, TRUE, TRUE, FALSE, TRUE }
};
for ( size_t n = 0; n < nYears; n++ )
{
int year = years[0][n];
bool should = years[1][n] != 0;
printf("Year %d is %sa leap year (should be: %s)\n",
year,
wxDateTime::IsLeapYear(year) ? "" : "not ",
should ? "yes" : "no");
wxASSERT( should == wxDateTime::IsLeapYear(year) );
}
}
// test constructing wxDateTime objects
static void TestTimeSet()
{
puts("\n*** wxDateTime construction test ***");
printf("Current time:\t%s\n", wxDateTime::Now().Format().c_str());
printf("Unix epoch:\t%s\n", wxDateTime((time_t)0).Format().c_str());
printf("Today noon:\t%s\n", wxDateTime(12, 0).Format().c_str());
printf("May 29, 1976:\t%s\n", wxDateTime(29, wxDateTime::May, 1976).Format().c_str());
}
#endif // TEST_TIME
// ----------------------------------------------------------------------------
@@ -200,7 +271,7 @@ void MyDetachedThread::OnExit()
void TestDetachedThreads()
{
puts("*** Testing detached threads ***");
puts("\n*** Testing detached threads ***");
static const size_t nThreads = 3;
MyDetachedThread *threads[nThreads];
@@ -226,7 +297,7 @@ void TestDetachedThreads()
void TestJoinableThreads()
{
puts("*** Testing a joinable thread (a loooong calculation...) ***");
puts("\n*** Testing a joinable thread (a loooong calculation...) ***");
// calc 10! in the background
MyJoinableThread thread(10);
@@ -238,7 +309,9 @@ void TestJoinableThreads()
void TestThreadSuspend()
{
MyDetachedThread *thread = new MyDetachedThread(30, 'X');
puts("\n*** Testing thread suspend/resume functions ***");
MyDetachedThread *thread = new MyDetachedThread(15, 'X');
thread->Run();
@@ -271,6 +344,56 @@ void TestThreadSuspend()
puts("");
}
void TestThreadDelete()
{
// As above, using Sleep() is only for testing here - we must use some
// synchronisation object instead to ensure that the thread is still
// running when we delete it - deleting a detached thread which already
// terminated will lead to a crash!
puts("\n*** Testing thread delete function ***");
MyDetachedThread *thread1 = new MyDetachedThread(30, 'Y');
thread1->Run();
wxThread::Sleep(300);
thread1->Delete();
puts("\nDeleted a running thread.");
MyDetachedThread *thread2 = new MyDetachedThread(30, 'Z');
thread2->Run();
wxThread::Sleep(300);
thread2->Pause();
thread2->Delete();
puts("\nDeleted a sleeping thread.");
MyJoinableThread *thread3 = new MyJoinableThread(20);
thread3->Run();
thread3->Delete();
puts("\nDeleted a joinable thread.");
MyJoinableThread *thread4 = new MyJoinableThread(2);
thread4->Run();
wxThread::Sleep(300);
thread4->Delete();
puts("\nDeleted a joinable thread which already terminated.");
puts("");
}
#endif // TEST_THREADS
// ----------------------------------------------------------------------------
@@ -421,12 +544,15 @@ int main(int argc, char **argv)
if ( argc > 1 && argv[1][0] == 't' )
wxLog::AddTraceMask("thread");
TestThreadSuspend();
if ( 0 )
{
TestDetachedThreads();
if ( 0 )
TestJoinableThreads();
}
if ( 0 )
TestThreadSuspend();
if ( 1 )
TestThreadDelete();
#endif // TEST_THREADS
#ifdef TEST_LONGLONG
@@ -437,11 +563,8 @@ int main(int argc, char **argv)
#endif // TEST_LONGLONG
#ifdef TEST_TIME
wxDateTime time = wxDateTime::Now();
printf("Current time: '%s', current year %u is %sa leap one",
time.Format().c_str(),
time.GetYear(),
wxDateTime::IsLeapYear(time.GetYear()) ? "" : "not");
TestTimeStatic();
TestTimeSet();
#endif // TEST_TIME
wxUninitialize();

View File

@@ -54,6 +54,7 @@ static wxDateTime::wxDateTime_t gs_daysInMonth[2][12] =
// private functions
// ----------------------------------------------------------------------------
// this function is a wrapper around strftime(3)
static wxString CallStrftime(const wxChar *format, const tm* tm)
{
wxChar buf[1024];
@@ -66,6 +67,28 @@ static wxString CallStrftime(const wxChar *format, const tm* tm)
return wxString(buf);
}
// if year and/or month have invalid values, replace them with the current ones
static void ReplaceDefaultYearMonthWithCurrent(int *year,
wxDateTime::Month *month)
{
struct tm *tmNow = NULL;
if ( *year == wxDateTime::Inv_Year )
{
tmNow = wxDateTime::GetTmNow();
*year = 1900 + tmNow->tm_year;
}
if ( *month == wxDateTime::Inv_Month )
{
if ( !tmNow )
tmNow = wxDateTime::GetTmNow();
*month = (wxDateTime::Month)tmNow->tm_mon;
}
}
// ============================================================================
// implementation of wxDateTime
// ============================================================================
@@ -122,6 +145,9 @@ void wxDateTime::Tm::ComputeWeekDay()
/* static */
bool wxDateTime::IsLeapYear(int year, wxDateTime::Calendar cal)
{
if ( year == Inv_Year )
year = GetCurrentYear();
if ( cal == Gregorian )
{
// in Gregorian calendar leap years are those divisible by 4 except
@@ -197,6 +223,30 @@ wxDateTime::Month wxDateTime::GetCurrentMonth(wxDateTime::Calendar cal)
return Inv_Month;
}
/* static */
wxDateTime::wxDateTime_t wxDateTime::GetNumberOfDays(int year, Calendar cal)
{
if ( year == Inv_Year )
{
// take the current year if none given
year = GetCurrentYear();
}
switch ( cal )
{
case Gregorian:
case Julian:
return IsLeapYear(year) ? 366 : 365;
break;
default:
wxFAIL_MSG(_T("unsupported calendar"));
break;
}
return 0;
}
/* static */
wxDateTime::wxDateTime_t wxDateTime::GetNumberOfDays(wxDateTime::Month month,
int year,
@@ -310,12 +360,9 @@ wxDateTime& wxDateTime::Set(wxDateTime_t day,
ms_InvDateTime,
_T("Invalid time in wxDateTime::Set()") );
if ( year == Inv_Year )
year = GetCurrentYear();
if ( month == Inv_Month )
month = GetCurrentMonth();
ReplaceDefaultYearMonthWithCurrent(&year, &month);
wxCHECK_MSG( day < GetNumberOfDays(month, year), ms_InvDateTime,
wxCHECK_MSG( day <= GetNumberOfDays(month, year), ms_InvDateTime,
_T("Invalid date in wxDateTime::Set()") );
// the range of time_t type (inclusive)
@@ -324,7 +371,7 @@ wxDateTime& wxDateTime::Set(wxDateTime_t day,
// test only the year instead of testing for the exact end of the Unix
// time_t range - it doesn't bring anything to do more precise checks
if ( year >= yearMaxInRange && year <= yearMaxInRange )
if ( year >= yearMinInRange && year <= yearMaxInRange )
{
// use the standard library version if the date is in range - this is
// probably more efficient than our code
@@ -473,6 +520,87 @@ wxDateTime& wxDateTime::Add(const wxDateSpan& diff)
return *this;
}
// ----------------------------------------------------------------------------
// Weekday and monthday stuff
// ----------------------------------------------------------------------------
wxDateTime& wxDateTime::SetToLastMonthDay(Month month,
int year)
{
// take the current month/year if none specified
ReplaceDefaultYearMonthWithCurrent(&year, &month);
return Set(gs_daysInMonth[IsLeapYear(year)][month], month, year);
}
bool wxDateTime::SetToWeekDay(WeekDay weekday,
int n,
Month month,
int year)
{
wxCHECK_MSG( weekday != Inv_WeekDay, FALSE, _T("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?
// take the current month/year if none specified
ReplaceDefaultYearMonthWithCurrent(&year, &month);
wxDateTime dt;
// TODO this probably could be optimised somehow...
if ( n > 0 )
{
// get the first day of the month
dt.Set(1, month, year);
// get its wday
WeekDay wdayFirst = dt.GetWeekDay();
// go to the first weekday of the month
int diff = weekday - wdayFirst;
if ( diff < 0 )
diff += 7;
// add advance n-1 weeks more
diff += 7*(n - 1);
dt -= wxDateSpan::Days(diff);
}
else
{
// get the last day of the month
dt.SetToLastMonthDay(month, year);
// get its wday
WeekDay wdayLast = dt.GetWeekDay();
// go to the last weekday of the month
int diff = wdayLast - weekday;
if ( diff < 0 )
diff += 7;
// and rewind n-1 weeks from there
diff += 7*(n - 1);
dt -= wxDateSpan::Days(diff);
}
// check that it is still in the same month
if ( dt.GetMonth() == month )
{
*this = dt;
return TRUE;
}
else
{
// no such day in this month
return FALSE;
}
}
// ----------------------------------------------------------------------------
// wxDateTime to/from text representations
// ----------------------------------------------------------------------------

View File

@@ -203,7 +203,10 @@ extern int WXDLLEXPORT wxVsnprintf(wxChar *buf, size_t len,
// vsnprintf() will not terminate the string with '\0' if there is not
// enough place, but we want the string to always be NUL terminated
int rc = wxVsnprintfA(buf, len - 1, format, argptr);
if ( rc == -1 )
{
buf[len] = 0;
}
return rc;
#endif // Unicode/ANSI