我从 API 中获取
ms
中的纪元时间,并希望从中提取年、月等(还比较两个日期,添加小时/天/月等)。
我看过 Howard Hinnant “计时教程” 并尝试过 cppreference,但我无法完全让它发挥作用。
这是我迄今为止所拥有的一切:
enum class DatePrecision { YEAR, MONTH, DAY, HOUR, MINUTE, SECOND, MILLI };
long long et = 1693322440062;
std::chrono::milliseconds ms{ et };
std::chrono::time_point<std::chrono::system_clock> tp(ms);
int getTimeUnit(const std::chrono::time_point tp, const DatePrecision dp) {
/* .?. */
}
我该去哪里?
tp
只为我提供 time_since_epoch
作为其上的函数,正如我所说,我无法从 cppreference 获取示例来工作,特别是在使用 utc_time
而不是 system_time
时。提取是/月/日将是一个很好的开始,但我更喜欢
提前感谢您的帮助!
所以这很容易做到,但我不推荐这样做。我不推荐它的原因是最好留在 chrono 类型系统内,以便编译器可以帮助您在编译时找到任何逻辑错误。将这些值作为 int
返回会消除 chrono 为您提供的类型安全性。
#include <chrono>
#include <iostream>
#include <stdexcept>
enum class DatePrecision { YEAR, MONTH, DAY, HOUR, MINUTE, SECOND, MILLI };
int
getTimeUnit(const std::chrono::system_clock::time_point tp, const DatePrecision dp)
{
using namespace std;
using namespace std::chrono;
switch (dp)
{
case DatePrecision::YEAR:
return int{year_month_day{floor<days>(tp)}.year()};
case DatePrecision::MONTH:
return unsigned{year_month_day{floor<days>(tp)}.month()};
case DatePrecision::DAY:
return unsigned{year_month_day{floor<days>(tp)}.day()};
default:
{
hh_mm_ss hms{floor<milliseconds>(tp - floor<days>(tp))};
switch (dp)
{
case DatePrecision::HOUR:
return hms.hours().count();
case DatePrecision::MINUTE:
return hms.minutes().count();
case DatePrecision::SECOND:
return hms.seconds().count();
case DatePrecision::MILLI:
return hms.subseconds().count();
default:
throw logic_error("oops");
}
}
}
}
int main()
{
using namespace std;
using namespace std::chrono;
long long et = 1693322440062;
std::chrono::milliseconds ms{ et };
std::chrono::time_point<std::chrono::system_clock> tp(ms);
cout << tp << '\n';
cout << getTimeUnit(tp, DatePrecision::YEAR) << '\n';
cout << getTimeUnit(tp, DatePrecision::MONTH) << '\n';
cout << getTimeUnit(tp, DatePrecision::DAY) << '\n';
cout << getTimeUnit(tp, DatePrecision::HOUR) << '\n';
cout << getTimeUnit(tp, DatePrecision::MINUTE) << '\n';
cout << getTimeUnit(tp, DatePrecision::SECOND) << '\n';
cout << getTimeUnit(tp, DatePrecision::MILLI) << '\n';
}
输出:
2023-08-29 15:20:40.062000
2023
8
29
15
20
40
62
说明:
您需要打开每个所需的字段以获得正确的语法,以从
time_point
中提取它。请注意,
std::chrono::time_point
是模板,而不是类型。我以为您的意思是 std::chrono::system_clock::time_point
签名中的 std::chrono::time_point<std::chrono::system_clock>
(或等效的 getTimeUnit
)。另请注意,基于 time_point
的
system_clock
具有 UTC 语义,而不是当地时间。对于“日期字段”,首先使用 time_point
将
days
截断为 floor<days>
精度,然后将其转换为 year_month_day
。 year_month_day
类型具有 year
、month
和 day
的 getter,它们随后会显式转换为整型。对于“一天中的时间字段”,从原始值中减去日期精度time_point
,即可得到一天中的时间作为持续时间。然后类型
hh_mm_ss
将 duration
转换为 {hours, minutes, seconds, subseconds}
数据结构,每个字段都有 getter。如果您没有可用的 C++20 chrono 位,您仍然可以通过利用我的免费、开源、仅限头文件的 C++20 chrono 预览库#include "date/date.h"
和
using namespace date;
即可,其余语法相同。当您能够迁移到 C++20 时,这显然会很容易地移植到它。免责声明:我把它放在一起,它可能可以重构得更整洁一些。但希望这能让你开始。