5

メッセージをUTCで保存しています。したがって、誰かが以前のメッセージを振り返った場合、タイムスタンプを、当時のタイムゾーンに対する相対的な時間に変換できる必要があります。当時のタイムゾーンを取得するにはどうすればよいですか?

たとえば、2012 年 9 月 3 日のタイムゾーンは PDT です。現在のタイム オフセットは -0700 です。9:06にメッセージを送信します。時刻は UTC 16:06 です。

2012 年 12 月 1 日のこのメッセージに戻ります。現在のタイムゾーンは PST です。現在のタイム オフセットは -0800 です。2012 年 9 月 3 日に送信したメッセージを確認します。現在のタイム オフセットを使用して UTC から変換すると、メッセージが送信されたときではない 8:06 になります。9:06に送信されました。

したがって、2012 年 9 月 3 日のタイムゾーンが PST ではなく PDT であったことを確認する方法が必要です。

ライブラリのないPSが最高です、ありがとう。

4

3 に答える 3

3

C++実行中に個別のタイムゾーンを使用する必要がない単純なアプリケーションの場合は、それを使用して特定のタイムゾーン情報を含むlocaltime共有参照を取得できます。システムが PST のタイムゾーンで構成されている場合、 を呼び出すと、表示に太平洋のタイムゾーン情報が使用されます。例では、2012 年 1 月 1 日 (GMT) と 2012 年 6 月 1 日を使用しています。struct tm *time_tlocaltime

time_t def_time = 1325376000;
struct tm *a_tim = localtime(&def_time);
printf("%s %ld %d\n", a_tim->tm_zone, a_tim->tm_gmtoff, a_tim->tm_isdst);
def_time = 1338505200;
a_tim = localtime(&def_time);
printf("%s %ld %d\n", a_tim->tm_zone, a_tim->tm_gmtoff, a_tim->tm_isdst);

私のシステム (TZ=Europe/Dublin) では、次のように表示されます。

GMT 0 0
IST 3600 1

TZ 環境変数を America/Los_Angeles でオーバーライドすると、次のようになります。

PST -28800 0
PDT -25200 1

つまり、システムはタイムゾーン名、GMT からのオフセット、UTC タイムスタンプからサマータイムが有効かどうかを判断できます。

編集: posix が提供するタイムゾーン ルーチンを使用して、C/C++ プログラム内で複数のタイムゾーンを同時に使用しようとするのは恐ろしいことです。

于 2012-09-03T17:04:40.873 に答える
3

Boost Date_timeはそれを行います。これは私がぶらぶらしていた単純な例です(以下のコード):

edd@max:~/src/progs/C++$ g++ -o boost_posix_time_dst boost_posix_time_dst.cpp
edd@max:~/src/progs/C++$ ./boost_posix_time_dst 
DST ran from 2012-Mar-11 02:00:00 to 2012-Nov-04 02:00:00
DST shortcut PDT
DST name     Pacific Daylight Time
edd@max:~/src/progs/C++$ 

日付 (2012 年 12 月 1 日) を形成し、それが特定の間隔内にあるかどうかを確認する機能もあります (ここでは DST の開始と終了によって形成されます)。

日付を作成して isDST() ブール値をチェックすることでも取得できると思います。

私のショートプログラムは以下です。csv ファイルのローカル コピーが必要です。これは、a) Boost ソースと b) タイムゾーンを扱う多くのサイトにあります (たとえば、Google の最初または 2 番目のヒットは CERN で見つかります)。

#include <iostream>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/date_time/posix_time/posix_time_io.hpp>
#include <boost/date_time/gregorian/gregorian.hpp>  
#include <boost/date_time/local_time/local_time.hpp>     

using namespace boost::posix_time;
using namespace boost::gregorian;

int main(int argc, char **argv) {

  boost::local_time::tz_database tz;
  tz.load_from_file("/tmp/date_time_zonespec.csv");

  boost::local_time::time_zone_ptr tzp =
            tz.time_zone_from_region("America/Los_Angeles");    

  int year = 2012;
  boost::posix_time::ptime t1 = tzp->dst_local_start_time(year);
  boost::posix_time::ptime t2 = tzp->dst_local_end_time(year);
  std::cout << "DST ran from " << t1 << " to " << t2 << std::endl;
  std::cout << "DST shortcut " << tzp->dst_zone_abbrev() << std::endl;
  std::cout << "DST name     " << tzp->dst_zone_name() << std::endl;

}
于 2012-09-03T16:27:19.010 に答える
0

現在のオフセットを知るだけでは、同じ場所の別の時期のオフセットを知るには不十分です。1 年の一部だけタイムゾーンを共有する場所のペアがたくさんあります (中央ヨーロッパとアルジェリア、または米国東部とコロンビアなど)。

最も簡単な修正方法は、メッセージと共にタイムゾーンを保存することです。

于 2012-09-03T16:25:16.610 に答える