Я пытаюсь спасти std::time_point
в std::stream
и прочитайте это назад. Одна проблема заключается в том, что использование стандартных функций где-то «теряет» час. То есть, время, которое я читаю, отстает от времени, которое я пишу, на 1 час. Я подозреваю, что мне нужно где-то настроить летнее время. Я собрал небольшую программу, которая печатает время 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;
}
Самое странное, что программа печатает следующее:
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 (летнее время) внезапно не равно, и время не совпадает.
Я использую libc ++ на Mac OS X 10.8.2 с XCode46-DP2. Версии clang ++, которые я использую: Apple clang version 4.1
а также clang version 3.2 (trunk 167239)
Я думаю, мои вопросы:
А) Что касается разницы в 1 час, это ошибка в моей библиотеке или я неправильно использую стандартные функции? (Последнее меня не удивит …)
Б) Что происходит с кодом, когда я раскомментирую три строки в конце моей программы? Это похоже на ошибку для меня. Кто-нибудь хочет попробовать это на своей платформе?
Я думаю, что мы смотрим на ошибку с %Z
спецификатор и может быть с %z
Спецификатор также, но не уверен.
Я буду смотреть на причину этих ошибок больше. Однако я хотел пойти дальше и опубликовать, чтобы получить обходной путь. Я полагаю, если вы инициализируете ввод tm
и всегда предполагайте, что это относительно вашего местного часового пояса, тогда вы устраните свои ошибки:
std::tm time_in{0};
Других решений пока нет …