4

に保存std::time_pointしてstd::stream読み戻そうとしています。1 つの問題は、標準関数を使用すると、どこかで 1 時間を「失う」ことです。つまり、私が読む時間は、私が書く時間よりも 1 時間遅れています。どこかで夏時間を設定する必要があると思います。std::stringstream時間を aに出力して読み返す小さなプログラムをまとめました。

#include <iomanip>
#include <iostream>
#include <sstream>

#include <chrono>
#include <ctime>

using std::chrono::system_clock;
namespace chrono = std::chrono;

void test();

int main(int argc, char** argv)
{
    std::stringstream ss;

    auto start = system_clock::now();

    std::time_t ts = system_clock::to_time_t(start);

    std::tm time_out = *std::localtime(&ts);
    ss << std::put_time(&time_out, "%Y-%m-%d %H:%M:%S %Z") << '\n';

    std::cout << ss.str() << std::endl;

    std::tm time_in;
    ss >> std::get_time(&time_in, "%Y-%m-%d %H:%M:%S %Z");

    std::cout << "Are time dsts equal? : " <<
    (time_out.tm_isdst == time_in.tm_isdst) << '\n';

    std::time_t rawTime = std::mktime(&time_in);
    auto end = std::chrono::system_clock::from_time_t(rawTime);

    std::cout << "Are time points equal? : " << (start == end) << '\n';

    // print the trouble makers
    std::time_t start_time = system_clock::to_time_t(start);
    std::time_t end_time = system_clock::to_time_t(end);

    std::cout << "times: \n"
    << '\t' << std::put_time(std::localtime(&start_time), "%c %z") << '\n'
    << '\t' << std::put_time(std::localtime(&end_time), "%c %z") << '\n';

    // this is a source of strange behaviour...
//    std::cout << "Difference: "
//    << chrono::duration_cast<chrono::seconds>(start - end).count()
//    << std::endl;

    return 0;
}

最も奇妙なことは、プログラムが次のように出力することです。

Are time dsts equal? : 1
Are time points equal? : 0
times: 
Tue Dec 11 19:26:24 2012 +0000
Tue Dec 11 19:26:24 2012 +0000

そして、プログラムの最後にある 3 行のコメントを外す (時点間の差を出力する) と、結果は次のようになります。

Are time dsts equal? : 0
Are time points equal? : 0
times: 
Tue Dec 11 19:29:40 2012 +0000
Tue Dec 11 18:29:40 2012 +0000
Difference: 3600

dst (夏時間) が突然等しくなく、時間も等しくないことに注意してください。

XCode46-DP2 を搭載した Mac OS X 10.8.2 で libc++ を使用しています。私が使用しているclang ++バージョンApple clang version 4.1clang version 3.2 (trunk 167239)

私の質問は次のとおりだと思います: A) 1 時間の違いに関しては、これは私のライブラリのバグですか、それとも標準関数を正しく使用していませんか? (後者は私を驚かせません...)

B) プログラムの最後にある 3 行のコメントを外すと、コードはどうなりますか? これは私にはバグのように見えます。自分のプラットフォームで試してみたい人はいますか?

4

1 に答える 1

1

%Z指定子のバグを調べていると思いますが、おそらく指定子にもバグがあるかもしれませんが、%zまだわかりません。

これらのバグの原因をさらに調べます。ただし、回避策を得るために先に進んで投稿したかったのです。入力をゼロで初期化tmし、それがローカルのタイムゾーンを基準としていると常に仮定すると、エラーが解消されると思います。

std::tm time_in{0};
于 2012-12-12T00:11:26.380 に答える