2011-01-28 14 views
6

boost::posix_time::ptimeboost::int64_tとしてネットワーク経由で転送したいと考えています。 A way to turn boost::posix_time::ptime into an __int64によれば、自分でエポックを簡単に定義でき、その参照エポックからのtime_durationのみを64ビット整数として転送できます。しかし、ptimeに戻すにはどうすればいいですか?int64_tをtime_durationに変換する

#include <iostream> 
#include <cassert> 
#include <boost/date_time/posix_time/posix_time.hpp> 
#include <boost/date_time/gregorian/greg_month.hpp> 

using namespace std; 

using boost::posix_time::ptime; 
using boost::posix_time::time_duration; 
using boost::gregorian::date; 

int main(int argc, char ** argv){ 
    ptime t = boost::posix_time::microsec_clock::local_time(); 

    // convert to int64_t 
    ptime myEpoch(date(1970,boost::gregorian::Jan,1)); 
    time_duration myTimeFromEpoch = t - myEpoch; 
    boost::int64_t myTimeAsInt = myTimeFromEpoch.ticks(); 

    // convert back to ptime 
    ptime test = myEpoch + time_duration(myTimeAsInt); 

    assert(test == t); 
    return 0; 
} 

これは、引数がプライベートであるようチック・カウントを取るtime_durationコンストラクタ以来、機能していません。単純なデータ型の上に単にptimeを転送する他の方法にも興味があります。ミリ秒の分解能を持つ

+1

マシン間でticks()の戻り値が返されますか?正規化するにはticks_per_second()を使用する必要があります。 myEpochが両端で同じ場合、なぜ64ビットのミリ秒のエポックタイムスタンプを転送できないのですか? – hplbsh

+0

ミリ秒の解像度で動作しています。あなたは答えとしてあなたのコメントを投稿できますか? – tibur

答えて

5

作業溶液:

int main(int argc, char ** argv){ 
    ptime t = boost::posix_time::microsec_clock::local_time(); 

    // convert to int64_t 
    ptime myEpoch(date(1970,boost::gregorian::Jan,1)); 
    time_duration myTimeFromEpoch = t - myEpoch; 
    boost::int64_t myTimeAsInt = myTimeFromEpoch.total_milliseconds(); 

    // convert back to ptime 
    ptime test = myEpoch + boost::posix_time::milliseconds(myTimeAsInt); 

    cout << test << endl; 
    cout << t << endl; 

    time_duration diff = test - t; 

    assert(diff.total_milliseconds()==0); 
    return 0; 
} 

おかげ12a6。

+3

私はこの答えは32ビットシステムでは動作しないと思います。私は1901-01-01 00:00:00のエポックを使用して32ビットシステムでこれを試しましたが、動作しません。明らかにそれはあなたのために働くが、 'milliseconds()'への引数はlong型で、 'total_milliseconds()'からの戻り値はlong型であるため、int64_tからlongへの暗黙のキャストで何も失われません。 – mathematician1975

+0

これは、プラットフォームに関係なく64ビット長のコンパイラでのみ動作します。 32ビットMSVCでは、longは32ビットです。 –

2

あなたboost::datetimeライブラリが(通常はミクロス/またはnanos)にコンパイルされているものの最大解像度で動作します:

time_duration time_duration_from_ticks(time_duration::tick_type ticks) 
{ 
    return time_duration(
     0,           // hours 
     0,           // minutes 
     ticks/time_duration::ticks_per_second(), // seconds 
     ticks % time_duration::ticks_per_second()); // fractional_seconds 
} 

(、time_duration::tick_typeはあなたが唯一のマイクロ秒の分解能でブースト日時を設定している場合は、あなたのint64_tであることに注意してくださいこれはデフォルトです)

+1

しかし、私のWindows 7 VS2013コンパイラでは、 'seconds'引数は32ビットでなければなりません。したがって、2038問題はこの解決策には依然として存在します。 –

+0

私はダムでなければなりませんが、なぜそれが32ビットでなければならないのか分かりません.'ticks'は64ビット(32ビットアーチでさえ)になります。 –

+2

この特定のコンストラクタを 'time_duration'に見ると、3番目のパラメータは32ビットと定義されています。実際には、私はこのコンストラクタを使用していますが、日付は間違っています。まさに2038年の問題を予期するものです。しかし、それは簡単に行うことができ、ミリ秒を使用して2038問題を避けることができます。実際の答えはhttp://stackoverflow.com/a/26211377/368896を参照してください。 –

0

マイクロ秒の分解能TIME_DURATION付:。

boost::posix_time::microseconds(_ts/TICKS_PER_MICROSECOND) 

ここで、TICKS_PER_MICROSECONDはマイクロ秒当たりのティック数です(たとえば、ティックがヘクトナンセンスの場合は10、Windows FILETIMEのように10です)。

ミリ秒のコンストラクタが一部の人にとってうまくいくように見える理由は、longのパラメータ型を受け入れるということです。これは、一部のコンパイラでは64ビットです。 MSVCでは32ビットプラットフォームでは32ビットなので、動作しません。マイクロ秒のコンストラクタは64ビット整数を受け取ります。これは「すべての人にとって十分」でなければなりません。

関連する問題