[英]How to store, print and parse date time as yyyyMMdd-HH:MM:SS.nnnnnnnnn C++
I faced with problem of correct way to store and work with date and time by specific locale or stamp including nanoseconds: yyyyMMdd-HH:MM:SS.nnnnnnnnn
(example: 20211215-06:36:01.571670316).我遇到了按特定语言环境或标记(包括纳秒)存储和处理日期和时间的正确方法的问题: yyyyMMdd-HH:MM:SS.nnnnnnnnn
(例如:20211215-06:36:01.571670316)。
Option 1 I need to store the date time including nanoseconds so I found few examples with std::chrono::nanoseconds
.选项 1我需要存储包括纳秒在内的日期时间,所以我找到了几个std::chrono::nanoseconds
的例子。 As I understand it is a period from 1970 ( std::chrono::duration
) and I can take days, hours, minuts etc. include nanoseconds (got here )据我了解,这是从 1970 年开始的一段时期( std::chrono::duration
),我可能需要几天、几小时、几分钟等,包括纳秒(到这里)
std::chrono::time_point<std::chrono::system_clock> now = std::chrono::system_clock::now();
auto duration = now.time_since_epoch();
typedef std::chrono::duration<int, std::ratio_multiply<std::chrono::hours::period, std::ratio<8>>::type> Days; // UTC: +8:00
Days days = std::chrono::duration_cast<Days>(duration);
duration -= days;
auto hours = std::chrono::duration_cast<std::chrono::hours>(duration);
duration -= hours;
auto minutes = std::chrono::duration_cast<std::chrono::minutes>(duration);
duration -= minutes;
auto seconds = std::chrono::duration_cast<std::chrono::seconds>(duration);
duration -= seconds;
auto milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(duration);
duration -= milliseconds;
auto microseconds = std::chrono::duration_cast<std::chrono::microseconds>(duration);
duration -= microseconds;
auto nanoseconds = std::chrono::duration_cast<std::chrono::nanoseconds>(duration);
std::cout << hours.count() << ":"
<< minutes.count() << ":"
<< seconds.count() << "."
<< milliseconds.count()
<< microseconds.count()
<< nanoseconds.count() << std::endl;
Question 1.1 : How can I print this stored date time std::chrono::duration
as std::string
or char*
using locale or stamp yyyyMMdd-HH:MM:SS.nnnnnnnnn
?问题 1.1 :如何使用语言环境或标记yyyyMMdd-HH:MM:SS.nnnnnnnnn
将此存储的日期时间std::chrono::duration
打印为std::string
或char*
?
Question 1.2 How can I parse std::string
or char*
with same locale or stamp as std::chrono::duration
to save it?问题 1.2如何解析std::string
或char*
与std::chrono::duration
相同的语言环境或标记来保存它?
Question 1.3 Are there any other ways to use std::chrono::duration
for date time store, print and parce as I need?问题 1.3是否有任何其他方法可以根据需要使用std::chrono::duration
进行日期时间存储、打印和打包?
Option 2选项 2
I also tried to use next approach (got here ).我也尝试使用下一种方法(到 这里)。 Here the date and time use one source it's std::chrono::time_point
, the nanoseconds added as additional part by cast to the std::chrono::duration
:这里的日期和时间使用一个来源,它是std::chrono::time_point
,纳秒作为附加部分添加到std::chrono::duration
:
std::chrono::time_point now = std::chrono::high_resolution_clock::now();
auto time = std::chrono::system_clock::to_time_t(now);
auto tm = *std::gmtime(&time);
auto epoch = now.time_since_epoch();
auto ns = std::chrono::duration_cast<std::chrono::nanoseconds>(epoch).count() % 1000000000;
std::ostringstream oss;
oss << std::put_time(&tm, "%Y%m%d-%T.");
auto str = oss.str();
std::cout << str << ns ;
out: 20220110-04:00:25.576973219
出: 20220110-04:00:25.576973219
As I see everything looks good, we use only std::chrono::time_point to store date and time, but I don't really think it's good way to use lot of additional casts, like std::chrono::duration
for nanoseconds and std::ostringstream
to string.当我看到一切看起来都不错时,我们只使用 std::chrono::time_point 来存储日期和时间,但我真的不认为这是使用大量额外转换的好方法,比如std::chrono::duration
纳秒和std::ostringstream
到字符串。
So then I have another questions:那么我还有一个问题:
Question 2.1 Is it a good way to store print and parse date time or I can do it witout lot of cast?问题 2.1这是存储打印和解析日期时间的好方法,还是我可以在没有大量演员的情况下做到这一点?
Question 2.2 What is the correct approach to get std::chrono::time_point
from std::string
or char*
using locale or stamp yyyyMMdd-HH:MM:SS.nnnnnnnnn
?问题 2.2使用语言环境或标记yyyyMMdd-HH:MM:SS.nnnnnnnnn
从std::string
或char*
获取std::chrono::time_point
的正确方法是什么?
Unfortunately c++20 std::format
doesn't work with gcc不幸的是,c++20 std::format
不适用于 gcc
Additional information:附加信息:
gcc --version
gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
cmake --version
cmake version 3.16.3
set(CMAKE_CXX_STANDARD 23)
BTW Clion write cmake version is 3.21.1 BTW Clion 写 cmake 版本是 3.21.1
Since your question is tagged C++20, I'm going to show a C++20 solution, even though your compiler does not yet implement these parts of C++20.由于您的问题被标记为 C++20,因此我将展示 C++20 解决方案,即使您的编译器尚未实现 C++20 的这些部分。 However, there exists a free, open-source, header-only preview of this part of C++20 that you can use in the interim which gives you a very nice migration path to C++20.但是,有一个免费的、开源的、仅包含头文件的 C++20 这一部分预览版,您可以在过渡期间使用它,它为您提供了一个非常好的迁移到 C++20 的路径。 Additionally the C++20 tools in this area are far easier to use than in prior C++ standards.此外,该领域的 C++20 工具比以前的 C++ 标准更容易使用。
#include <cassert>
#include <chrono>
#include <format>
#include <iostream>
#include <sstream>
int
main()
{
using namespace std;
using namespace std::chrono;
stringstream io;
sys_time<nanoseconds> now = system_clock::now();
io << format("{:%Y%m%d-%T}", now); // store
cout << io.str() << '\n'; // 20220110-15:13:19.576742000
now = {}; // "zero out" now just to tell if the parse works
io >> parse("%Y%m%d-%T", now); // parse
assert(!io.fail()); // another way to tell if the parse works
cout << now << '\n'; // 2022-01-10 15:13:19.576742000
}
auto
in place of sys_time<nanoseconds>
, put this makes the precision platform-dependent.在 gcc 上,您可以使用auto
代替sys_time<nanoseconds>
,这会使精度依赖于平台。 Eg macOS would give you microseconds.例如 macOS 会给你几微秒。To use the free, open-source, header-only preview :要使用免费、开源、仅标题的预览:
#include <format>
with #include "date/date.h"
.将#include <format>
替换为#include "date/date.h"
。using namespace date;
添加using namespace date;
"{:%Y%m%d-%T}"
to "%Y%m%d-%T"
将第一个格式字符串从"{:%Y%m%d-%T}"
更改为"%Y%m%d-%T"
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.