に保存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.1
はclang version 3.2 (trunk 167239)
私の質問は次のとおりだと思います: A) 1 時間の違いに関しては、これは私のライブラリのバグですか、それとも標準関数を正しく使用していませんか? (後者は私を驚かせません...)
B) プログラムの最後にある 3 行のコメントを外すと、コードはどうなりますか? これは私にはバグのように見えます。自分のプラットフォームで試してみたい人はいますか?