繁体   English   中英

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

[英]How to store, print and parse date time as yyyyMMdd-HH:MM:SS.nnnnnnnnn C++

我遇到了按特定语言环境或标记(包括纳秒)存储和处理日期和时间的正确方法的问题: yyyyMMdd-HH:MM:SS.nnnnnnnnn (例如:20211215-06:36:01.571670316)。

选项 1我需要存储包括纳秒在内的日期时间,所以我找到了几个std::chrono::nanoseconds的例子。 据我了解,这是从 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; 

问题 1.1 :如何使用语言环境或标记yyyyMMdd-HH:MM:SS.nnnnnnnnn将此存储的日期时间std::chrono::duration打印为std::stringchar*

问题 1.2如何解析std::stringchar*std::chrono::duration相同的语言环境或标记来保存它?

问题 1.3是否有任何其他方法可以根据需要使用std::chrono::duration进行日期时间存储、打印和打包?


选项 2

我也尝试使用下一种方法(到 这里)。 这里的日期和时间使用一个来源,它是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 ;

出: 20220110-04:00:25.576973219

当我看到一切看起来都不错时,我们只使用 std::chrono::time_point 来存储日期和时间,但我真的不认为这是使用大量额外转换的好方法,比如std::chrono::duration纳秒和std::ostringstream到字符串。

那么我还有一个问题:

问题 2.1这是存储打印和解析日期时间的好方法,还是我可以在没有大量演员的情况下做到这一点?

问题 2.2使用语言环境或标记yyyyMMdd-HH:MM:SS.nnnnnnnnnstd::stringchar*获取std::chrono::time_point的正确方法是什么?

不幸的是,c++20 std::format不适用于 gcc

附加信息:

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 写 cmake 版本是 3.21.1

由于您的问题被标记为 C++20,因此我将展示 C++20 解决方案,即使您的编译器尚未实现 C++20 的这些部分。 但是,有一个免费的、开源的、仅包含头文件的 C++20 这一部分预览版,您可以在过渡期间使用它,它为您提供了一个非常好的迁移到 C++20 的路径。 此外,该领域的 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
}
  • 没有演员表
  • 简单的
  • 纳秒精度
  • 请注意,这是一个 UTC 时间戳
  • 在 gcc 上,您可以使用auto代替sys_time<nanoseconds> ,这会使精度依赖于平台。 例如 macOS 会给你几微秒。

要使用免费、开源、仅标题的预览

  • #include <format>替换为#include "date/date.h"
  • 添加using namespace date;
  • 将第一个格式字符串从"{:%Y%m%d-%T}"更改为"%Y%m%d-%T"

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM