2017-08-02 13 views
2
uint64_t timestamp_nanoseconds = 634019142119225390; 
time_t result = timestamp_nanoseconds/1000000000; 
struct tm * timeinfo = gmtime(&result); 
struct tm dateInfo ; 
dateInfo.tm_mday = timeinfo->tm_mday ; 
dateInfo.tm_mon = timeinfo->tm_mon ; 
dateInfo.tm_year = timeinfo->tm_year ; 
dateInfo.tm_hour = 0 ; 
dateInfo.tm_min = 0 ; 
dateInfo.tm_sec = 0 ; 
time_t NoOfSecInDate = mktime (&dateInfo); 

入力タイムスタンプ(ナノ秒単位)から、dateInfo構造体に設定されたコードのように日付を取得できます。その時点から、入力日付の真夜中から経過時間を秒単位で見つける必要があります。C++のmktimeに替わる

1970年1月1日から経過時間がナノ秒単位で入力されます。たとえば、634019142119225390と言ってください。時刻を00:00:00に設定してから、経過時間を符号なし整数で表す必要があります1970年1月1日のUnixエポック00:00 UTCからの経過時間(ナノ秒単位)。

解決策は、指定されたタイムスタンプで、現在の日付ではありません。この上記のコードで

、我々ははmktime関数は時間がたくさんあると

を期待されていない完了するまでに約64マイクロ秒かかることがわかりますが返す同じ結果を達成機能をはmktimeするために、他の選択肢を持っていますかエポックからの経過時間を秒単位で表したものですが、時間はそれほどありません。

+1

私は理解できません - あなたはtime_tで始まり、tmに入れてから、mktimeを使って、あなたが始めた情報からtime_tを得るのですか?なぜ、あなたが始めなければならなかった 'result' time_tを使用しないのですか? – doctorlove

答えて

0

あなたは、同じUTCの日の開始時に時間を取得しようとしています。これを行うには、あなたはわずか数秒で計算を行うことができます:あなたはあなたの地域のタイムゾーンで一日のスタートを取得したい場合は

calc took 0 sec 1 usec. total 0.000000 
UTC: Sat Feb 3 04:25:42 1990 
Day: Sat Feb 3 00:00:00 1990 

あなたが追加することができます。

struct timezone tz = {0, 0}; 
struct timeval start, end; 

gettimeofday(&start, &tz); 
uint64_t timestamp_nanoseconds = 634019142119225390ULL; 
time_t result = timestamp_nanoseconds/1000000000ULL; 
time_t day = result - (result % 86400); 
gettimeofday(&end, &tz); 

struct timeval dsec; 
timersub(&end, &start, &dsec); 
printf("calc took %ld sec %ld usec.\n", 
    dsec.tv_sec, dsec.tv_usec, s); 

printf("UTC: %s",asctime(gmtime(&now))); 
printf("Day: %s",asctime(gmtime(&day))); 

これははるかに少ない時間がかかりますdayの計算へのオフセット。

+0

入力タイムスタンプ(ナノ秒単位)から、dateInfo構造体に設定されたコードに示すように、日付を取得できます。その時点から、現在の日付ではなく、入力日付の真夜中からの経過時間を秒単位で見つける必要があります。 –

+0

サンプルデータの計算を表示するように変更されました。 – stark

1

これは、<chrono>Howard Hinnant's free, open-source, date-time libraryで非常に効率的に行うことができます。考える

uint64_t timestamp_nanoseconds = 634019142119225390; 

フォームstd::chrono::time_pointsystem_clocknanosecondsに基づきます。あなたがdays精度time_pointに、このナノ秒精度time_pointを切り捨てることができます

sys_time<nanoseconds> ts{nanoseconds{timestamp_nanoseconds}}; 

次:日時ライブラリは、このような種類のテンプレートタイプの別名を持つ非常に簡単なことになり

auto sd = floor<days>(ts); 

sdですエポック(ナノ秒ではなく)からのカウント日数はsystem_clocktime_pointです。各フィールドのgetterと{year, month, day}構造体:次に、あなたがそれのように聞こえる、まさにである、year_month_daysdを変換することができ

year_month_day ymd = sd; 

そして、この質問に関連する部分、これはあなたが午前0時からナノ秒を取得する方法です。 012からどこへ行く

auto tod = ts - sd; 

そして、あなたは秒単位であることをしたい場合は、それがすべてで

auto tod = duration_cast<seconds>(ts - sd); 

、現在の日付(UTC)で秒ナノ秒のカウント、および時間も、それは次のとおりです。

:634019142119225390の入力を考えると

auto t0 = steady_clock::now(); 
sys_time<nanoseconds> ts{nanoseconds{timestamp_nanoseconds}}; 
auto tod = duration_cast<seconds>(ts - floor<days>(ts)); 
auto t1 = steady_clock::now(); 

、および-O3でMacOSで、この使用して打ち鳴らすコンパイル、これは、その結果

tod == 15942s 

と約200nsかかります。

duration_cast<days>ではなく、floor<days>を使用しているため、この指定は正のと負の入力の両方に対して正しく機能します。例えば、-1'000'000'000の入力は、86399sの時刻を与​​える。