summaryrefslogtreecommitdiff
path: root/qmake/tools/qdatetime.cpp
Side-by-side diff
Diffstat (limited to 'qmake/tools/qdatetime.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--qmake/tools/qdatetime.cpp70
1 files changed, 58 insertions, 12 deletions
diff --git a/qmake/tools/qdatetime.cpp b/qmake/tools/qdatetime.cpp
index 93e40a8..3137877 100644
--- a/qmake/tools/qdatetime.cpp
+++ b/qmake/tools/qdatetime.cpp
@@ -1,134 +1,133 @@
/****************************************************************************
** $Id$
**
** Implementation of date and time classes
**
** Created : 940124
**
-** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
**
** This file is part of the tools module of the Qt GUI Toolkit.
**
** This file may be distributed under the terms of the Q Public License
** as defined by Trolltech AS of Norway and appearing in the file
** LICENSE.QPL included in the packaging of this file.
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.
**
** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
** licenses may use this file in accordance with the Qt Commercial License
** Agreement provided with the Software.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
** information about Qt Commercial License Agreements.
** See http://www.trolltech.com/qpl/ for QPL licensing information.
** See http://www.trolltech.com/gpl/ for GPL licensing information.
**
** Contact info@trolltech.com if any conditions of this licensing are
** not clear to you.
**
**********************************************************************/
-// Get the system specific includes and defines
#include "qplatformdefs.h"
#include "qdatetime.h"
#include "qdatastream.h"
#include "qregexp.h"
#include <stdio.h>
#ifndef Q_OS_TEMP
#include <time.h>
#endif
#if defined(Q_OS_WIN32)
#include <windows.h>
#endif
static const uint FIRST_DAY = 2361222; // Julian day for 1752-09-14
static const int FIRST_YEAR = 1752; // ### wrong for many countries
static const uint SECS_PER_DAY = 86400;
static const uint MSECS_PER_DAY = 86400000;
static const uint SECS_PER_HOUR = 3600;
static const uint MSECS_PER_HOUR= 3600000;
static const uint SECS_PER_MIN = 60;
static const uint MSECS_PER_MIN = 60000;
static const short monthDays[] = {
0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
static const char * const qt_shortMonthNames[] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
#ifndef QT_NO_DATESTRING
/*****************************************************************************
Some static function used by QDate, QTime and QDateTime
*****************************************************************************/
// Replaces tokens by their value. See QDateTime::toString() for a list of valid tokens
static QString getFmtString( const QString& f, const QTime* dt = 0, const QDate* dd = 0, bool am_pm = FALSE )
{
if ( f.isEmpty() )
return QString::null;
QString buf = f;
if ( dt ) {
if ( f == "h" ) {
if ( ( am_pm ) && ( dt->hour() > 12 ) )
buf = QString::number( dt->hour() - 12 );
else if ( ( am_pm ) && ( dt->hour() == 0 ) )
buf = "12";
else
buf = QString::number( dt->hour() );
} else if ( f == "hh" ) {
if ( ( am_pm ) && ( dt->hour() > 12 ) )
buf = QString::number( dt->hour() - 12 ).rightJustify( 2, '0', TRUE );
else if ( ( am_pm ) && ( dt->hour() == 0 ) )
buf = "12";
else
buf = QString::number( dt->hour() ).rightJustify( 2, '0', TRUE );
} else if ( f == "m" ) {
buf = QString::number( dt->minute() );
} else if ( f == "mm" ) {
buf = QString::number( dt->minute() ).rightJustify( 2, '0', TRUE );
} else if ( f == "s" ) {
buf = QString::number( dt->second() );
} else if ( f == "ss" ) {
buf = QString::number( dt->second() ).rightJustify( 2, '0', TRUE );
} else if ( f == "z" ) {
buf = QString::number( dt->msec() );
} else if ( f == "zzz" ) {
buf = QString::number( dt->msec() ).rightJustify( 3, '0', TRUE );
} else if ( f == "ap" ) {
buf = dt->hour() < 12 ? "am" : "pm";
} else if ( f == "AP" ) {
buf = dt->hour() < 12 ? "AM" : "PM";
}
}
if ( dd ) {
if ( f == "d" ) {
buf = QString::number( dd->day() );
} else if ( f == "dd" ) {
buf = QString::number( dd->day() ).rightJustify( 2, '0', TRUE );
} else if ( f == "M" ) {
buf = QString::number( dd->month() );
} else if ( f == "MM" ) {
buf = QString::number( dd->month() ).rightJustify( 2, '0', TRUE );
#ifndef QT_NO_TEXTDATE
} else if ( f == "ddd" ) {
buf = dd->shortDayName( dd->dayOfWeek() );
} else if ( f == "dddd" ) {
buf = dd->longDayName( dd->dayOfWeek() );
} else if ( f == "MMM" ) {
buf = dd->shortMonthName( dd->month() );
} else if ( f == "MMMM" ) {
buf = dd->longMonthName( dd->month() );
@@ -802,294 +801,312 @@ QString QDate::toString( const QString& format ) const
\warning If \a y is in the range 0..99, it is interpreted as
1900..1999.
Returns TRUE if the date is valid; otherwise returns FALSE.
*/
bool QDate::setYMD( int y, int m, int d )
{
if ( year() == y && month() == m && day() == d )
return isValid();
if ( !isValid(y,m,d) ) {
#if defined(QT_CHECK_RANGE)
qWarning( "QDate::setYMD: Invalid date %04d-%02d-%02d", y, m, d );
#endif
return FALSE;
}
jd = gregorianToJulian( y, m, d );
return TRUE;
}
/*!
Returns a QDate object containing a date \a ndays later than the
date of this object (or earlier if \a ndays is negative).
\sa addMonths() addYears() daysTo()
*/
QDate QDate::addDays( int ndays ) const
{
QDate d;
d.jd = jd + ndays;
return d;
}
/*!
Returns a QDate object containing a date \a nmonths later than the
date of this object (or earlier if \a nmonths is negative).
\sa addDays() addYears()
*/
QDate QDate::addMonths( int nmonths ) const
{
int y, m, d;
julianToGregorian( jd, y, m, d );
while ( nmonths != 0 ) {
if ( nmonths < 0 && nmonths + 12 <= 0 ) {
y--;
nmonths+=12;
} else if ( nmonths < 0 ) {
m+= nmonths;
nmonths = 0;
if ( m <= 0 ) {
--y;
m+=12;
}
} else if ( nmonths - 12 >= 0 ) {
y++;
nmonths-=12;
} else if ( m == 12 ) {
y++;
m = 0;
} else {
m+= nmonths;
nmonths = 0;
if ( m > 12 ) {
++y;
m -= 12;
}
}
}
QDate tmp(y,m,1);
if( d > tmp.daysInMonth() )
d = tmp.daysInMonth();
QDate date(y, m, d);
return date;
}
/*!
Returns a QDate object containing a date \a nyears later than the
date of this object (or earlier if \a nyears is negative).
\sa addDays(), addMonths()
*/
QDate QDate::addYears( int nyears ) const
{
int y, m, d;
julianToGregorian( jd, y, m, d );
y += nyears;
+
+ QDate tmp(y,m,1);
+
+ if( d > tmp.daysInMonth() )
+ d = tmp.daysInMonth();
+
QDate date(y, m, d);
return date;
}
/*!
Returns the number of days from this date to \a d (which is
negative if \a d is earlier than this date).
Example:
\code
QDate d1( 1995, 5, 17 ); // May 17th 1995
QDate d2( 1995, 5, 20 ); // May 20th 1995
d1.daysTo( d2 ); // returns 3
d2.daysTo( d1 ); // returns -3
\endcode
\sa addDays()
*/
int QDate::daysTo( const QDate &d ) const
{
return d.jd - jd;
}
/*!
\fn bool QDate::operator==( const QDate &d ) const
Returns TRUE if this date is equal to \a d; otherwise returns FALSE.
*/
/*!
\fn bool QDate::operator!=( const QDate &d ) const
Returns TRUE if this date is different from \a d; otherwise returns FALSE.
*/
/*!
\fn bool QDate::operator<( const QDate &d ) const
Returns TRUE if this date is earlier than \a d, otherwise returns FALSE.
*/
/*!
\fn bool QDate::operator<=( const QDate &d ) const
Returns TRUE if this date is earlier than or equal to \a d,
otherwise returns FALSE.
*/
/*!
\fn bool QDate::operator>( const QDate &d ) const
Returns TRUE if this date is later than \a d, otherwise returns FALSE.
*/
/*!
\fn bool QDate::operator>=( const QDate &d ) const
Returns TRUE if this date is later than or equal to \a d,
otherwise returns FALSE.
*/
/*!
\overload
Returns the current date, as reported by the system clock.
\sa QTime::currentTime(), QDateTime::currentDateTime()
*/
QDate QDate::currentDate()
{
return currentDate( Qt::LocalTime );
}
/*!
Returns the current date, as reported by the system clock, for the
TimeSpec \a ts. The default TimeSpec is LocalTime.
\sa QTime::currentTime(), QDateTime::currentDateTime(), Qt::TimeSpec
*/
QDate QDate::currentDate( Qt::TimeSpec ts )
{
QDate d;
#if defined(Q_OS_WIN32)
SYSTEMTIME t;
memset( &t, 0, sizeof(SYSTEMTIME) );
if ( ts == Qt::LocalTime )
GetLocalTime( &t );
else
GetSystemTime( &t );
d.jd = gregorianToJulian( t.wYear, t.wMonth, t.wDay );
#else
+ // posix compliant system
time_t ltime;
time( &ltime );
tm *t;
+
+# if defined(QT_THREAD_SUPPORT) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
+ // use the reentrant versions of localtime() and gmtime() where available
+ tm res;
+ if ( ts == Qt::LocalTime )
+ t = localtime_r( &ltime, &res );
+ else
+ t = gmtime_r( &ltime, &res );
+# else
if ( ts == Qt::LocalTime )
t = localtime( &ltime );
- else
+ else
t = gmtime( &ltime );
+# endif // QT_THREAD_SUPPORT && _POSIX_THREAD_SAFE_FUNCTIONS
+
d.jd = gregorianToJulian( t->tm_year + 1900, t->tm_mon + 1, t->tm_mday );
#endif
return d;
}
#ifndef QT_NO_DATESTRING
/*!
Returns the QDate represented by the string \a s, using the format
\a f, or an invalid date if the string cannot be parsed.
Note for \c Qt::TextDate: It is recommended that you use the
English short month names (e.g. "Jan"). Although localized month
names can also be used, they depend on the user's locale settings.
\warning \c Qt::LocalDate cannot be used here.
*/
QDate QDate::fromString( const QString& s, Qt::DateFormat f )
{
if ( ( s.isEmpty() ) || ( f == Qt::LocalDate ) ) {
#if defined(QT_CHECK_RANGE)
qWarning( "QDate::fromString: Parameter out of range." );
#endif
return QDate();
}
switch ( f ) {
case Qt::ISODate:
{
int year( s.mid( 0, 4 ).toInt() );
int month( s.mid( 5, 2 ).toInt() );
int day( s.mid( 8, 2 ).toInt() );
if ( year && month && day )
return QDate( year, month, day );
}
break;
default:
#ifndef QT_NO_TEXTDATE
case Qt::TextDate:
{
/*
This will fail gracefully if the input string doesn't
contain any space.
*/
int monthPos = s.find( ' ' ) + 1;
int dayPos = s.find( ' ', monthPos ) + 1;
QString monthName( s.mid(monthPos, dayPos - monthPos - 1) );
int month = -1;
// try English names first
for ( int i = 0; i < 12; i++ ) {
if ( monthName == qt_shortMonthNames[i] ) {
month = i + 1;
break;
}
}
// try the localized names
if ( month == -1 ) {
for ( int i = 0; i < 12; i++ ) {
if ( monthName == shortMonthName( i + 1 ) ) {
month = i + 1;
break;
}
}
}
#if defined(QT_CHECK_RANGE)
if ( month < 1 || month > 12 ) {
qWarning( "QDate::fromString: Parameter out of range." );
month = 1;
}
#endif
int day = s.mid( dayPos, 2 ).stripWhiteSpace().toInt();
int year = s.right( 4 ).toInt();
return QDate( year, month, day );
}
#else
break;
#endif
}
return QDate();
}
#endif //QT_NO_DATESTRING
/*!
\overload
Returns TRUE if the specified date (year \a y, month \a m and day
\a d) is valid; otherwise returns FALSE.
Example:
\code
QDate::isValid( 2002, 5, 17 ); // TRUE May 17th 2002 is valid
QDate::isValid( 2002, 2, 30 ); // FALSE Feb 30th does not exist
QDate::isValid( 2004, 2, 29 ); // TRUE 2004 is a leap year
QDate::isValid( 1202, 6, 6 ); // FALSE 1202 is pre-Gregorian
\endcode
@@ -1462,346 +1479,357 @@ QTime QTime::addSecs( int nsecs ) const
/*!
Returns the number of seconds from this time to \a t (which is
negative if \a t is earlier than this time).
Because QTime measures time within a day and there are 86400
seconds in a day, the result is always between -86400 and 86400.
\sa addSecs() QDateTime::secsTo()
*/
int QTime::secsTo( const QTime &t ) const
{
return ((int)t.ds - (int)ds)/1000;
}
/*!
Returns a QTime object containing a time \a ms milliseconds later
than the time of this object (or earlier if \a ms is negative).
Note that the time will wrap if it passes midnight. See addSecs()
for an example.
\sa addSecs(), msecsTo()
*/
QTime QTime::addMSecs( int ms ) const
{
QTime t;
if ( ms < 0 ) {
// % not well-defined for -ve, but / is.
int negdays = (MSECS_PER_DAY-ms) / MSECS_PER_DAY;
t.ds = ((int)ds + ms + negdays*MSECS_PER_DAY)
% MSECS_PER_DAY;
} else {
t.ds = ((int)ds + ms) % MSECS_PER_DAY;
}
return t;
}
/*!
Returns the number of milliseconds from this time to \a t (which
is negative if \a t is earlier than this time).
Because QTime measures time within a day and there are 86400
seconds in a day, the result is always between -86400 and 86400s.
\sa secsTo()
*/
int QTime::msecsTo( const QTime &t ) const
{
return (int)t.ds - (int)ds;
}
/*!
\fn bool QTime::operator==( const QTime &t ) const
Returns TRUE if this time is equal to \a t; otherwise returns FALSE.
*/
/*!
\fn bool QTime::operator!=( const QTime &t ) const
Returns TRUE if this time is different from \a t; otherwise returns FALSE.
*/
/*!
\fn bool QTime::operator<( const QTime &t ) const
Returns TRUE if this time is earlier than \a t; otherwise returns FALSE.
*/
/*!
\fn bool QTime::operator<=( const QTime &t ) const
Returns TRUE if this time is earlier than or equal to \a t;
otherwise returns FALSE.
*/
/*!
\fn bool QTime::operator>( const QTime &t ) const
Returns TRUE if this time is later than \a t; otherwise returns FALSE.
*/
/*!
\fn bool QTime::operator>=( const QTime &t ) const
Returns TRUE if this time is later than or equal to \a t;
otherwise returns FALSE.
*/
-/*!
+/*!
\overload
Returns the current time as reported by the system clock.
Note that the accuracy depends on the accuracy of the underlying
operating system; not all systems provide 1-millisecond accuracy.
*/
QTime QTime::currentTime()
{
return currentTime( Qt::LocalTime );
}
/*!
Returns the current time as reported by the system clock, for the
TimeSpec \a ts. The default TimeSpec is LocalTime.
Note that the accuracy depends on the accuracy of the underlying
operating system; not all systems provide 1-millisecond accuracy.
\sa Qt::TimeSpec
*/
QTime QTime::currentTime( Qt::TimeSpec ts )
{
QTime t;
currentTime( &t, ts );
return t;
}
#ifndef QT_NO_DATESTRING
/*!
Returns the representation \a s as a QTime using the format \a f,
or an invalid time if this is not possible.
\warning Note that \c Qt::LocalDate cannot be used here.
*/
QTime QTime::fromString( const QString& s, Qt::DateFormat f )
{
if ( ( s.isEmpty() ) || ( f == Qt::LocalDate ) ) {
#if defined(QT_CHECK_RANGE)
qWarning( "QTime::fromString: Parameter out of range." );
#endif
return QTime();
}
int hour( s.mid( 0, 2 ).toInt() );
int minute( s.mid( 3, 2 ).toInt() );
int second( s.mid( 6, 2 ).toInt() );
int msec( s.mid( 9, 3 ).toInt() );
return QTime( hour, minute, second, msec );
}
#endif
/*!
\internal
\obsolete
Fetches the current time and returns TRUE if the time is within one
minute after midnight, otherwise FALSE. The return value is used by
QDateTime::currentDateTime() to ensure that the date there is correct.
*/
bool QTime::currentTime( QTime *ct )
{
return currentTime( ct, Qt::LocalTime );
}
/*!
\internal
Fetches the current time, for the TimeSpec \a ts, and returns TRUE
if the time is within one minute after midnight, otherwise FALSE. The
return value is used by QDateTime::currentDateTime() to ensure that
the date there is correct. The default TimeSpec is LocalTime.
\sa Qt::TimeSpec
*/
bool QTime::currentTime( QTime *ct, Qt::TimeSpec ts )
{
if ( !ct ) {
#if defined(QT_CHECK_NULL)
qWarning( "QTime::currentTime(QTime *): Null pointer not allowed" );
#endif
return FALSE;
}
#if defined(Q_OS_WIN32)
SYSTEMTIME t;
if ( ts == Qt::LocalTime ) {
GetLocalTime( &t );
} else {
GetSystemTime( &t );
}
ct->ds = (uint)( MSECS_PER_HOUR*t.wHour + MSECS_PER_MIN*t.wMinute +
1000*t.wSecond + t.wMilliseconds );
#elif defined(Q_OS_UNIX)
+ // posix compliant system
struct timeval tv;
gettimeofday( &tv, 0 );
time_t ltime = tv.tv_sec;
tm *t;
- if ( ts == Qt::LocalTime ) {
+
+# if defined(QT_THREAD_SUPPORT) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
+ // use the reentrant versions of localtime() and gmtime() where available
+ tm res;
+ if ( ts == Qt::LocalTime )
+ t = localtime_r( &ltime, &res );
+ else
+ t = gmtime_r( &ltime, &res );
+# else
+ if ( ts == Qt::LocalTime )
t = localtime( &ltime );
- } else {
+ else
t = gmtime( &ltime );
- }
+# endif // QT_THREAD_SUPPORT && _POSIX_THREAD_SAFE_FUNCTIONS
+
ct->ds = (uint)( MSECS_PER_HOUR * t->tm_hour + MSECS_PER_MIN * t->tm_min +
1000 * t->tm_sec + tv.tv_usec / 1000 );
#else
time_t ltime; // no millisecond resolution
::time( &ltime );
tm *t;
- if ( ts == Qt::LocalTime )
+ if ( ts == Qt::LocalTime )
localtime( &ltime );
else
gmtime( &ltime );
ct->ds = (uint) ( MSECS_PER_HOUR * t->tm_hour + MSECS_PER_MIN * t->tm_min +
1000 * t->tm_sec );
#endif
// 00:00.00 to 00:00.59.999 is considered as "midnight or right after"
return ct->ds < (uint) MSECS_PER_MIN;
}
/*!
\overload
Returns TRUE if the specified time is valid; otherwise returns
FALSE.
The time is valid if \a h is in the range 0..23, \a m and \a s are
in the range 0..59, and \a ms is in the range 0..999.
Example:
\code
QTime::isValid(21, 10, 30); // returns TRUE
QTime::isValid(22, 5, 62); // returns FALSE
\endcode
*/
bool QTime::isValid( int h, int m, int s, int ms )
{
return (uint)h < 24 && (uint)m < 60 && (uint)s < 60 && (uint)ms < 1000;
}
/*!
Sets this time to the current time. This is practical for timing:
\code
QTime t;
- t.start(); // start clock
- ... // some lengthy task
- qDebug( "%d\n", t.elapsed() ); // prints the number of msecs elapsed
+ t.start();
+ some_lengthy_task();
+ qDebug( "Time elapsed: %d ms", t.elapsed() );
\endcode
\sa restart(), elapsed(), currentTime()
*/
void QTime::start()
{
*this = currentTime();
}
/*!
Sets this time to the current time and returns the number of
milliseconds that have elapsed since the last time start() or
restart() was called.
This function is guaranteed to be atomic and is thus very handy
for repeated measurements. Call start() to start the first
measurement and then restart() for each later measurement.
Note that the counter wraps to zero 24 hours after the last call
to start() or restart().
\warning If the system's clock setting has been changed since the
last time start() or restart() was called, the result is
undefined. This can happen when daylight savings time is turned on
or off.
\sa start(), elapsed(), currentTime()
*/
int QTime::restart()
{
QTime t = currentTime();
int n = msecsTo( t );
if ( n < 0 ) // passed midnight
n += 86400*1000;
*this = t;
return n;
}
/*!
Returns the number of milliseconds that have elapsed since the
last time start() or restart() was called.
Note that the counter wraps to zero 24 hours after the last call
to start() or restart.
Note that the accuracy depends on the accuracy of the underlying
operating system; not all systems provide 1-millisecond accuracy.
\warning If the system's clock setting has been changed since the
last time start() or restart() was called, the result is
undefined. This can happen when daylight savings time is turned on
or off.
\sa start(), restart()
*/
int QTime::elapsed() const
{
int n = msecsTo( currentTime() );
if ( n < 0 ) // passed midnight
n += 86400*1000;
return n;
}
/*****************************************************************************
QDateTime member functions
*****************************************************************************/
/*!
\class QDateTime qdatetime.h
\reentrant
\brief The QDateTime class provides date and time functions.
\ingroup time
\mainclass
A QDateTime object contains a calendar date and a clock time (a
"datetime"). It is a combination of the QDate and QTime classes.
It can read the current datetime from the system clock. It
provides functions for comparing datetimes and for manipulating a
datetime by adding a number of seconds, days, months or years.
A QDateTime object is typically created either by giving a date
and time explicitly in the constructor, or by using the static
function currentDateTime(), which returns a QDateTime object set
to the system clock's time. The date and time can be changed with
setDate() and setTime(). A datetime can also be set using the
setTime_t() function, which takes a POSIX-standard "number of
seconds since 00:00:00 on January 1, 1970" value. The fromString()
function returns a QDateTime given a string and a date format
which is used to interpret the date within the string.
The date() and time() functions provide access to the date and
@@ -1867,202 +1895,220 @@ QDateTime::QDateTime( const QDate &date, const QTime &time )
/*!
\fn bool QDateTime::isValid() const
Returns TRUE if both the date and the time are valid; otherwise
returns FALSE.
\sa QDate::isValid(), QTime::isValid()
*/
/*!
\fn QDate QDateTime::date() const
Returns the date part of the datetime.
\sa setDate(), time()
*/
/*!
\fn QTime QDateTime::time() const
Returns the time part of the datetime.
\sa setTime(), date()
*/
/*!
\fn void QDateTime::setDate( const QDate &date )
Sets the date part of this datetime to \a date.
\sa date(), setTime()
*/
/*!
\fn void QDateTime::setTime( const QTime &time )
Sets the time part of this datetime to \a time.
\sa time(), setDate()
*/
/*!
Returns the datetime as the number of seconds that have passed
since 1970-01-01T00:00:00, Coordinated Universal Time (UTC).
On systems that do not support timezones, this function will
behave as if local time were UTC.
\sa setTime_t()
*/
uint QDateTime::toTime_t() const
{
tm brokenDown;
brokenDown.tm_sec = t.second();
brokenDown.tm_min = t.minute();
brokenDown.tm_hour = t.hour();
brokenDown.tm_mday = d.day();
brokenDown.tm_mon = d.month() - 1;
brokenDown.tm_year = d.year() - 1900;
brokenDown.tm_isdst = -1;
int secsSince1Jan1970UTC = (int) mktime( &brokenDown );
if ( secsSince1Jan1970UTC < -1 )
secsSince1Jan1970UTC = -1;
return (uint) secsSince1Jan1970UTC;
}
/*!
\overload
Convenience function that sets the date and time to local time
based on the given UTC time.
*/
void QDateTime::setTime_t( uint secsSince1Jan1970UTC )
{
setTime_t( secsSince1Jan1970UTC, Qt::LocalTime );
}
/*!
Sets the date and time to \a ts time (\c Qt::LocalTime or \c
Qt::UTC) given the number of seconds that have passed since
1970-01-01T00:00:00, Coordinated Universal Time (UTC). On systems
that do not support timezones this function will behave as if
local time were UTC.
On Windows, only a subset of \a secsSince1Jan1970UTC values are
supported, as Windows starts counting from 1980.
\sa toTime_t()
*/
void QDateTime::setTime_t( uint secsSince1Jan1970UTC, Qt::TimeSpec ts )
{
time_t tmp = (time_t) secsSince1Jan1970UTC;
tm *brokenDown = 0;
+
+#if defined(Q_OS_UNIX) && defined(QT_THREAD_SUPPORT) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
+ // posix compliant system
+ // use the reentrant versions of localtime() and gmtime() where available
+ tm res;
+ if ( ts == Qt::LocalTime )
+ brokenDown = localtime_r( &tmp, &res );
+ if ( !brokenDown ) {
+ brokenDown = gmtime_r( &tmp, &res );
+ if ( !brokenDown ) {
+ d.jd = QDate::gregorianToJulian( 1970, 1, 1 );
+ t.ds = 0;
+ return;
+ }
+ }
+#else
if ( ts == Qt::LocalTime )
brokenDown = localtime( &tmp );
if ( !brokenDown ) {
brokenDown = gmtime( &tmp );
if ( !brokenDown ) {
d.jd = QDate::gregorianToJulian( 1970, 1, 1 );
t.ds = 0;
return;
}
}
+#endif
+
d.jd = QDate::gregorianToJulian( brokenDown->tm_year + 1900,
brokenDown->tm_mon + 1,
brokenDown->tm_mday );
t.ds = MSECS_PER_HOUR * brokenDown->tm_hour +
MSECS_PER_MIN * brokenDown->tm_min +
1000 * brokenDown->tm_sec;
}
#ifndef QT_NO_DATESTRING
#ifndef QT_NO_SPRINTF
/*!
\overload
Returns the datetime as a string. The \a f parameter determines
the format of the string.
If \a f is \c Qt::TextDate, the string format is "Wed May 20
03:40:13 1998" (using QDate::shortDayName(), QDate::shortMonthName(),
and QTime::toString() to generate the string, so the day and month
names will have localized names).
If \a f is \c Qt::ISODate, the string format corresponds to the
ISO 8601 extended specification for representations of dates and
times, which is YYYY-MM-DDTHH:MM:SS.
If \a f is \c Qt::LocalDate, the string format depends on the
locale settings of the system.
If the format \a f is invalid, toString() returns a null string.
\sa QDate::toString() QTime::toString()
*/
QString QDateTime::toString( Qt::DateFormat f ) const
{
if ( f == Qt::ISODate ) {
return d.toString( Qt::ISODate ) + "T" + t.toString( Qt::ISODate );
}
#ifndef QT_NO_TEXTDATE
else if ( f == Qt::TextDate ) {
#ifndef Q_WS_WIN
QString buf = d.shortDayName( d.dayOfWeek() );
buf += ' ';
buf += d.shortMonthName( d.month() );
buf += ' ';
buf += QString().setNum( d.day() );
buf += ' ';
#else
QString buf;
QString winstr;
QT_WA( {
TCHAR out[255];
GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_ILDATE, out, 255 );
winstr = QString::fromUcs2( (ushort*)out );
} , {
char out[255];
GetLocaleInfoA( LOCALE_USER_DEFAULT, LOCALE_ILDATE, (char*)&out, 255 );
winstr = QString::fromLocal8Bit( out );
} );
switch ( winstr.toInt() ) {
case 1:
buf = d.shortDayName( d.dayOfWeek() ) + " " + QString().setNum( d.day() ) + ". " + d.shortMonthName( d.month() ) + " ";
break;
default:
buf = d.shortDayName( d.dayOfWeek() ) + " " + d.shortMonthName( d.month() ) + " " + QString().setNum( d.day() ) + " ";
break;
}
#endif
buf += t.toString();
buf += ' ';
buf += QString().setNum( d.year() );
return buf;
}
#endif
else if ( f == Qt::LocalDate ) {
return d.toString( Qt::LocalDate ) + " " + t.toString( Qt::LocalDate );
}
return QString::null;
}
#endif
/*!
Returns the datetime as a string. The \a format parameter
determines the format of the result string.
These expressions may be used for the date:
\table
\header \i Expression \i Output
\row \i d \i the day as number without a leading zero (1-31)
\row \i dd \i the day as number with a leading zero (01-31)
\row \i ddd
\i the abbreviated localized day name (e.g. 'Mon'..'Sun').
Uses QDate::shortDayName().
\row \i dddd
\i the long localized day name (e.g. 'Monday'..'Sunday').
Uses QDate::longDayName().
@@ -2207,193 +2253,193 @@ int QDateTime::daysTo( const QDateTime &dt ) const
return d.daysTo( dt.d );
}
/*!
Returns the number of seconds from this datetime to \a dt (which
is negative if \a dt is earlier than this datetime).
Example:
\code
QDateTime dt = QDateTime::currentDateTime();
QDateTime xmas( QDate(dt.year(),12,24), QTime(17,00) );
qDebug( "There are %d seconds to Christmas", dt.secsTo(xmas) );
\endcode
\sa addSecs(), daysTo(), QTime::secsTo()
*/
int QDateTime::secsTo( const QDateTime &dt ) const
{
return t.secsTo(dt.t) + d.daysTo(dt.d)*SECS_PER_DAY;
}
/*!
Returns TRUE if this datetime is equal to \a dt; otherwise returns FALSE.
\sa operator!=()
*/
bool QDateTime::operator==( const QDateTime &dt ) const
{
return t == dt.t && d == dt.d;
}
/*!
Returns TRUE if this datetime is different from \a dt; otherwise
returns FALSE.
\sa operator==()
*/
bool QDateTime::operator!=( const QDateTime &dt ) const
{
return t != dt.t || d != dt.d;
}
/*!
Returns TRUE if this datetime is earlier than \a dt; otherwise
returns FALSE.
*/
bool QDateTime::operator<( const QDateTime &dt ) const
{
if ( d < dt.d )
return TRUE;
return d == dt.d ? t < dt.t : FALSE;
}
/*!
Returns TRUE if this datetime is earlier than or equal to \a dt;
otherwise returns FALSE.
*/
bool QDateTime::operator<=( const QDateTime &dt ) const
{
if ( d < dt.d )
return TRUE;
return d == dt.d ? t <= dt.t : FALSE;
}
/*!
Returns TRUE if this datetime is later than \a dt; otherwise
returns FALSE.
*/
bool QDateTime::operator>( const QDateTime &dt ) const
{
if ( d > dt.d )
return TRUE;
return d == dt.d ? t > dt.t : FALSE;
}
/*!
Returns TRUE if this datetime is later than or equal to \a dt;
otherwise returns FALSE.
*/
bool QDateTime::operator>=( const QDateTime &dt ) const
{
if ( d > dt.d )
return TRUE;
return d == dt.d ? t >= dt.t : FALSE;
}
/*!
\overload
-
+
Returns the current datetime, as reported by the system clock.
\sa QDate::currentDate(), QTime::currentTime()
*/
QDateTime QDateTime::currentDateTime()
{
return currentDateTime( Qt::LocalTime );
}
/*!
Returns the current datetime, as reported by the system clock, for the
TimeSpec \a ts. The default TimeSpec is LocalTime.
\sa QDate::currentDate(), QTime::currentTime(), Qt::TimeSpec
*/
QDateTime QDateTime::currentDateTime( Qt::TimeSpec ts )
{
QDateTime dt;
QTime t;
dt.setDate( QDate::currentDate(ts) );
if ( QTime::currentTime(&t, ts) ) // midnight or right after?
dt.setDate( QDate::currentDate(ts) ); // fetch date again
dt.setTime( t );
return dt;
}
#ifndef QT_NO_DATESTRING
/*!
Returns the QDateTime represented by the string \a s, using the
format \a f, or an invalid datetime if this is not possible.
Note for \c Qt::TextDate: It is recommended that you use the
English short month names (e.g. "Jan"). Although localized month
names can also be used, they depend on the user's locale settings.
\warning Note that \c Qt::LocalDate cannot be used here.
*/
QDateTime QDateTime::fromString( const QString& s, Qt::DateFormat f )
{
if ( ( s.isEmpty() ) || ( f == Qt::LocalDate ) ) {
#if defined(QT_CHECK_RANGE)
qWarning( "QDateTime::fromString: Parameter out of range" );
#endif
return QDateTime();
}
if ( f == Qt::ISODate ) {
return QDateTime( QDate::fromString( s.mid(0,10), Qt::ISODate ),
QTime::fromString( s.mid(11), Qt::ISODate ) );
}
#if !defined(QT_NO_REGEXP) && !defined(QT_NO_TEXTDATE)
else if ( f == Qt::TextDate ) {
QString monthName( s.mid( 4, 3 ) );
int month = -1;
// Assume that English monthnames are the default
for ( int i = 0; i < 12; ++i ) {
if ( monthName == qt_shortMonthNames[i] ) {
month = i + 1;
break;
}
}
// If English names can't be found, search the localized ones
if ( month == -1 ) {
for ( int i = 1; i <= 12; ++i ) {
if ( monthName == QDate::shortMonthName( i ) ) {
month = i;
break;
}
}
}
#if defined(QT_CHECK_RANGE)
if ( month < 1 || month > 12 ) {
qWarning( "QDateTime::fromString: Parameter out of range." );
month = 1;
}
#endif
int day = s.mid( 8, 2 ).simplifyWhiteSpace().toInt();
int year = s.right( 4 ).toInt();
QDate date( year, month, day );
QTime time;
int hour, minute, second;
int pivot = s.find( QRegExp("[0-9][0-9]:[0-9][0-9]:[0-9][0-9]") );
if ( pivot != -1 ) {
hour = s.mid( pivot, 2 ).toInt();
minute = s.mid( pivot+3, 2 ).toInt();
second = s.mid( pivot+6, 2 ).toInt();
time.setHMS( hour, minute, second );
}
return QDateTime( date, time );
}
#endif //QT_NO_REGEXP
return QDateTime();
}
#endif //QT_NO_DATESTRING