c++中获取时间日期的三种基本方法以及优缺点比较
ctime / SYSTEMTIME / chrono
time() / GetLocalTime() / system_clock::time_point
c++中获取时间日期的三种基本方法分别是
- 使用time.h或ctime
- 使用Windows系统API
- 使用chrono+ctime
接下来分别介绍三种方法
第一种方法: ctime -> time_t + tm
代码如下:
#include <ctime>
time_t now = time(NULL);
tm *tm_t = localtime(&now);
cout << "year:" << tm_t->tm_year + 1900 << " month:" << tm_t->tm_mon + 1 << " day:" << tm_t->tm_mday
<< " hour:" << tm_t->tm_hour << " minute:" << tm_t->tm_min << " second:" << tm_t->tm_sec << endl;
提示:
这里的时间是从1900年1月1日算起, 所以输出时需要加上对应的数字
优点:
- 时间结构tm中还包含 tm_wday -> 一周中第几天, tm_yday -> 一年中第几天, tm_isdst -> 是否使用夏令时 等信息
- 而且ctime中还包含一些优秀的输出函数, 比如 strftime() 能够格式化输出时间
- 多系统支持, windows/Linux等unix系统都可以使用
缺点:
- 精度不高, 最多只能到秒, 用于常规计时足够, 但毫秒级别的计时遍无法用此实现
附加阅读资料
https://www.runoob.com/w3cnote/cpp-time_t.html // 不使用原文是因为这个排版好看些
第二种方法: (仅限Windows) SYSTEMTIME -> GetLocalTime
代码如下:
#include <windows.h>
SYSTEMTIME st;
GetLocalTime(&st);
cout << "year:" << st.wYear << " month:" << st.wMonth << " day:" << st.wDay
<< " hour:" << st.wHour << " minute:" << st.wMinute << " second:" << st.wSecond
<< " millisecond:" << st.wMilliseconds << endl;
提示:
类似的系统API函数还有 GetSystemTime() -> 获取系统时间, UTC时间, 其实是格林威治时间, GetTickTime() -> 获取系统开机到现在的时间, 以毫秒计算, 返回一个uint64
优点:
- 与系统时间挂钩, 你甚至可以使用SetLocalTime()设置系统的时间, 而SYSTEMTIME结构也可以单独修改
- 而且该结构体中也包含 wDayOfWeek -> 一周中第几天 的信息
缺点:
- 与系统挂钩, 必须使用Windows系统才能够使用该种方法
附加阅读资料
https://blog.csdn.net/weixin_43069562/article/details/104177339
第三种方法: (仅限-std=c++11) chrono -> system_clock
代码如下:
#include <ctime>
#include <chrono>
//使用宏简化代码
#define GetDuration(time_scale, time_point) (duration_cast<time_scale>(time_point.time_since_epoch()).count())
using namespace chrono;
system_clock::time_point nowTp = system_clock::now();
//单独取出ms,mcs,nm
uint64_t ms = GetDuration(milliseconds, nowTp) - GetDuration(seconds, nowTp) * 1000;
uint64_t mcs = GetDuration(microseconds, nowTp) - GetDuration(milliseconds, nowTp) * 1000;
uint64_t ns = GetDuration(nanoseconds, nowTp) - GetDuration(microseconds, nowTp) * 1000;
time_t tt = system_clock::to_time_t(nowTp); //利用chrono库自带的方法转换为ctime中的time_t, 会导致精度降低
tm *tm_t = localtime(&tt);
cout << "year:" << tm_t->tm_year + 1900 << " month:" << tm_t->tm_mon + 1 << " day:" << tm_t->tm_mday
<< " hour:" << tm_t->tm_hour << " minute:" << tm_t->tm_min << " second:" << tm_t->tm_sec
<< " milliseconds:" << ms << " microseconds:" << mcs << " nanoseconds:" << ns << endl;
提示:
chrono库中本身也可以获取年数月数, 但是获取方法及其复杂, 涉及一个复杂的获取时间写法以及转换算法
故此处使用转换为time_t的方法输出, 省去代码, 有兴趣了解可以参考 附加阅读资料1
优点:
- 精度非常高, 经过测试, 精度最高可以到达100纳秒, 也就是10^-7秒
- 多系统支持, windows/Linux等unix系统都可以使用
- 适用性很强, 还可以支持时间间隔和另外的自定义时间长度
缺点:
- 代码非常复杂, 简单的功能往往需要复杂的代码来实现, 往往是命名空间套命名空间, 可读性比较低
- 没有合适方便的时间格式化方法以及输出方法, 往往需要一定的转换才能输出
- 需要编译器支持-std=c++11参数,也就是使用了STL c++ 11的内容
附加阅读资料
- https://www.cnblogs.com/fortunely/p/16321080.html
- https://blog.csdn.net/linfengmove/article/details/104562569
我把完整代码上传到了gitee,并且你可以去那里找到作者我开发的一个整合了以上三种方法的优点的时间日期库
完整代码网址如下
https://gitee.com/ProAyeR/perfect-time-and-date/blob/master/examples/_NormalWayToGetTime.cpp
自制时间库网址
https://gitee.com/ProAyeR/perfect-time-and-date
完整可运行代码如下
(2022年8月25日)
/**
* 特殊说明:本代码作者是代码仓库拥有者ProAyeR
* 这段代码之后会上传CSDN作为一篇笔记
*/
#include <iostream>
#include <ctime> //方法一、三
#include <chrono> //方法三
#include <windows.h> // 方法二
using namespace std;
int main()
{
// 第一种方法: ctime -> time_t + tm
{
time_t now = time(NULL);
tm *tm_t = localtime(&now);
cout << "year:" << tm_t->tm_year + 1900 << " month:" << tm_t->tm_mon + 1 << " day:" << tm_t->tm_mday
<< " hour:" << tm_t->tm_hour << " minute:" << tm_t->tm_min << " second:" << tm_t->tm_sec << endl;
// 提示: 这里的时间是从1900年1月1日算起, 所以输出时需要加上对应的数字
// 优点: 时间结构tm中还包含 tm_wday -> 一周中第几天, tm_yday -> 一年中第几天, tm_isdst -> 是否使用夏令时 等信息
// 而且ctime中还包含一些优秀的输出函数, 比如 strftime() 能够格式化输出时间
// 多系统支持, windows/Linux等unix系统都可以使用
// 缺点: 精度不高, 最多只能到秒, 用于常规计时足够, 但毫秒级别的计时遍无法用此实现
// 附加阅读资料 https://www.runoob.com/w3cnote/cpp-time_t.html // 不使用原文是因为这个排版好看些
}
// 第二种方法: (仅限Windows) SYSTEMTIME -> GetLocalTime
{
SYSTEMTIME st;
GetLocalTime(&st);
cout << "year:" << st.wYear << " month:" << st.wMonth << " day:" << st.wDay
<< " hour:" << st.wHour << " minute:" << st.wMinute << " second:" << st.wSecond
<< " millisecond:" << st.wMilliseconds << endl;
// 提示: 类似的系统API函数还有 GetSystemTime() -> 获取系统时间, UTC时间, 其实是格林威治时间,
// GetTickTime() -> 获取系统开机到现在的时间, 以毫秒计算, 返回一个uint64
// 优点: 与系统时间挂钩, 你甚至可以使用SetLocalTime()设置系统的时间, 而SYSTEMTIME结构也可以单独修改
// 而且该结构体中也包含 wDayOfWeek -> 一周中第几天 的信息
// 缺点: 与系统挂钩, 必须使用Windows系统才能够使用该种方法
// 附加阅读资料 https://blog.csdn.net/weixin_43069562/article/details/104177339
}
// 第三种方法: (仅限-std=c++11) chrono -> system_clock
{
//使用宏简化代码
#define GetDuration(time_scale, time_point) (duration_cast<time_scale>(time_point.time_since_epoch()).count())
using namespace chrono;
system_clock::time_point nowTp = system_clock::now();
//单独取出ms,mcs,nm
uint64_t ms = GetDuration(milliseconds, nowTp) - GetDuration(seconds, nowTp) * 1000;
uint64_t mcs = GetDuration(microseconds, nowTp) - GetDuration(milliseconds, nowTp) * 1000;
uint64_t ns = GetDuration(nanoseconds, nowTp) - GetDuration(microseconds, nowTp) * 1000;
time_t tt = system_clock::to_time_t(nowTp); //利用chrono库自带的方法转换为ctime中的time_t, 会导致精度降低
tm *tm_t = localtime(&tt);
cout << "year:" << tm_t->tm_year + 1900 << " month:" << tm_t->tm_mon + 1 << " day:" << tm_t->tm_mday
<< " hour:" << tm_t->tm_hour << " minute:" << tm_t->tm_min << " second:" << tm_t->tm_sec
<< " milliseconds:" << ms << " microseconds:" << mcs << " nanoseconds:" << ns << endl;
// 提示: chrono库中本身也可以获取年数月数, 但是获取方法及其复杂, 涉及一个复杂的获取时间写法以及转换算法
// 故此处使用转换为time_t的方法输出, 省去代码, 有兴趣了解可以参考 附加阅读资料1
// 优点: 精度非常高, 经过测试, 精度最高可以到达100纳秒, 也就是10^-7秒
// 多系统支持, windows/Linux等unix系统都可以使用
// 适用性很强, 还可以支持时间间隔和另外的自定义时间长度
// 缺点: 代码非常复杂, 简单的功能往往需要复杂的代码来实现, 往往是命名空间套命名空间, 可读性比较低
// 没有合适方便的时间格式化方法以及输出方法, 往往需要一定的转换才能输出
// 需要编译器支持-std=c++11参数,也就是使用了STL c++ 11的内容
// 附加阅读资料1 https://www.cnblogs.com/fortunely/p/16321080.html
// 附加阅读资料2 https://blog.csdn.net/linfengmove/article/details/104562569
}
}
编译运行即可看到如下输出
year:2022 month:8 day:25 hour:22 minute:52 second:58
year:2022 month:8 day:25 hour:22 minute:52 second:58 millisecond:160
year:2022 month:8 day:25 hour:22 minute:52 second:58 milliseconds:161 microseconds:232 nanoseconds:200