简体   繁体   English

如何将日期时间存储、打印和解析为 yyyyMMdd-HH:MM:SS.nnnnnnnn C++

[英]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::stringchar*

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::stringchar*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.nnnnnnnnnstd::stringchar*获取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
}
  • No casts没有演员表
  • Simple简单的
  • nanosecond precision纳秒精度
  • Note that this is a UTC timestamp请注意,这是一个 UTC 时间戳
  • On gcc, you could use 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 :要使用免费、开源、仅标题的预览

  • Replace #include <format> with #include "date/date.h" .#include <format>替换为#include "date/date.h"
  • Add using namespace date;添加using namespace date;
  • Change the first format string from "{:%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.

相关问题 格式化时间 c++ dd/mm/yyyy hh:ss - Formatting time c++ dd/mm/yyyy hh:ss 如何在 C++ 中将秒更改为 HH:MM:SS 格式? - How to change seconds into HH:MM:SS format in C++? C ++-用std :: difftime编写调度程序-如何检查白天发生的时间(HH:MM:SS)? - C++ - writing a scheduler with std::difftime - how to check for a time (HH:MM:SS) occurence during the day? 如何在C ++中将格式化字符串HH:MM:SS转换为秒 - How to convert formatted string HH:MM:SS to seconds in C++ 如何在 C++ 中获取 hh:mm:ss.uuuuuu 时间戳? - How to get hh:mm:ss.uuuuuu timestamp in c++? 在C ++中将日期格式Www Mmm dd hh:mm:ss yyyy转换为dd hh:mm:ss字符串 - convert date format Www Mmm dd hh:mm:ss yyyy to dd hh:mm:ss string in c++ 将时间转换为本地时间:hh_ss_mm 模板参数问题 (C++ 14) - Converting time to local zone time: issue with hh_ss_mm template args (C++ 14) 如何使用将 stable_clock 时间格式化为 HH:MM:SS.Milliseconds<chrono> 来自 c++ stdl?</chrono> - How to format steady_clock time into HH:MM:SS.Milliseconds using <chrono>from c++ stdl? 如何比较“月日期hh:mm:ss”格式的两个时间戳来检查+ ve或-ve值 - How to compare two time stamp in format “Month Date hh:mm:ss” to check +ve or -ve value Qt C ++将秒转换为格式化字符串(hh:mm:ss) - Qt C++ Convert seconds to formatted string (hh:mm:ss)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM