I know I can use boost::gregorian::date_duration for time intervals in days, and boost::posix_time::time_duration for time intervals, but is there a simple data type I can use for anything from seconds to many days of time interval?
What are the limits (max duration) to boost::posix_time::time_duration ?
From the documentation:
By default the posix_time system uses a 64 bit integer and a 32 bit integer internally to provide nano-second level resolutions -- 96 bits for each time value. As an alternative, a single 64 bit integer can be used to provide a microsecond level resolution. This alternative implementation may provide better performance and more compact memory usage for many applications that do not require nano-second resolutions.
and
The variable BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG, as defined in build/Jamfile, selects between these options. To select the 64 bit integer implementation simply remove this define from the Jamfile.
So as far as you're probably concerned, DevSolar's answer summarizes it nicely at the end.
"POSIX time" usually means "seconds since January 1st, 1970", which is good until about 2037 if you're using a 32-bit value, much longer if you are using 64 bit. So without looking at the exact specs of Boost, I wouldn't worry too much about the limits of boost::posix_time::time_duration.
Related
Will QueryPerformanceCounter return the correct value for 32-bit computer that is up for more than month or even a couple of months or years?
Thanks
Microsoft guarantees that QueryPerformanceCounter will not roll over sooner than 100 years from boot: quoting https://learn.microsoft.com/en-us/windows/win32/sysinfo/acquiring-high-resolution-time-stamps#general-faq-about-qpc-and-tsc
How often does QPC roll over?
Not less than 100 years from the most recent system boot, and potentially longer based on the underlying hardware timer used. For most applications, rollover isn't a concern.
You cannot deduce this just from the fact that QueryPerformanceCounter produces a 64-bit value. The hardware clock used to implement QPC could have a much smaller range, and Windows could just be zero-extending that clock to 64 bits. This is particularly plausible on the older 32-bit systems you were asking about. Only explicit documentation of the rollover interval should be relied on.
The C++ Draft par 20.12.7.3 reads:
high_resolution_clock may be a synonym for system_clock or steady_clock
Of course this may mandates nothing but I wonder :
Is there any point for high_resolution_clock to something other that a typedef ?
Are there such implementations ?
If a clock with a shorter tick period is devised it can either be steady or not steady. So if such a mechanism exists, wouldn't we want to "improve" system_clock and high_resolution_clock as well, defaulting to the typedef solution once more ?
The reason that specs have wording such as "may" and "can", and other vague words that allow for other possibilities comes from the wish by the spec writers not wanting to (unnecessarily) limit the implementation of a "better" solution of something.
Imagine a system where time in general is counted in seconds, and the system_clock is just that - the system_clock::period will return 1 second. This time is stored as a single 64-bit integer.
Now, in the same system, there is also a time in nano-seconds, but it's stored as a 128-bit integer. The resulting time-calculations are slightly more complex due to this large integer format, and for someone that only needs 1s precision for their time (in a system where a large number of calculations on time are made), you wouldn't want to have the extra penalty of using high_precision_clock, when the system doesn't need it.
As to if there are such things in real life, I'm not sure. The key is that it's not a violation to the standard, if you care to implement it such.
Note that steady is very much a property of "what happens when the system changes time" (e.g. if the outside network has been down for a several days, and the internal clock in the system has drifted off from the atomic clock that the network time updates to). Using steady_clock will guarantee that time doesn't go backwards or suddenly jumps forward 25 seconds all of a sudden. Likewise, there is no problem when there is a "leap second" or similar time adjustment in the computer system. On the other hand, a system_clock is guaranteed to give you the correct new time if you give it a forward duration past a daylight savings time, or some such, where steady_clock will just tick along hour after hour, regardless. So choosing the right one of those will affect the recording of your favourite program in the digital TV recorder - steady_clock will record at the wrong time [my DTV recorder did this wrong a few years back, but they appear to have fixed it now].
system_clock should also take into account the user (or sysadmin) changing the clock in the system, steady_clock should NOT do so.
Again, high_resolution_clock may or may not be steady - it's up to the implementor of the C++ library to give the appropriate response to is_steady.
In the 4.9.2 version of <chrono>, we find this using high_resolution_clock = system_clock;, so in this case it's a direct typedef (by a different name). But the spec doesn't REQUIRE this.
Here's what I'd need to do:
double now=getdoubletimestampsomehow();
Where getdoubletimestampsomehow() should be a straight-forward, easy to use function returning a double value representing the number of seconds elapsed from a given date. I'd need it to be quite precise, but I don't really need it to be more precise than a few milliseconds. Portability is quite important, if it isn't possible to directly port it anywhere could you please tell me both an unix and a windows way to do it?
Have you looked at Boost and particularly its Date_Time library ? Here is the seconds since epoch example.
You will be hard-pressed to find something more portable, and of higher resolution.
Portable good precision double timestamp in C++?
There is no portable way to get high-precision timestamp (milliseconds) without using 3rd party libraries. Maximum precision you'll get is 1 second, using time/localtime/gmtime.
If you're fine with 3rd party libraries, use either Boost or Qt 4.
both an unix and a windows way to do it?
GetSystemTime on Windows and gettimeofday on linux.
Please note that if you're planning to use timestamps to determine order of some events, then it might be a bad idea. System clock might have very limited precision (10 milliseconds on windows platform), in which case several operations performed consequently can produce same timestamp. So, to determine order of events you would need "logical timestamps" ("vector clock" is one of examples).
On windows platform, there are highly precise functions that can be used to determine how much time has passed since some point in the past (QueryPerformanceCounter), but they aren't connected to timestamps.
C++11 introduced the <chrono> header containing quite a few portable clocks. The highest resolution clock among them is the std::chrono::high_resolution_clock.
It provides the current time as a std::chrono::time_point object which has a time_since_epoch member. This might contain what you want.
Reference:
Prior to the release of the C++11 standard, there was no standard way in which one could accurately measure the execution time of a piece of code. The programmer was forced to use external libraries like Boost, or routines provided by each operating system.
The C++11 chrono header file provides three standard clocks that could be used for timing one’s code:
system_clock - this is the real-time clock used by the system;
high_resolution_clock - this is a clock with the shortest tick period possible on the current system;
steady_clock - this is a monotonic clock that is guaranteed to never be adjusted.
If you want to measure the time taken by a certain piece of code for execution, you should generally use the steady_clock, which is a monotonic clock that is never adjusted by the system. The other two clocks provided by the chrono header can be occasionally adjusted, so the difference between two consecutive time moments, t0 < t1, is not always positive.
Doubles are not precise - therefore you idea for double now=getdoubletimestampsomehow(); falls down at the first hurdle.
Others have mentioned other possibilities. I would explore those.
I'm going to be developing a small dedicated server in C/C++ that will require uptime of forever. I've been looking into some time functions as millisecond timing is required for calculations. I have 2 problems that I'm facing:
Using a 32bit integer to store the number of milliseconds since the operation began will wrap around at about the 49 days mark resetting to zero. I have thought about using 64 bit integers, using gettimeofday to retrieve microseconds but this brings me to the second part.
There doesn't seem to be any standard system calls for getting elapsed milliseconds that are platform independant
What should I do to resolve both these issues?
Use a 64bit integer, presuming that gives you enough time
You are correct; there is no standard. One possibility would be to use the Boost DateTime library, alternately find another or roll your own.
Good Luck!
As has already been said, the first problem you are going to confront is going to obtain a reliable millisecond-precise time.
I admit I am a bit phased by the question though.
I can understand the need for precise timing (millisecond level, even microsecond) but timing a 50days at a millisecond level seems... strange.
You should perhaps review your need first, but it is rare to need more than 6 or 7 significant digits... and I am afraid that you are trying to get a one size fit them all duration object.
Perhaps that you should instead classify your durations:
a few minutes at most > use millisecond precision
otherwise > use second precision (the famous count since Jan 1st 1970)
Because... what is the sense of 1/10 second at the scale of 2 months ?
Obvious. Use 64-bit integers with platform-specific code to get the number of milliseconds. On Unix including OSX, you want gettimeofday. On Windows, good luck getting a reliable millisecond-granularity time source; the code in the Tcl library to do this is really complex as there are some evil gotchas in the area.
answer to 1: If the "millisecond timing" that you are measuring is under around 20 days, you can subtract the times as unsigned values and check the result as signed value. This should give the right result with wrapping timers (wrapping from 0xffffffff to 0x00000000). If your timing is over 20 days, you need more bits.
I need to keep datetime in a C++ structure for an iPhone app. The time will be saved and restored into sqlite db. What is the best data type and corresponding API for this?
My candidates are:
time_t and struct tm from <ctime> and <time.h>
NSTimeInterval from <NSDate.h>
TimeValue from the QuickTime API
My instinct is to go with the good ole' C/C++ types from <time.h>. Any drawbacks down the road? Any other time type I miss that is a darling of the iPhone SDK?
NSTimeInterval and its CoreFoundation counterpart CFAbsoluteTime are the best values to use, as they include sub-millisecond accuracy (they're double-precision floating-point values). time_t and struct tm are only really used in certain BSD APIs (and struct timeval or struct timespec are more common there). TimeValue is only used to represent values and intervals within a media file, and is usually based on a configurable time base.
It depends completely upon what you are using the times for.
What precision do you need?
How many will be stored? (On average / worst case)
Store as much precision as you need, but no more. (But also think about future needs). You don't save appointment times to the nearest nanosecond - it doesn't make sense. However if you are recording some type of data where very small intervals are important, then you might save it to the precision of the system clock (often 100 nanosecond chunks), or even a bit finer than that to allow for future versions with better clocks.
If you are only storing small numbers (say less than a few thousand) then storage size and access speed are probably unimportant. If you are storing many records, then the size of the records may become important.
Apart from the above considerations, it doesn't really matter; as long as it is clearly documented.
I'm not familiar with the sqlite db. Does it have any native date/time type? If so, that is probably simplest -- as long as it meets your requirements.