2012-08-25 14 views
9

私は以下のコードを実行しています。上記のプログラムが実行された場合mktime()関数の動作が混乱する:tm_hour個数を1つ増やす

int main() 
{ 
struct tm storage={0,0,0,0,0,0,0,0,0}; 
char *p = NULL; 
p = (char *)strptime("2012-08-25 12:23:12","%Y-%m-%d %H:%M:%S",&storage); 
char buff[1024]={0}; 
strftime(buff,1024,"%Y-%m-%d %H:%M:%S",&storage); 
cout << buff << endl; 
storage.tm_sec += 20; 
strftime(buff,1024,"%Y-%m-%d %H:%M:%S",&storage); 
cout << buff << endl; 
mktime(&storage); 
strftime(buff,1024,"%Y-%m-%d %H:%M:%S",&storage); 
cout << buff << endl; 
return 0; 
} 

は、それは代わりに「2012年8月25日12時23分三十二秒」の「2012年8月25日13時23分32秒」出力します。助けてください、なぜそれがtm_hour値を増やしていますか。 プログラムに入力日付を '2012-02-25 12:23:32'と入力すると正しく動作しますが、これは紛らわしいものです。

出力 - 私のシステム上>

[[email protected] root]$ ./a.out 
2012-08-25 12:23:12 
2012-08-25 12:23:32 
2012-08-25 13:23:32 
[[email protected] root]$ 

日付情報、 - >

[[email protected] root]$ date 
Sat Aug 25 08:28:26 EDT 2012 
+0

コードに時間が増えていることを示すコードは表示されません。そのためには、 'strptime'の結果と' mktime'の呼び出し結果を表示します。それは実際に起こっていることをピン止めするのに役立ちます。 –

+0

申し訳ありませんが、私はそれを解析することはできません。 1つではなく3つの出力を持ちますが、どこから来たのかはわかりません。出力に合わせてサンプルコードを更新してください。 –

答えて

11

あなたが指定した日付が有効で夏時間を持っていますが、mktimeを呼び出すときに、storage.tm_isdstがゼロである

どうなりますか。 mktimeはこれを見て、「ねえ、彼らは私に夏時間フラグが正しくない日を与えて、それを修正できると思う」と考えています。次に、tm_isdstを1に設定し、tm_hourを変更します。

も参照してくださいthis回答。それに代わりmktime

    • 使用timegmを修正するには

      は(もtimegmからの例を参照してください)mktimeを呼び出す前にUTCにタイムゾーンを設定します。

      setenv("TZ", "", 1); 
      tzset(); 
      mktime();
    • 良いタのデータを使用時間ライブラリ(boost::locale::date_time/boost::date_timeのようなものですが、Q &セクションを読んでくださいboost::locale::date_timeページを選択する前に)
  • +1

    ありがとう、それは私の疑いを助け、説明しました。今度は、両方のタイプのシステム(DSTのオンとオフ)でコードを実行する必要があります。例えばmktime()を呼び出す前にtm_isdst = 1をコードに挿入すると、DSTがオフのシステムで不正な結果が返されます(tm_hourを1減らすことになります)。与えられた日付に秒を追加する他の方法はありますか? (これは "mktime()の使用を避ける"または "tm_isdstフラグを無視するmktime()のスマートな利用") –

    +0

    @DhirajNeve:私はいくつかの修正を加えました。より多くの日付/時刻関連のことをする必要がある場合は、良いC++の日付/時刻ライブラリを使うべきだと思います。 – rve

    +0

    'timegm' POSIXだけではありませんか? – stackptr

    4

    うわー、ちょうどその周りに方法はありません。システムのmktime(3)実装のバグでなければなりません。 mktime(3)は、それに渡された struct tm *を変更すべきではありません。

    storage.tm_isdstの値を確認することをお勧めします。 DSTについて混乱しないように、0に設定してみてください。それでも問題が解決しない場合は、-1に設定して、自動的に適切な値を決定させてください。

    mktime - convert broken-down time into time since the Epoch

    はmktime()は夏時間は、それぞれ、であるか、または指定された時間のために有効ではないことを最初に推定させるためtm_isdstが正または0の値

    。 tm_isdstを負の値にすると、mktime()は夏時間が指定された時間有効であるかどうかを判断しようとします。


    私は(3)struct tm *を変更しないではmktimeについて間違っていました。値を正規化するのは正しい動作です。

    +0

    'man mktime'(http://linux.die.net/man/3/mktime)によれば' stuct tm'を変更することができます。その値を正規化し、不足しているフィールドを埋めます。 – rve

    +0

    @rveあなたが正しいように見えます。私は言葉を誤解していた。私はtime_tを設定する目的で正規化していると思った。 –

    +0

    はい、実装が間違っています... –