dig*_*evo 2 c++ fstream datetime-format c++-chrono c++23
我正在尝试将一个chrono::zoned_seconds对象作为文本写入文件,然后检索它并chrono::zoned_seconds稍后构造另一个对象。如何才能以相当有效的方式完成此任务?
我认为下面的代码片段没有显示正确的结果:
#include <fstream>
#include <print>
#include <chrono>
#include <format>
#include <string>
#include <sstream>
int main()
{
{
std::ofstream file("data.txt");
if (!file) {
std::println( "Unable to open file.\n" );
return 1;
}
auto now = std::chrono::system_clock::now();
const std::chrono::zoned_seconds zs { "America/New_York", std::chrono::time_point_cast<std::chrono::seconds>( now ) };
std::format_to(std::ostreambuf_iterator<char>(file), "{:%F %T %Z}", zs);
std::println( "{:%F %T %Z}", zs ); // correct time
}
{
std::ifstream file("data.txt");
if (!file) {
std::println( "Unable to open file.\n" );
return 1;
}
std::string str;
std::getline(file, str);
std::istringstream iss { str };
std::chrono::sys_seconds tp;
std::string zone_name;
iss >> std::chrono::parse("%F %T %Z", tp, zone_name);
std::chrono::zoned_seconds zs { zone_name, tp };
std::println( "{:%F %T %Z}", zs ); // incorrect time!!
}
}
Run Code Online (Sandbox Code Playgroud)
可以看出,我使用了std::chrono::parse但输出不匹配:
2024-03-01 13:35:20 EST
2024-03-01 08:35:20 EST
Run Code Online (Sandbox Code Playgroud)
您的代码中有两个错误。为了向他们展示我将从 a 开始阅读和写作stringstream以简化事情。
这是您的代码,除了使用之外没有更改stringstream:
#include <sstream>
#include <print>
#include <chrono>
#include <format>
#include <string>
#include <sstream>
int main()
{
std::stringstream file;
auto now = std::chrono::floor<std::chrono::seconds>(std::chrono::system_clock::now());
const std::chrono::zoned_seconds zs { "America/New_York", now };
file << std::format( "{:%F %T %Z}", zs);
std::println( "{:%F %T %Z}", zs ); // correct time
std::chrono::sys_seconds tp;
std::string zone_name;
file >> std::chrono::parse("%F %T %Z", tp, zone_name);
std::chrono::zoned_seconds zs2 { zone_name, tp };
std::println( "{:%F %T %Z}", zs2 );
}
Run Code Online (Sandbox Code Playgroud)
目前的输出如下所示:
2024-03-01 14:04:28 EST
2024-03-01 09:04:28 EST
Run Code Online (Sandbox Code Playgroud)
时间差异较大的原因是,当您的格式 a 时,zoned_time它显示的是本地时间,而不是 UTC。但是,当您在上面阅读时,您正在解析,就好像解析的时间是 UTC,而不是本地时间:
std::chrono::sys_seconds tp;
Run Code Online (Sandbox Code Playgroud)
将上面的行更改为:
std::chrono::local_seconds tp;
Run Code Online (Sandbox Code Playgroud)
you change the semantics of 2024-03-01 14:04:28 from UTC to local time.
2024-03-01 14:08:06 EST
2024-03-01 14:08:06 EST
Run Code Online (Sandbox Code Playgroud)
Although this looks right, it is still subtly wrong.
EST is a IANA time zone with no DST rules. It has a fixed UTC offset of -5h. America/New_York is the same as EST for a few months of the year, and then goes on daylight saving the rest of the year. So the program above will only be correct when daylight saving is not in effect for America/New_York.
To correct this bug, "America/New_York" must be stored in file instead of EST. This can be fixed by changing one line:
file << std::format( "{:%F %T %Z}", zs);
Run Code Online (Sandbox Code Playgroud)
to:
file << std::format( "{:%F %T }", zs) << zs.get_time_zone()->name();
Run Code Online (Sandbox Code Playgroud)
I.e. this outputs the actual time zone name as opposed to the time zone abbreviation.
2024-03-01 14:13:30 EST
2024-03-01 14:13:30 EST
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
32 次 |
| 最近记录: |