linuxにおけるc++タイムゾーンの概要

6520 ワード

作成者mail:[email protected]
c++における時間は主にGMT時間とローカル時間に分けられる.GMT時間はグリニッジ時間、つまりUTC時間と呼ばれています.この時間は少し特殊で、その時間帯は0です.この時間帯では、ローカル時間とGMT時間が完全に一致しています.地球上の他の場所の時間はこの時間にタイムゾーンを加えなければなりません.これこそ他の場所のローカル時間です.地球は24時間区に分けられ、隣接する時間区は1時間差がある.例えば中国の上海は+8区で、もしグリニッジが今27日1時0分0秒ならば、中国の上海は27日の朝9時0分0秒です.私たちはグリニッジより8時間早く27日に入りました.具体的なタイムゾーン情報は『http://zh.wikipedia.org/wiki/タイムゾーンリスト」(タイムゾーンUTC-12からUTC+14)タイムゾーン情報は/usr/share/zoneinfo/に格納され、上海タイムゾーンファイルのように/usr/share/zoneinfo/ASia/shanghaiに格納されます.タイムゾーンは環境変数TZで設定でき、上海の場合はexport TZ=「Asia/Schanghai」で設定できます.c++プログラムでtzset()関数を呼び出すと、環境変数TZによってタイムゾーン情報を初期化できます.環境変数TZがない場合、tzset()は/etc/localtimeを使用してタイムゾーン情報を初期化します.TZ環境変数は、絶対パスを指すこともできるし、相対パスを指すこともできる.相対パスの場合は/usr/share/zoneinfo/を基準パスとします.
日光節約時間(daylight saving time;DST)は夏時間や夏時間制とも呼ばれ、夏に太陽が昇る時間が冬より早い(特に高緯度地域)ため、人々は日照を十分に利用して照明を節約するために電気を使うため、わざわざ時間を1時間持ち上げて民衆が早く眠れるようにする制度を日光節約時間と呼ぶ.台湾、香港、日本、アメリカ、ヨーロッパを含む世界100以上の国や地域で実行されていますが、中国大陸では実行されていないようです.struct tmにはtm_がありますisdstは日光節約時間を表し、0の場合は日光節約時間がないことを示し、0未満の場合はシステムのタイムゾーン情報に基づいて日光節約時間を実行するか否かを判断する.0より大きい場合は、加算すべき日光の節約時間を秒単位で表します.
c++には、GMTの1970-01-01 00:00:00+0000(UTC)という時間点が重要です.これは0時区の時間、すなわちグリニッジ時間またはUTC時間で、この時間学名はEpoch、新紀元と呼ばれています.どうしてこの時間は特別ですか?その時点でtime()関数を呼び出すと、返される値が0であることがわかりますから!今、私たちは勝手に調整して、帰ってきたのは10桁です.私は先ほど1309164941に変更しましたが、UTC時間の2011-06-27 08:55:45:41+0000(UTC)、中国時間の2011-06-27 16:55:41+7080(CST)です.7080は16進数で、10進数の28800秒、つまり8時間です.
c++の時間には,struct tmといういくつかのデータ構造が比較的よく用いられる.
           struct tm {
               int tm_sec;         /* seconds */
               int tm_min;         /* minutes */
               int tm_hour;        /* hours */
               int tm_mday;        /* day of the month */
               int tm_mon;         /* month */
               int tm_year;        /* year */
               int tm_wday;        /* day of the week */
               int tm_yday;        /* day in the year */
               int tm_isdst;       /* daylight saving time */
           };
           struct timeval {
               time_t      tv_sec;     /* seconds */
               suseconds_t tv_usec;    /* microseconds */
           };
           struct timezone {
               int tz_minuteswest;     /* minutes west of Greenwich */
               int tz_dsttime;         /* type of DST correction */
           };

c++のいくつかの重要な時間関数について説明します.
       time_t time(time_t *t);

これはおそらく最もよく使われる時間関数と言えるでしょう.この関数は、t!=NULLは、戻り値がtが指すメモリに埋め込まれる.注意:UTC標準の秒数を返します.グリニッジと上海でこの関数を同時に呼び出すと、この2つの値は同じで、グリニッジの現在の秒数で、タイムゾーンは計算されません.
       int gettimeofday(struct timeval *tv, struct timezone *tz);
       int settimeofday(const struct timeval *tv, const struct timezone *tz);

このtimevalは相対time_tより正確な時間は,微妙な数を含んでいる.tv_usecは最大999999、さらに1を加えると1秒、1秒を超えるとtv_にキャリーsec.timezoneは一般にNULLに転送され、linuxはtimezoneのtz_を処理していない.dsttime情報.
       struct tm *gmtime(const time_t *timep);
       struct tm *gmtime_r(const time_t *timep, struct tm *result);

この2つの関数は同じ意味でtime_tこの秒数はUTCタイムゾーンを基準とした年月日分秒時間に変換される.gmtime_rはスレッドが安全なので、これをお勧めします.gmtimeはstruct tm*を返し、このポインタは静的メモリを指し、この領域は常に変更されます.gmtime()を呼び出したばかりで、他のいくつかのコマンドを実行して、さっきgmtime()を使ってstruct tmを得ようとしたら、内容が間違っていることに気づいたので、危険で、私は霧の水にやられて、gdbが何度も経った後、このような状況であることに気づいて、gmtime_に変更しました.r後は問題ないgmtime_rは結果をあなたが入力したメモリに保存します.
       struct tm *localtime(const time_t *timep);
       struct tm *localtime_r(const time_t *timep, struct tm *result);

この2つの関数は意味も同じで、タイムゾーン情報に基づいてローカル時間を得て、上海でlocaltimeを同時に呼び出します.rとgmtime_rは発見するlocaltime_r得られる時間数は8より多くなります.私たちは+8区だからです.同様にlocaltime_を使用することを推奨します.rバージョン.
       time_t mktime(struct tm *tm);

タイムゾーン情報に基づいて計算されたstruct tmをtime_に変換tの秒数.算出される秒数はUTC時間を基準としており,time()を呼び出して得られる秒数と同じ概念である.このstruct tmは、上海時間2011-08-20 13:20:40などのローカル時間であり、struct tmの各値は、この時間にタイムゾーン情報が含まれているため、この時間の対応値である.グリニッジと上海で同じstruct tmに対してこの関数を呼び出すと、返される値が異なり、上海の値はグリニッジより8時間少ない.
ローカル時間とUTC時間の変換についても紹介します.ローカル時間はUTC時間に基づいてタイムゾーンと日光による時間節約により調整される.では,次のような関数と変数がローカル時間とUTC時間を変換する役割を果たす.
       void tzset (void);
       extern char *tzname[2];
       extern long timezone;
       extern int daylight;

具体的なコード:
    #include <time.h>
    tzset ();
    time_t current_timet;
    time(¤t_timet);//        
    struct tm utc_tm;
    gmtime_r (¤t_timet, &utc_tm);//  GMT, UTC  
    struct tm local_tm;
    localtime_r(¤t_timet, &local_tm);//      ,            8  。
    printf ("current_timet: %d, timezone info:[%d / %d]
", current_timet, timezone, daylight); printf ("utc_tm: %d-%d-%d %d:%d:%dZ
", utc_tm.tm_year, utc_tm.tm_mon, utc_tm.tm_mday, utc_tm.tm_hour, utc_tm.tm_min, utc_tm.tm_sec); printf ("local_tm: %d-%d-%d %d:%d:%d
", local_tm.tm_year, local_tm.tm_mon, local_tm.tm_mday, local_tm.tm_hour, local_tm.tm_min, local_tm.tm_sec); struct tm local_tm2 = utc_tm; local_tm2.tm_sec -= timezone; local_tm2.tm_isdst = daylight; // utc time_t local_timet2 = mktime(&local_tm2);// printf ("
local_timet2=%d
", local_timet2);// , 。daylight 。

苦痛な回顧、私はかつて以下のコードを書いたことがあります
time_t now;
time(&now);
DEBUG ("now:%d",now)
struct tm* timeNow = gmtime (&now);
    DEBUG ("timeNOw:sec=%d, min=%d, hour=%d, mday=%d, mon=%d, year=%d, wday=%d, yday=%d, isdst=%d",
           timeNow->tm_sec, timeNow->tm_min, timeNow->tm_hour, timeNow->tm_mday, timeNow->tm_mon,
           timeNow->tm_year, timeNow->tm_wday, timeNow->tm_yday, timeNow->tm_isdst);
struct tm tm1 = *timeNow;
    DEBUG ("tm1    :sec=%d, min=%d, hour=%d, mday=%d, mon=%d, year=%d, wday=%d, yday=%d, isdst=%d",
           tm1.tm_sec, tm1.tm_min, tm1.tm_hour, tm1.tm_mday, tm1.tm_mon,
           tm1.tm_year, tm1.tm_wday, tm1.tm_yday, tm1.tm_isdst);

その結果、予想外に印刷されました.timeNowとtm 1の内容は同じだと思いますが、tm_hourはなんと8違い.その後、DEBUG()で処理する時間があることがわかり、静的メモリが変更されました.しかし、DEBUG()のような関数の問題は誰が注目するだろうか.したがって、時間的にはリエント可能なバージョンを使用することが望ましい.
/*******************************************************************
•        windsome  ,          。
• QQ: 35327864
• msn: [email protected]
• mail: [email protected]
 ********************************************************************/