【发布时间】:2021-12-11 23:58:40
【问题描述】:
我目前正在尝试解析日志文件中列出的有关实验开始时间的一些信息。读入文件后,使用<regex> 解析列标题、开始时间、测量间隔时间等重要信息。
我正在尝试使用std::chrono::from_stream(...) 函数将格式为“DD/MM/YYYY at hh:mm:ss”的字符串解析为std::chrono::time_point,字符串示例:
2021 年 8 月 3 日 09:37:25
目前我正在尝试使用以下函数来尝试此操作,该函数尝试从提供的字符串构造持续时间以进行解析和字符串进行解析,然后将其转换为 time_point 以便我可以控制使用的时钟:
#include <chrono>
#include <string>
#include <sstream>
#include <iostream>
using nano = std::chrono::duration<std::uint64_t, std::nano>;
template <typename Duration>
Duration TimeFormat(const std::string& str,
const std::string& fmt,
const Duration& default_val)
{
Duration dur;
std::stringstream ss{ str };
std::chrono::from_stream(ss, fmt.c_str(), dur);
/*
from_stream sets the failbit of the input stream if it fails to parse
any part of the input format string or if it receives any contradictory
information.
*/
if (ss.good())
{
std::cout << "Successful parse!" << std::endl;
std::cout << dur.count() << std::endl;
return dur;
}
else
{
std::cout << "Failed parse!" << std::endl;
std::cout << dur.count() << std::endl;
return default_val;
}
}
int main()
{
/*
The file is already read in, and regex matches the correct line from the log file and a
format pattern from a related config file.
*/
/*
Two different lines in the log file give:
- str1 = test start time.
- str2 = time between each measurement.
*/
std::string str1("08/03/2021 at 09:37:25"), str2("00:00:05");
std::string fmt1("%d/%m/%Y at %H:%M:%S"), fmt2("%H:%M:%S");
auto test1 = TimeFormat<nano>(str1, fmt1, nano::zero());
/*
--> "Failed parse!" & test1.count() = 14757395258967641292
A little research indicates that this is what VS initializes variables to
in debug mode. If run in release mode test1.count() = 0 in my tests.
*/
auto test2 = TimeFormat<nano>(str2, fmt2, nano::zero());
/*
--> "Failed parse!" & test2.count() = 5000000000 (5 billion nanoseconds)
Chose nanoseconds because it also has to handle windows file times which are measured
relative to 01/01/1601 in hundreds of nanoseconds. Might be worth pointing out.
What's weird is that it fails even though the value it reads is correct.
*/
/*
... Convert to a time_point after this,
e.g auto t1 = std::chrono::time_point<std::chrono::high_resolution_clock, nano>(test1);
*/
}
可以在here 找到 from_stream 的 MS 文档。在 from_stream 文档之后提供有关不同格式字符的详细信息。
【问题讨论】:
-
需要注意的是:
std::chrono::time_point<std::chrono::high_resolution_clock, nano>(test1)是没有意义的。高分辨率时钟没有明确定义的纪元,因此这种时钟中的时间点实际上并不代表任何特定的日期。仅对具有明确定义的纪元的时钟应用日期派生持续时间才有意义(因为该持续时间是自该纪元以来的时间)。如果从文本中获取的时间不是UTC时间,那么你需要弄清楚它是什么时间。
标签: c++ c++20 chrono visual-c++-2019