将微秒精度的字符串转换为计时 time_point
Convert a string with micro second precision to a chrono time_point
这是一个非常微不足道的问题。但是我找不到一个简单的答案。
我有一个精度为微秒的时间戳字符串,比方说,20:38:42.444491
。如何将其转换为适当的时间对象,以便我可以在时间比较等中使用它...
我正在尝试使用 date lib by HowardHinnant。但是我不确定如何只使用时间戳。
例如
#include <iostream>
#include "date.h"
using namespace std;
// This works fine
chrono::system_clock::time_point makeDateTime(const string& s) {
istringstream in{s};
chrono::system_clock::time_point tp;
in >> date::parse("%d/%m/%y %T", tp);
return tp;
}
// This always returns epoch. How to fix this ?
chrono::system_clock::time_point makeTime(const string& s) {
istringstream in{s};
chrono::system_clock::time_point tp;
in >> date::parse("%T", tp);
return tp;
}
int main() {
auto a = makeDateTime("30/03/09 16:31:32.121567");
cout << a.time_since_epoch().count() << endl; // 1238430692121567000
auto b = makeTime("16:31:32.121567");
cout << b.time_since_epoch().count() << endl; // 0
return 0;
}
如图所示,我可以正确解析日期时间戳。但是如果我只有时间(没有日期),我需要知道如何处理它。
很快,您就有了几个选择。但是你绝对不应该把“just a time”写成system_clock::time_point
。这样做的原因是 system_clock::time_point
有一个特定的含义:它测量自(或之前)1970-01-01 00:00:00 UTC 以来的时间,不包括闰秒。
平心而论,这个意思在C++11/14/17中是没有的,只在C++20中指定了。然而,所有实现都遵循 C++11/14/17 中的这一约定。
您可以将“一天中的时间”存储在 duration
中,例如 microseconds
。然后在您的代码中,您只需将此 duration
解释为自午夜以来经过的时间,您可以在其中定义“午夜”(当地午夜?UTC?等)。
std::chrono::microseconds
makeTime(std::string s)
{
using namespace std;
using namespace std::chrono;
istringstream in{move(s)};
microseconds tp;
in >> date::parse("%T", tp);
return tp;
}
上面的解决方案很简单,很好。但是,这个“一天中的时间”可能会意外地与其他一些不表示“一天中的时间”的持续时间混淆,从而导致您的程序出现逻辑错误。
为了使上面的类型更加安全,您可以创建一个“时间”时钟:
struct time_of_day
{
using duration = std::chrono::microseconds;
using rep = duration::rep;
using period = duration::period;
using time_point = std::chrono::time_point<time_of_day>;
static constexpr bool is_steady = false;
static
time_point
now()
{
using namespace date;
using namespace std::chrono;
auto t_sys = floor<microseconds>(system_clock::now());
return time_point{t_sys - floor<days>(t_sys)};
};
};
time_of_day::time_point
makeTime(std::string s)
{
using namespace std;
using namespace std::chrono;
istringstream in{move(s)};
microseconds d;
in >> date::parse("%T", d);
return time_of_day::time_point{d};
}
以上我将午夜定义为 UTC 只是为了简化演示。
time_of_day
解决方案不一定更好。程序员应该决定额外的复杂性成本是否证明了类型安全的好处。
这是一个非常微不足道的问题。但是我找不到一个简单的答案。
我有一个精度为微秒的时间戳字符串,比方说,20:38:42.444491
。如何将其转换为适当的时间对象,以便我可以在时间比较等中使用它...
我正在尝试使用 date lib by HowardHinnant。但是我不确定如何只使用时间戳。
例如
#include <iostream>
#include "date.h"
using namespace std;
// This works fine
chrono::system_clock::time_point makeDateTime(const string& s) {
istringstream in{s};
chrono::system_clock::time_point tp;
in >> date::parse("%d/%m/%y %T", tp);
return tp;
}
// This always returns epoch. How to fix this ?
chrono::system_clock::time_point makeTime(const string& s) {
istringstream in{s};
chrono::system_clock::time_point tp;
in >> date::parse("%T", tp);
return tp;
}
int main() {
auto a = makeDateTime("30/03/09 16:31:32.121567");
cout << a.time_since_epoch().count() << endl; // 1238430692121567000
auto b = makeTime("16:31:32.121567");
cout << b.time_since_epoch().count() << endl; // 0
return 0;
}
如图所示,我可以正确解析日期时间戳。但是如果我只有时间(没有日期),我需要知道如何处理它。
很快,您就有了几个选择。但是你绝对不应该把“just a time”写成system_clock::time_point
。这样做的原因是 system_clock::time_point
有一个特定的含义:它测量自(或之前)1970-01-01 00:00:00 UTC 以来的时间,不包括闰秒。
平心而论,这个意思在C++11/14/17中是没有的,只在C++20中指定了。然而,所有实现都遵循 C++11/14/17 中的这一约定。
您可以将“一天中的时间”存储在 duration
中,例如 microseconds
。然后在您的代码中,您只需将此 duration
解释为自午夜以来经过的时间,您可以在其中定义“午夜”(当地午夜?UTC?等)。
std::chrono::microseconds
makeTime(std::string s)
{
using namespace std;
using namespace std::chrono;
istringstream in{move(s)};
microseconds tp;
in >> date::parse("%T", tp);
return tp;
}
上面的解决方案很简单,很好。但是,这个“一天中的时间”可能会意外地与其他一些不表示“一天中的时间”的持续时间混淆,从而导致您的程序出现逻辑错误。
为了使上面的类型更加安全,您可以创建一个“时间”时钟:
struct time_of_day
{
using duration = std::chrono::microseconds;
using rep = duration::rep;
using period = duration::period;
using time_point = std::chrono::time_point<time_of_day>;
static constexpr bool is_steady = false;
static
time_point
now()
{
using namespace date;
using namespace std::chrono;
auto t_sys = floor<microseconds>(system_clock::now());
return time_point{t_sys - floor<days>(t_sys)};
};
};
time_of_day::time_point
makeTime(std::string s)
{
using namespace std;
using namespace std::chrono;
istringstream in{move(s)};
microseconds d;
in >> date::parse("%T", d);
return time_of_day::time_point{d};
}
以上我将午夜定义为 UTC 只是为了简化演示。
time_of_day
解决方案不一定更好。程序员应该决定额外的复杂性成本是否证明了类型安全的好处。