C++ 打印/读取时间时的奇怪行为

C++ 打印/读取时间时的奇怪行为,c++,time,c++11,timezone,chrono,C++,Time,C++11,Timezone,Chrono,我正试图将std::time\u point保存到std::stream中,并将其读回。一个问题是使用标准函数在某处“损失”了一个小时。也就是说,我读的时间比我写的时间晚了一个小时。我怀疑我需要在某处设置夏令时。我编写了一个小程序,将时间打印到一个std::stringstream,并将其读回 #include <iomanip> #include <iostream> #include <sstream> #include <chrono> #

我正试图将
std::time\u point
保存到
std::stream
中,并将其读回。一个问题是使用标准函数在某处“损失”了一个小时。也就是说,我读的时间比我写的时间晚了一个小时。我怀疑我需要在某处设置夏令时。我编写了一个小程序,将时间打印到一个
std::stringstream
,并将其读回

#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;
}
当我取消注释程序末尾的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(夏令时)突然不相等,时间也不相等

我正在Mac OS X 10.8.2上使用libc++和XCode46-DP2。我使用的clang++版本是
Apple clang版本4.1
clang版本3.2(trunk 167239)

我想我的问题是: A) 至于1小时的差异,这是我的库中的错误还是我没有正确使用标准函数?(后者不会让我感到惊讶……)


B) 当我在程序末尾取消注释这三行代码时,代码发生了什么?对我来说这看起来像个虫子。有人愿意在他们的平台上尝试吗?

我想我们正在寻找一个使用
%Z
说明符的bug,可能还有
%Z
说明符的bug,还不确定

我将进一步调查这些错误的原因。不过,我想继续发帖给你一个解决办法。我相信,如果您将输入初始化为零,并且始终假定它与您的本地时区有关,那么您将消除错误:

std::tm time_in{0};

对于chrono/io,您可能喜欢使用boost chrono_io@JohanLundberg:这两个都是我的代码,因此切换不太可能解决问题。调查…谢谢,很好用。我使用的是
time\u in.isdst=0
,这同样有效。在相关的注释中,您建议时间戳的“时间类型”是什么?我使用这个缓存中的条目,希望能够丢弃旧条目。我正在使用
time\u t timestamp=system\u clock::to\u time\t(system\u clock::now())
创建时间戳,但我不确定它是否是最佳选择。这取决于您的精度需要。但是在Mac OS X 10.8.2上,如果您在64位模式下编译,这是默认模式,
time\t
的精度为秒,占用64位
system\u clock::time\u point
也是一个合适的时间戳,也占用64位,精度为微秒。如果您需要精度为纳秒的时间戳,那么在此平台上,您可以使用高分辨率时钟::时间点,也就是64位。
std::tm time_in{0};