4 Stimmen

C++ :: Boost :: posix_time (verstrichene Sekunden. verstrichene Bruchteile von Sekunden)

Ich versuche, eine Antwort auf zwei Fragen zu finden, die anfangs nicht schwer zu sein schienen. F1 : Wie erhalte ich die Anzahl der verstrichenen Sekunden zwischen UTC.Now() und einem bestimmten Datum? A1 : Genau wie in dem unten stehenden Code! Q2 : Wie ermittle ich, wie viele Sekundenbruchteile seit der letzten "vollen" Sekunde verstrichen sind? Ich möchte die "total_elapsed_seconds.fractional_seconds" -> "1234124.45" ausgeben. Wie kann ich das tun? 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;
    }
}

8voto

zdan Punkte 27066

Sie verwenden die second_clock um die aktuelle Zeit zu erhalten. Wie der Name schon sagt, ist sie nur auf die nächste Sekunde genau. Da Ihre Referenzzeit keine Sekundenbruchteile hat, ist die Dauer der Sekundenbruchteile immer 0. Verwenden Sie die microsec_clock stattdessen:

ptime Now = microsec_clock::universal_time();

Außerdem würde ich in einer solch engen Schleife nicht erwarten, dass die Uhr bei jeder Iteration aktualisiert wird, so dass Sie vielleicht auch einen Sleep von boost::thread hinzufügen möchten:

boost::this_thread::sleep(boost::posix_time::milliseconds(25));

2voto

teeks99 Punkte 3423

Sie erwähnen nicht, welches Betriebssystem Sie verwenden, aber ich weiß mit Sicherheit, dass die Windows-Uhr Ihnen keine bessere Auflösung als etwa 15 Millisekunden liefert (es sei denn, Sie spielen wirklich einige Spiele).
Windows verfügt jedoch über einen so genannten Performance-Timer, der eine Auflösung im Nanosekundenbereich ermöglicht. Es ist wirklich nur ein Zähler, wie oft die CPU-Zyklen (Sie können durch die CPU-Frequenz dividieren, um Zeit zu erhalten), so dass, um es als Uhr zu verwenden, müssen Sie diese Zeit zu einer bekannten Zeit zu addieren:

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);

Ich habe auch einen Timer im Stil einer Stoppuhr, den ich mit Hilfe der Windows-Aufrufe selbst geschrieben habe.

#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

1voto

Das klingt in der Tat vernünftig, aber die Ausgabe gibt mir :

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 . . .

In Wahrheit hatte ich mehr Ziffern erwartet - ich hoffe auf ein Ergebnis im Bereich 10 ^ (-6) [sec].

0voto

lothar Punkte 19157

Fügen Sie dies zu Ihrem Beispiel hinzu, um die "aktuellen" Sekundenbruchteile zu erhalten:

cout << Now.time_of_day().fractional_seconds() << endl;

Und ändern Sie die Uhr von second_clock in microsec_clock, um Sekundenbruchteile zu erhalten, die nicht Null sind.

ptime Now = microsec_clock::universal_time();

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X