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:
@@ -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.
|
||||
|
@@ -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
328
include/wx/datetime.inl
Normal 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;
|
||||
}
|
||||
|
||||
|
@@ -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); }
|
||||
|
@@ -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();
|
||||
TestJoinableThreads();
|
||||
}
|
||||
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();
|
||||
|
@@ -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
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@@ -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);
|
||||
buf[len] = 0;
|
||||
if ( rc == -1 )
|
||||
{
|
||||
buf[len] = 0;
|
||||
}
|
||||
|
||||
return rc;
|
||||
#endif // Unicode/ANSI
|
||||
|
Reference in New Issue
Block a user