我正在努力想出一个最初看起来并不难的两个问题的答案。 Q1:如何获取UTC.Now()和给定日期之间经过的秒数? A1:就像下面的代码一样! Q2:如何确定自上一次“完整”秒后经过的小数秒数?我想打印“total_elapsed_seconds.fractional_seconds” - > “1234124.45”。我怎么做? A2:???
#include <iostream>
#include <boost/date_time/gregorian/gregorian.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
using namespace std;
using namespace boost::gregorian;
using namespace boost::posix_time;
void main()
{
ptime Jan1st1970(date(1970, 1, 1));
for(int i = 0; i < 10; i++)
{
ptime Now = second_clock::universal_time();
time_duration diff = Now - Jan1st1970;
cout << Now << " : " << diff.total_seconds() << "." << diff.fractional_seconds() << endl;
}
}
答案 0 :(得分:8)
您正在使用second_clock
获取当前时间。顾名思义,它仅精确到最接近的秒。由于您的参考时间没有小数秒,因此持续时间小数秒始终为0.请改为使用microsec_clock
:
ptime Now = microsec_clock::universal_time();
另外,在如此紧凑的循环中,我不希望每次迭代都更新时钟,所以你可能还想从boost :: thread添加一个sleep:
boost::this_thread::sleep(boost::posix_time::milliseconds(25));
答案 1 :(得分:2)
你没有提到你使用的操作系统,但我知道窗口的时钟不会给你提供超过15毫秒的分辨率(除非你真的玩一些游戏)。
但是,Windows具有所谓的性能计时器,可以为您提供纳秒级别的分辨率。它实际上只是CPU循环次数的计数器(您可以除以CPU的频率来获取时间),因此要将其用作时钟,您必须将该时间添加到已知时间:
ptime Start = microsec_clock::universal_time();
initMyClockToZero(); // You have to write this to use the performance timer
.... do something ....
int64 microseconds = getMyClockMicrosec(); // this too
ptime Now = Start + posix_time::microseconds(microseconds);
我还有一个秒表式的计时器,我是用自己的Windows编写的。
#ifndef STOPWATCH_HPP
#define STOPWATCH_HPP
#include <iostream>
#include <windows.h>
//! \brief Stopwatch for timing performance values
//!
//! This stopwatch class is designed for timing performance of various
//! software operations. If the values you get back a greater than a
//! few seconds, you should be using a different tool.
//! On a Core 2 Duo E6850 @ 3.00GHz, the start/stop sequence takes
//! approximately 230 nano seconds in the debug configuration and 180
//! nano seconds in the release configuration. If you are timing on the
//! sub-microsecond scale, please take this into account and test it on
//! your machine.
class Stopwatch{
public:
//! \param start if set to true will initialize and then start the
//! timer.
Stopwatch(bool start=false){
_start.QuadPart = 0;
_stop.QuadPart = 0;
if(start)
Start();
}
//! Starts the stopwatch running
void Start(){
QueryPerformanceCounter(&_start);
}
//! Run this when the event being timed is complete
void Stop(){
QueryPerformanceCounter(&_stop);
}
//! Stops the timer and returns the result
double StopResult(){
Stop();
return ResultNanoseconds();
}
//! You can get the result of the stopwatch start-stop sequence at
//! your leisure.
double ResultNanoseconds(){
LARGE_INTEGER frequency;
QueryPerformanceFrequency(&frequency);
double cyclesPerNanosecond = static_cast<double>(frequency.QuadPart) / 1000000000.0;
LARGE_INTEGER elapsed;
elapsed.QuadPart = _stop.QuadPart - _start.QuadPart;
return elapsed.QuadPart / cyclesPerNanosecond;
}
void PrintResultNanoseconds(){
std::cout << ResultNanoseconds() << "nanosec" << std::endl;
}
void PrintResultMicroseconds(){
std::cout << ResultNanoseconds()/100 << "microsec" << std::endl;
}
void PrintResultMilliseconds(){
std::cout << ResultNanoseconds()/100000 << "millisec" << std::endl;
}
void PrintResultSeconds(){
std::cout << ResultNanoseconds()/1000000000 << "sec" << std::endl;
}
private:
LARGE_INTEGER _start;
LARGE_INTEGER _stop;
};
#endif STOPWATCH_HPP
答案 2 :(得分:1)
这听起来确实合理,但输出给了我:
2009-May-28 20:14:32 : 1243541672.0
2009-May-28 20:14:32 : 1243541672.0
2009-May-28 20:14:32 : 1243541672.0
2009-May-28 20:14:32 : 1243541672.0
2009-May-28 20:14:32 : 1243541672.0
2009-May-28 20:14:32 : 1243541672.0
2009-May-28 20:14:32 : 1243541672.0
2009-May-28 20:14:32 : 1243541672.0
2009-May-28 20:14:32 : 1243541672.0
2009-May-28 20:14:32 : 1243541672.0
Press any key to continue . . .
事实上,我期待更多数字 - 我希望得到10 ^( - 6)[秒]范围内的结果。
答案 3 :(得分:0)
将此添加到您的示例中以获取“当前”小数秒:
cout << Now.time_of_day().fractional_seconds() << endl;
将时钟从second_clock更改为microsec_clock以获得非零小数秒。
ptime Now = microsec_clock::universal_time();