From: Vadim Zeitlin Date: Sun, 27 Nov 2011 19:50:23 +0000 (+0000) Subject: Added wxGetUTCTimeMillis() and wxGetUTCTimeUSec(). X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/a43503cb8dffad7a359a353010523341c76fbba0 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 --- diff --git a/docs/changes.txt b/docs/changes.txt index a0a5e779af..68cf93d967 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -459,7 +459,9 @@ All: - Fix crash in wxArray::insert() overload taking iterator range (wsu). - Added wxEventFilter class and wxEvtHandler::{Add,Remove}Filter(). - 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): diff --git a/include/wx/stopwatch.h b/include/wx/stopwatch.h index 189f0434cc..791eda9506 100644 --- a/include/wx/stopwatch.h +++ b/include/wx/stopwatch.h @@ -1,10 +1,12 @@ ///////////////////////////////////////////////////////////////////////////// // Name: wx/stopwatch.h // 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) // RCS-ID: $Id$ // Copyright: (c) 1998-2003 Julian Smart, Sylvain Bougnoux +// (c) 2011 Vadim Zeitlin // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// @@ -14,6 +16,11 @@ #include "wx/defs.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 // ---------------------------------------------------------------------------- @@ -116,6 +123,14 @@ extern long WXDLLIMPEXP_BASE wxGetUTCTime(); // Get number of milliseconds since local time 00:00:00 Jan 1st 1970 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() // on some really old systems gettimeofday() doesn't have the second argument, diff --git a/interface/wx/stopwatch.h b/interface/wx/stopwatch.h index d10bbbe0a4..3e37dacd1f 100644 --- a/interface/wx/stopwatch.h +++ b/interface/wx/stopwatch.h @@ -105,7 +105,11 @@ long wxGetLocalTime(); /** 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} */ @@ -120,5 +124,19 @@ wxLongLong wxGetLocalTimeMillis(); */ 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(); + //@} diff --git a/src/common/stopwatch.cpp b/src/common/stopwatch.cpp index 4ff9b7532d..67863bd0a7 100644 --- a/src/common/stopwatch.cpp +++ b/src/common/stopwatch.cpp @@ -42,10 +42,6 @@ // System headers // ---------------------------------------------------------------------------- -#if defined(__WIN32__) && !defined(HAVE_FTIME) && !defined(__MWERKS__) && !defined(__WXWINCE__) - #define HAVE_FTIME -#endif - #if defined(__VISAGECPP__) && !defined(HAVE_FTIME) #define HAVE_FTIME # if __IBMCPP__ >= 400 @@ -120,6 +116,7 @@ struct PerfCounter #endif // __WXMSW__ const int MILLISECONDS_PER_SECOND = 1000; +const int MICROSECONDS_PER_MILLISECOND = 1000; const int MICROSECONDS_PER_SECOND = 1000*1000; } // anonymous namespace @@ -265,14 +262,43 @@ long wxGetUTCTime() #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 -wxLongLong wxGetLocalTimeMillis() +wxLongLong wxGetUTCTimeMillis() { wxLongLong val = 1000l; // If possible, use a function which avoids conversions from // broken-up time structures to milliseconds - #if defined(__WXPALMOS__) DateTimeType thenst; thenst.second = 0; @@ -285,23 +311,16 @@ wxLongLong wxGetLocalTimeMillis() uint32_t now = TimGetSeconds(); uint32_t then = TimDateTimeToSeconds (&thenst); return SysTimeToMilliSecs(SysTimeInSecs(now - then)); -#elif defined(__WXMSW__) && (defined(__WINE__) || defined(__MWERKS__)) - // This should probably be the way all WXMSW compilers should do it - // Go direct to the OS for time - - 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 - +#elif defined(__WXMSW__) + FILETIME ft; + ::GetSystemTimeAsFileTime(&ft); + + // 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) struct timeval tp; if ( wxGetTimeOfDay(&tp) != -1 ) @@ -323,32 +342,6 @@ wxLongLong wxGetLocalTimeMillis() val *= tp.time; return (val + tp.millitm); #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 - - // 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 // do NOT just shut off these warnings, drop me a line instead at // @@ -360,13 +353,17 @@ wxLongLong wxGetLocalTimeMillis() #else #warning "wxStopWatch will be up to second resolution!" #endif // compiler -#endif + val *= wxGetUTCTime(); return val; - #endif // time functions } +wxLongLong wxGetLocalTimeMillis() +{ + return wxGetUTCTimeMillis() - wxGetTimeZone()*MILLISECONDS_PER_SECOND; +} + #else // !wxUSE_LONGLONG double wxGetLocalTimeMillis(void)