Added wxGetUTCTimeMillis() and wxGetUTCTimeUSec().

Fixed wxGetLocalTimeMillis() to really return the local time and provide
wxGetUTCTimeMillis() doing what this function used to do before. Closes #13610.

Also add wxGetUTCTimeUSec() for even higher resolution time stamps as it is
basically the same as wxGetUTCTimeMillis() anyhow, at least for MSW and
non-ancient Unix systems providing gettimeofday().

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@69837 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2011-11-27 19:50:23 +00:00
parent 59068d79f7
commit a43503cb8d
4 changed files with 85 additions and 53 deletions

View File

@@ -459,7 +459,9 @@ All:
- Fix crash in wxArray::insert() overload taking iterator range (wsu). - Fix crash in wxArray::insert() overload taking iterator range (wsu).
- Added wxEventFilter class and wxEvtHandler::{Add,Remove}Filter(). - Added wxEventFilter class and wxEvtHandler::{Add,Remove}Filter().
- Added convenient wxCmdLineParser::AddLong{Option,Switch}() wrappers. - Added convenient wxCmdLineParser::AddLong{Option,Switch}() wrappers.
- Added wxStopWatch::TimeInMicro(). - Added wxStopWatch::TimeInMicro() and wxGetUTCTimeUSec().
- Made wxGetLocalTimeMillis() really return local time, added
wxGetUTCTimeMillis() returning what this function used to return.
All (GUI): All (GUI):

View File

@@ -1,10 +1,12 @@
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// Name: wx/stopwatch.h // Name: wx/stopwatch.h
// Purpose: wxStopWatch and global time-related functions // Purpose: wxStopWatch and global time-related functions
// Author: Julian Smart (wxTimer), Sylvain Bougnoux (wxStopWatch) // Author: Julian Smart (wxTimer), Sylvain Bougnoux (wxStopWatch),
// Vadim Zeitlin (time functions, current wxStopWatch)
// Created: 26.06.03 (extracted from wx/timer.h) // Created: 26.06.03 (extracted from wx/timer.h)
// RCS-ID: $Id$ // RCS-ID: $Id$
// Copyright: (c) 1998-2003 Julian Smart, Sylvain Bougnoux // Copyright: (c) 1998-2003 Julian Smart, Sylvain Bougnoux
// (c) 2011 Vadim Zeitlin
// Licence: wxWindows licence // Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
@@ -14,6 +16,11 @@
#include "wx/defs.h" #include "wx/defs.h"
#include "wx/longlong.h" #include "wx/longlong.h"
// Time-related functions are also available via this header for compatibility
// but you should include wx/time.h directly if you need only them and not
// wxStopWatch itself.
#include "wx/time.h"
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxStopWatch: measure time intervals with up to 1ms resolution // wxStopWatch: measure time intervals with up to 1ms resolution
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -116,6 +123,14 @@ extern long WXDLLIMPEXP_BASE wxGetUTCTime();
// Get number of milliseconds since local time 00:00:00 Jan 1st 1970 // Get number of milliseconds since local time 00:00:00 Jan 1st 1970
extern wxMilliClock_t WXDLLIMPEXP_BASE wxGetLocalTimeMillis(); extern wxMilliClock_t WXDLLIMPEXP_BASE wxGetLocalTimeMillis();
#if wxUSE_LONGLONG
// Get the number of milliseconds or microseconds since the Epoch.
wxLongLong WXDLLIMPEXP_BASE wxGetUTCTimeMillis();
wxLongLong WXDLLIMPEXP_BASE wxGetUTCTimeUSec();
#endif // wxUSE_LONGLONG
#define wxGetCurrentTime() wxGetLocalTime() #define wxGetCurrentTime() wxGetLocalTime()
// on some really old systems gettimeofday() doesn't have the second argument, // on some really old systems gettimeofday() doesn't have the second argument,

View File

@@ -105,7 +105,11 @@ long wxGetLocalTime();
/** /**
Returns the number of milliseconds since local time 00:00:00 Jan 1st 1970. Returns the number of milliseconds since local time 00:00:00 Jan 1st 1970.
@see wxDateTime::Now(), wxLongLong The use of wxGetUTCTimeMillis() is preferred as it provides a usually
(except for changes to the system time) monotonic clock which the local
time also changes whenever DST begins or ends.
@see wxDateTime::Now(), wxGetUTCTimeMillis(), wxGetUTCTimeUSec()
@header{wx/stopwatch.h} @header{wx/stopwatch.h}
*/ */
@@ -120,5 +124,19 @@ wxLongLong wxGetLocalTimeMillis();
*/ */
long wxGetUTCTime(); long wxGetUTCTime();
/**
Returns the number of milliseconds since GMT 00:00:00 Jan 1st 1970.
@since 2.9.3
*/
wxLongLong wxGetUTCTimeMillis();
/**
Returns the number of microseconds since GMT 00:00:00 Jan 1st 1970.
@since 2.9.3
*/
wxLongLong wxGetUTCTimeUSec();
//@} //@}

View File

@@ -42,10 +42,6 @@
// System headers // System headers
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
#if defined(__WIN32__) && !defined(HAVE_FTIME) && !defined(__MWERKS__) && !defined(__WXWINCE__)
#define HAVE_FTIME
#endif
#if defined(__VISAGECPP__) && !defined(HAVE_FTIME) #if defined(__VISAGECPP__) && !defined(HAVE_FTIME)
#define HAVE_FTIME #define HAVE_FTIME
# if __IBMCPP__ >= 400 # if __IBMCPP__ >= 400
@@ -120,6 +116,7 @@ struct PerfCounter
#endif // __WXMSW__ #endif // __WXMSW__
const int MILLISECONDS_PER_SECOND = 1000; const int MILLISECONDS_PER_SECOND = 1000;
const int MICROSECONDS_PER_MILLISECOND = 1000;
const int MICROSECONDS_PER_SECOND = 1000*1000; const int MICROSECONDS_PER_SECOND = 1000*1000;
} // anonymous namespace } // anonymous namespace
@@ -265,14 +262,43 @@ long wxGetUTCTime()
#if wxUSE_LONGLONG #if wxUSE_LONGLONG
wxLongLong wxGetUTCTimeUSec()
{
#if defined(__WXMSW__)
FILETIME ft;
::GetSystemTimeAsFileTime(&ft);
// FILETIME is in 100ns or 0.1us since 1601-01-01, transform to us since
// 1970-01-01.
wxLongLong t(ft.dwHighDateTime, ft.dwLowDateTime);
t /= 10;
t -= wxLL(11644473600000000); // Unix - Windows epochs difference in us.
return t;
#else // non-MSW
#ifdef HAVE_GETTIMEOFDAY
timeval tv;
if ( wxGetTimeOfDay(&tv) != -1 )
{
wxLongLong val(tv.tv_sec);
val *= MICROSECONDS_PER_SECOND;
val += tv.tv_usec;
return val;
}
#endif // HAVE_GETTIMEOFDAY
// Fall back to lesser precision function.
return wxGetUTCTimeMillis()*1000;
#endif // MSW/!MSW
}
// Get local time as milliseconds since 00:00:00, Jan 1st 1970 // Get local time as milliseconds since 00:00:00, Jan 1st 1970
wxLongLong wxGetLocalTimeMillis() wxLongLong wxGetUTCTimeMillis()
{ {
wxLongLong val = 1000l; wxLongLong val = 1000l;
// If possible, use a function which avoids conversions from // If possible, use a function which avoids conversions from
// broken-up time structures to milliseconds // broken-up time structures to milliseconds
#if defined(__WXPALMOS__) #if defined(__WXPALMOS__)
DateTimeType thenst; DateTimeType thenst;
thenst.second = 0; thenst.second = 0;
@@ -285,23 +311,16 @@ wxLongLong wxGetLocalTimeMillis()
uint32_t now = TimGetSeconds(); uint32_t now = TimGetSeconds();
uint32_t then = TimDateTimeToSeconds (&thenst); uint32_t then = TimDateTimeToSeconds (&thenst);
return SysTimeToMilliSecs(SysTimeInSecs(now - then)); return SysTimeToMilliSecs(SysTimeInSecs(now - then));
#elif defined(__WXMSW__) && (defined(__WINE__) || defined(__MWERKS__)) #elif defined(__WXMSW__)
// This should probably be the way all WXMSW compilers should do it FILETIME ft;
// Go direct to the OS for time ::GetSystemTimeAsFileTime(&ft);
SYSTEMTIME thenst = { 1970, 1, 4, 1, 0, 0, 0, 0 }; // 00:00:00 Jan 1st 1970
FILETIME thenft;
SystemTimeToFileTime( &thenst, &thenft );
wxLongLong then( thenft.dwHighDateTime, thenft.dwLowDateTime ); // time in 100 nanoseconds
SYSTEMTIME nowst;
GetLocalTime( &nowst );
FILETIME nowft;
SystemTimeToFileTime( &nowst, &nowft );
wxLongLong now( nowft.dwHighDateTime, nowft.dwLowDateTime ); // time in 100 nanoseconds
return ( now - then ) / 10000.0; // time from 00:00:00 Jan 1st 1970 to now in milliseconds
// FILETIME is expressed in 100ns (or 0.1us) units since 1601-01-01,
// transform them to ms since 1970-01-01.
wxLongLong t(ft.dwHighDateTime, ft.dwLowDateTime);
t /= 10000;
t -= wxLL(11644473600000); // Unix - Windows epochs difference in ms.
return t;
#elif defined(HAVE_GETTIMEOFDAY) #elif defined(HAVE_GETTIMEOFDAY)
struct timeval tp; struct timeval tp;
if ( wxGetTimeOfDay(&tp) != -1 ) if ( wxGetTimeOfDay(&tp) != -1 )
@@ -323,32 +342,6 @@ wxLongLong wxGetLocalTimeMillis()
val *= tp.time; val *= tp.time;
return (val + tp.millitm); return (val + tp.millitm);
#else // no gettimeofday() nor ftime() #else // no gettimeofday() nor ftime()
// We use wxGetLocalTime() to get the seconds since
// 00:00:00 Jan 1st 1970 and then whatever is available
// to get millisecond resolution.
//
// NOTE that this might lead to a problem if the clocks
// use different sources, so this approach should be
// avoided where possible.
val *= wxGetLocalTime();
// GRG: This will go soon as all WIN32 seem to have ftime
// JACS: unfortunately not. WinCE doesn't have it.
#if defined (__WIN32__)
// If your platform/compiler needs to use two different functions
// to get ms resolution, please do NOT just shut off these warnings,
// drop me a line instead at <guille@iies.es>
// FIXME
#ifndef __WXWINCE__
#warning "Possible clock skew bug in wxGetLocalTimeMillis()!"
#endif
SYSTEMTIME st;
::GetLocalTime(&st);
val += st.wMilliseconds;
#else // !Win32
// If your platform/compiler does not support ms resolution please // If your platform/compiler does not support ms resolution please
// do NOT just shut off these warnings, drop me a line instead at // do NOT just shut off these warnings, drop me a line instead at
// <guille@iies.es> // <guille@iies.es>
@@ -360,13 +353,17 @@ wxLongLong wxGetLocalTimeMillis()
#else #else
#warning "wxStopWatch will be up to second resolution!" #warning "wxStopWatch will be up to second resolution!"
#endif // compiler #endif // compiler
#endif
val *= wxGetUTCTime();
return val; return val;
#endif // time functions #endif // time functions
} }
wxLongLong wxGetLocalTimeMillis()
{
return wxGetUTCTimeMillis() - wxGetTimeZone()*MILLISECONDS_PER_SECOND;
}
#else // !wxUSE_LONGLONG #else // !wxUSE_LONGLONG
double wxGetLocalTimeMillis(void) double wxGetLocalTimeMillis(void)