2016-09-01 37 views
2

BusyBox組み込みLinux上で動作するC++コードをプログラミングしています。私のコードとライブラリには、現在の時刻を取得するためのstd::chrono::system_clock::now()への呼び出しがいくつかあります。OSが設定した時間帯を考慮してstd :: chrono :: system_clock :: now()

これで私のボックスはdafaultタイムゾーン(UTC)として設定されていたので、すべて正常に動作し、結果はOKです。

今、別のタイムゾーンにとどまるために自分のlinuxを設定しなければなりませんでした。私はdateコマンドとコンソールを発行すると、私は正確な時刻を取得

export TZ=UTC+3 

、それでもUTC時刻、時間ではなくなってstd::chrono::system_clock::now() - 私に私の呼び出し:それから私はボックス/etc/profileに設定することで、それをやりましたdateコマンド(正しい時刻)に表示されます。

私のnow()コールをすべて変更したくない - その上に何百というものがあります...それが原因で、自分のプロセスが正しい時間よりも別の時間で動作するようになりました。

私のコードを変更することなく解決する方法はありますか?私はここで行方不明のものは何ですか?

ありがとうございます。

+0

:必要に応じて、一つはその文字列を記録することができ、そしてその後それは、コンピュータの現在のタイムゾーンでない場合であっても、その名前でtime_zoneを使用しています。それを人間のユーザーに表示するときは、現地時間に変換してください。プログラムはUTCでは完璧ですが、サーカディアンのリズムは気にしません。 –

+0

n.m. - now()から収集されたデータは、int64形式を使用してローカルおよびクラウドデータベースに格納され、Webサーバーにアップロードされます。最終的なユーザーに表示されます....私は上記のレイヤーでタイムゾーンのトラックを持っていないので、私はデータベースに格納する前に私のC + +コードで正しい時間を取得する必要があります。 – Mendes

+0

@mendesああ神、クラウドデータベースに現地時間を格納しないでください。 *多分*ユーザーが何らかのイベントを設定したときに使用するタイムゾーンを格納する* *ユニバーサルタイムスタンプ(カレンダーアプリケーションの場合、12月7日と7時を選んだ場所)*ローカルタイムはほとんどすべてのケースでユーザーの入力と出力。その場合(選択された時間帯)は、ユーザが何らかの意味で(時間、実際の出来事、または「今から6時間」という意味ではなく)絶対的な時刻*を選んだときです。 – Yakk

答えて

6

標準では指定されていませんが、std::chrono::system_clock::now()のすべての実装では、Unix Timeのトラッキングが行われていますが、これはUTCに非常に近い値です。あなたは現地時間にstd::chrono::system_clock::now()を翻訳したい場合は

、あなたはどちらかsystem_clock::to_time_t経由time_tsystem_clock::time_pointを翻訳することができ、その後、C APIを介して(例えばlocaltimeを)あなたのように動作するか、上に構築され、この近代的なタイムゾーンのライブラリを試してみてください<chrono>のトップ:

https://howardhinnant.github.io/date/tz.html

あなたはこのような現在のローカルタイムを取得するためにこれを使用します。

#include "tz.h" 
#include <iostream> 

int 
main() 
{ 
    using namespace date; 
    using namespace std::chrono; 
    auto t = make_zoned(current_zone(), system_clock::now()); 
    std::cout << t << '\n'; 
} 

make_zonedは、zoned_timeタイプを返すファクトリ関数です。system_clockがサポートしています。ナノ秒)。 time_zonesystem_clock::time_pointのペアです。

あなたはこのようstd::chrono::time_pointあるlocal_time<Duration>を取得することができます:ライブラリが自動的にIANA timezone databaseをダウンロードするには、リモートAPIを持ってい

auto t = make_zoned(current_zone(), system_clock::now()); 
    auto lt = t.get_local_time(); 
    std::cout << lt.time_since_epoch().count() << '\n'; 

ものの、そのAPIは-DHAS_REMOTE_API=0でコンパイルすることにより無効にすることができます。これはすべてinstallation instructionsに詳述されています。リモートAPIを無効にすると、IANA timezone database(それはちょうどtar.gzです)からデータベースを手動でダウンロードする必要があります。あなたはこのように得ることができ、現在のUTCオフセット、必要な場合は

:上記のスニペットで

auto t = make_zoned(current_zone(), system_clock::now()); 
    auto offset = t.get_info().offset; 
    std::cout << offset << '\n'; 

を、私はoffsetを印刷する同じgithubのリポジトリで発見"chrono_io.h"の利点を取っています。offsetのタイプはstd::chrono::secondsです。私にとってこれだけの出力:

-14400s 

(-0400)あなたの現在のタイムゾーンのIANA名を検出したい場合は

最後に、それは単純です:

私にとって
std::cout << current_zone()->name() << '\n'; 

ただ出力:

America/New_York 

name()から返されたタイプがstd::stringです。内部的にUTC以外のものを使用するのは間違いだろう

auto tz_name = current_zone()->name(); 
// ... 
auto t = make_zoned(tz_name, system_clock::now()); // current local time in tz_name 
+0

文字列は必要ありませんが、元のnow()と同じ形式ですが、正しいタイムゾーンを表す時計が必要です。ライブラリに何らかの外部アクセスが必要な場合、組み込みシステム上のインターネット接続はありません。 – Mendes

+0

@Mendes:あなたの懸念に対処するために更新された答え。 –

関連する問題