从c++中的std::chrono::time_point提取年/月/日等
Extract year/month/day etc. from std::chrono::time_point in C++
如何从std::chrono::time_point
对象中提取年、月、日、时、分、秒和毫秒 ?
我只看到了如何从duration
中提取例如秒的总数的示例。
您只能从system_clock::time_point
中提取此信息。这是唯一与民用日历有关系的系统提供的时钟。下面是如何使用这个时钟获取当前time_point:
system_clock::time_point now = system_clock::now();
然后可以使用以下命令将其转换为time_t
:
time_t tt = system_clock::to_time_t(now);
使用C库,您可以将time_t
转换为tm
,但您必须选择是否希望在UTC时区或您的本地时区进行转换:
tm utc_tm = *gmtime(&tt);
tm local_tm = *localtime(&tt);
然后你可以打印出tm的组件,例如:
std::cout << local_tm.tm_year + 1900 << 'n';
std::cout << local_tm.tm_mon + 1 << 'n';
std::cout << local_tm.tm_mday << 'n';
另外如果您愿意,您可以利用这些非保证信息:
我所知道的system_clock
的每个实现都是基于unix时间的。即从1970年UTC开始的秒数,忽略闰秒。这种计数的精度通常小于秒。下面是一个完整的程序,它提取了所有这些信息:
#include <chrono>
#include <ctime>
#include <iostream>
int
main()
{
using namespace std;
using namespace std::chrono;
typedef duration<int, ratio_multiply<hours::period, ratio<24> >::type> days;
system_clock::time_point now = system_clock::now();
system_clock::duration tp = now.time_since_epoch();
days d = duration_cast<days>(tp);
tp -= d;
hours h = duration_cast<hours>(tp);
tp -= h;
minutes m = duration_cast<minutes>(tp);
tp -= m;
seconds s = duration_cast<seconds>(tp);
tp -= s;
std::cout << d.count() << "d " << h.count() << ':'
<< m.count() << ':' << s.count();
std::cout << " " << tp.count() << "["
<< system_clock::duration::period::num << '/'
<< system_clock::duration::period::den << "]n";
time_t tt = system_clock::to_time_t(now);
tm utc_tm = *gmtime(&tt);
tm local_tm = *localtime(&tt);
std::cout << utc_tm.tm_year + 1900 << '-';
std::cout << utc_tm.tm_mon + 1 << '-';
std::cout << utc_tm.tm_mday << ' ';
std::cout << utc_tm.tm_hour << ':';
std::cout << utc_tm.tm_min << ':';
std::cout << utc_tm.tm_sec << 'n';
}
创建自定义duration
来模拟天数是很方便的:
typedef duration<int, ratio_multiply<hours::period, ratio<24> >::type> days;
现在你可以得到纪元以来的时间,尽可能精确,使用:
system_clock::duration tp = now.time_since_epoch();
然后截断为天,然后减去。
然后截断为小时,然后减去。
继续,直到减去秒数。
剩下的就是以system_clock::duration
为单位的几分之一秒。因此,打印出该运行时值和该值的编译时单位,如下所示。
对于我,这个程序打印出:
15806d 20:31:14 598155[1/1000000]
2013-4-11 20:31:14
我的输出表明system_clock::duration
精度是微秒。如果需要,可以使用以下命令将其截断为毫秒:
milliseconds ms = duration_cast<milliseconds>(tp);
这个仅头文件的c++ 11/14库封装了上面的工作,将客户端工作减少到:
#include "date.h"
#include <iostream>
int
main()
{
// Reduce verbosity but let you know what is in what namespace
namespace C = std::chrono;
namespace D = date;
namespace S = std;
auto tp = C::system_clock::now(); // tp is a C::system_clock::time_point
{
// Need to reach into namespace date for this streaming operator
using namespace date;
S::cout << tp << 'n';
}
auto dp = D::floor<D::days>(tp); // dp is a sys_days, which is a
// type alias for a C::time_point
auto ymd = D::year_month_day{dp};
auto time = D::make_time(C::duration_cast<C::milliseconds>(tp-dp));
S::cout << "year = " << ymd.year() << 'n';
S::cout << "month = " << ymd.month() << 'n';
S::cout << "day = " << ymd.day() << 'n';
S::cout << "hour = " << time.hours().count() << "hn";
S::cout << "minute = " << time.minutes().count() << "minn";
S::cout << "second = " << time.seconds().count() << "sn";
S::cout << "millisecond = " << time.subseconds().count() << "msn";
}
它只是为我输出:
2015-07-10 20:10:36.023017
year = 2015
month = Jul
day = 10
hour = 20h
minute = 10min
second = 36s
millisecond = 23ms
另一个更新这个库成长为c++标准提案,现在在c++ 20工作草案中。c++ 20中从system_clock::time_point
中提取这些字段的语法将是:
#include <chrono>
int
main()
{
using namespace std::chrono;
auto tp = system_clock::now();
auto dp = floor<days>(tp);
year_month_day ymd{dp};
hh_mm_ss time{floor<milliseconds>(tp-dp)};
auto y = ymd.year();
auto m = ymd.month();
auto d = ymd.day();
auto h = time.hours();
auto M = time.minutes();
auto s = time.seconds();
auto ms = time.subseconds();
}
上面的代码假设您希望这些字段使用UTC格式。如果您喜欢在其他时区使用它们,也可以这样做。例如,以下是如何在您的计算机当前的本地时区中执行此操作:
#include <chrono>
int
main()
{
using namespace std::chrono;
auto tp = zoned_time{current_zone(), system_clock::now()}.get_local_time();
auto dp = floor<days>(tp);
year_month_day ymd{dp};
hh_mm_ss time{floor<milliseconds>(tp-dp)};
auto y = ymd.year();
auto m = ymd.month();
auto d = ymd.day();
auto h = time.hours();
auto M = time.minutes();
auto s = time.seconds();
auto ms = time.subseconds();
}
上面唯一的区别是tp
的构造现在具有类型local_time
,而不是UTC示例中的sys_time
。或者,您可以选择一个任意的时区,并进行以下更改:
auto tp = zoned_time{"Europe/London", system_clock::now()}.get_local_time();
一旦我想出了这个实现。可能不是最好的,但对我的自制项目来说很好。
我们可以从timeinfo
和ms
中得到除了毫秒之外的所有内容。
static std::wstring GetDateTime()
{
time_t rawtime;
struct tm timeinfo;
wchar_t buffer[20];
time(&rawtime);
localtime_s(&timeinfo, &rawtime);
auto now = std::chrono::system_clock::now();
auto tt = std::chrono::system_clock::to_time_t(now);
auto nowTruncated = std::chrono::system_clock::from_time_t(tt);
auto ms = (now - nowTruncated).count();
wcsftime(buffer, 20, L"%Y-%m-%d %H:%M:%S", &timeinfo);
return std::wstring(buffer) + L"." + std::to_wstring(ms).substr(0, 3);
}
示例输出:
2021-06-25 10:18:48.295
- 如何使用默认参数等选择模板专业化
- 从包含m行的文件中提取n行,必要时(惰性地)重复该文件
- 在Linux中哪里可以找到互斥、未来等的源代码
- 如何从 std::atomic 中提取指针 T<T>?
- 为什么istream不支持右值提取
- 等<thing>效于char32_t
- 如何设置一个范围来提取我想要获得的信息
- 视觉工作室项目.提取源文件夹名称
- C++17 - 使用自定义分配器的节点提取/重新插入 - 适用于 clang++/libc++,但不适用于 libstd
- 从字符串中提取整数并形成一个数组
- C ++中的StringStream有助于使用向量从字符串中提取逗号分隔的整数,而不是空格分隔的整数,为什么?
- asn1c 不会从 asn.1 模块中提取八位字节字符串的默认值
- 从 std::vector<无符号字符>切片中提取 int?
- 使用 Clang++ 有没有办法将文件作为命名空间等包含?
- 如何从C++中的字符串ID中提取int日,月和年
- 从特征::等距3d提取旋转时出错
- 编译器在遇到提取或插入运算符时处理信息(字符串、操纵器等)的顺序是什么?
- 从给定日期提取日、月、年
- 从c++中的std::chrono::time_point提取年/月/日等
- 在 boost::p osix_time 中设置值(年、月、日等)