我正在使用 .json 实现时间戳的 json 序列化和反序列化nlohmann::json
。转换std::chrono::time_point
为mm/dd/yy hh:mm:ss
日期时间样式(根据我们的要求,它必须是人类可读的)后,我自然会丢失一些信息,因此我对反序列化后时间点相等的标准是“相差不超过一秒”。
在使用 gcc 11.4.0 的本地计算机上一切正常,但在使用 gcc 8.5.0 的生产服务器上失败。
在 godbolt 上重现问题的最少代码:
#include <iostream>
#include <iomanip>
#include <chrono>
#include <string>
int main() {
// serialization
auto ts = std::chrono::system_clock::now();
auto timeS_t = std::chrono::system_clock::to_time_t(ts);
std::ostringstream outStream;
outStream << std::put_time(std::localtime(&timeS_t), "%x %X");
std::string tsStr = outStream.str();
// deserialization
std::istringstream ss(tsStr);
std::tm t = {};
ss >> std::get_time(&t, "%x %X");
auto parsedTs = std::chrono::system_clock::from_time_t(std::mktime(&t));
// difference in seconds
int secDiff = std::chrono::duration_cast<std::chrono::seconds>(ts - parsedTs).count();
// just debug prints
std::cout << secDiff << std::endl;
std::time_t ttp1 = std::chrono::system_clock::to_time_t(ts);
std::time_t ttp2 = std::chrono::system_clock::to_time_t(parsedTs);
std::cout << "ts1: " << std::ctime(&ttp1);
std::cout << "ts2: " << std::ctime(&ttp2);
// my equality criterion
if (std::abs(secDiff) > 1) {
std::cout << "FAIL\n";
}
}
使用较新的编译器我得到相同的结果,例如
ts1: Thu Feb 22 16:06:25 2024
ts2: Thu Feb 22 16:06:25 2024
但对于旧的,我看到时间点上的差异正好是 100 年:
ts1: Thu Feb 22 16:06:17 2024
ts2: Fri Feb 22 16:06:17 1924
我想这可能与序列化例程有关std::localtime(&timeS_t)
,但我没有找到反序列化器的“反向”功能。我可以改变什么来保持一致的行为?