• 售前

  • 售后

热门帖子
入门百科

Linux体系中时间的获取和使用

[复制链接]
123457710 显示全部楼层 发表于 2021-10-25 19:53:35 |阅读模式 打印 上一主题 下一主题
Linux体系时间有两种。

(1)日历时间。该值是自和谐天下时(UTC)1970年1月1日00:00:00这个特定时间以来所经过的秒数累计值。根本数据范例用time_t生存。末了通过转换才华得到我们平常所看到的24小时制大概12小时间制的时间。

(2)历程时间。也被称为CPU时间,用以度量历程利用的中心处置惩罚器资源。历程时间以时钟滴答计算。

本文将给各人详细介绍关于Linux时间的获取和利用,下面话不多说了,来一起看看详细的介绍吧
获取时间戳

time()
  1. #include <time.h>
  2. time_t time(time_t *calptr)
复制代码
      
  • time返回当前时间的时间戳,也就是从天下时到现在的秒数;  
  • time_t现实就是一个uint64_t;  
  • calptr不为空时,时间戳也会写入到该指针中;
调用示例:
  1. #include <time.h>
  2. #include <iostream>
  3. #include <stdlib.h>
  4. using namespace std;
  5. int main()
  6. {
  7. time_t curTime;
  8. curTime = time(NULL);
  9. cout << curTime << endl;
  10. return 0;
  11. }
复制代码
结果:

返回一串数值,如
  1. 1533287924<br />
复制代码
gettimeofday()和clock_gettime()

time函数只能得到秒精度的时间,为了得到更高精度的时间戳,需要其他函数。gettimeofday函数可以得到微秒精度的时间戳,用结构体timeval来生存;clock_gettime函数可以得到纳秒精度的时间戳,用结构体timespec来生存。
  1. #include <sys/time.h>
  2. int gettimeofday(struct timeval *tp, void *tzp);
  3. 因为历史原因tzp的唯一合法值是NULL,因此调用时写入NULL即可。
  4. int clock_gettime(clockid_t clock_id, strcut timespec *tsp);
  5. clock_id有多个选择,当选择为CLOCK_REALTIME时与time的功能相似,但是时间精度更高。
复制代码
两个函数利用的结构体定义如下:
  1. struct timeval
  2. {
  3. long tv_sec; /*秒*/
  4. long tv_usec; /*微秒*/
  5. };
  6. struct timespec
  7. {
  8. time_t tv_sec; //秒
  9. long tv_nsec; //纳秒
  10. };
复制代码
调用示例:
  1. #include <time.h>
  2. #include <sys/time.h>
  3. #include <iostream>
  4. #include <stdlib.h>
  5. using namespace std;
  6. int main()
  7. {
  8. time_t dwCurTime1;
  9. dwCurTime1 = time(NULL);
  10. struct timeval stCurTime2;
  11. gettimeofday(&stCurTime2, NULL);
  12. struct timespec stCurTime3;
  13. clock_gettime(CLOCK_REALTIME, &stCurTime3);
  14. cout << "Time1: " << dwCurTime1 << "s" << endl;
  15. cout << "Time2: " << stCurTime2.tv_sec << "s, " << stCurTime2.tv_usec << "us" << endl;
  16. cout << "Time3: " << stCurTime3.tv_sec << "s, " << stCurTime3.tv_nsec << "ns" << endl;
  17. return 0;
  18. }
复制代码
结果:
  1. 编译时要在编译命令最后加上-lrt链接Real Time动态库,如
  2. g++ -o time2 test_time_linux_2.cpp -lrt
  3. Time1: 1533289490s
  4. Time2: 1533289490s, 133547us
  5. Time3: 1533289490s, 133550060ns
复制代码
可视化时间

tm结构体

得到的时间戳不能直观的展示现在的时间,为此需要利用tm结构体来表示成我们一样平常所见的时间,该结构体定义如下:
  1. struct tm
  2. {
  3. int tm_sec; /*秒,正常范围0-59, 但允许至61*/
  4. int tm_min; /*分钟,0-59*/
  5. int tm_hour; /*小时, 0-23*/
  6. int tm_mday; /*日,即一个月中的第几天,1-31*/
  7. int tm_mon; /*月, 从一月算起,0-11*/ 1+p->tm_mon;
  8. int tm_year; /*年, 从1900至今已经多少年*/ 1900+ p->tm_year;
  9. int tm_wday; /*星期,一周中的第几天, 从星期日算起,0-6*/
  10. int tm_yday; /*从今年1月1日到目前的天数,范围0-365*/
  11. int tm_isdst; /*日光节约时间的旗标*/
  12. };
复制代码
time_t转成tm

gmtime 和localtime可以将time_t范例的时间戳转为tm结构体,用法如下:
  1. struct tm* gmtime(const time_t *timep);
  2. //将time_t表示的时间转换为没有经过时区转换的UTC时间,是一个struct tm结构指针
  3. stuct tm* localtime(const time_t *timep);
  4. //和gmtime功能类似,但是它是经过时区转换的时间,也就是可以转化为北京时间。
复制代码
固定格式打印时间

得到tm结构体后,可以将其转为字符串格式的一样平常利用的时间,大概直接从time_t进行转换,分别可以利用以下两个函数到达目的。不外这两个函数只能打印固定格式的时间。
  1. //这两个函数已经被标记为弃用,尽量使用后面将要介绍的函数
  2. char *asctime(const struct tm* timeptr);
  3. char *ctime(const time_t *timep);
复制代码
调用示例:
  1. #include <time.h>
  2. #include <sys/time.h>
  3. #include <iostream>
  4. #include <stdlib.h>
  5. using namespace std;
  6. int main()
  7. {
  8. time_t dwCurTime1;
  9. dwCurTime1 = time(NULL);
  10. struct tm* pTime;
  11. pTime = localtime(&dwCurTime1);
  12. char* strTime1;
  13. char* strTime2;
  14. strTime1 = asctime(pTime);
  15. strTime2 = ctime(&dwCurTime1);
  16. cout << strTime1 << endl;
  17. cout << strTime2 << endl;
  18. return 0;
  19. }
复制代码
结果:
  1. Fri Aug 3 18:24:29 2018
  2. Fri Aug 3 18:24:29 2018
复制代码
机动安全的时间转换函数strftime()

上述两个函数由于大概出现缓冲区溢出的标题而被标记为弃用,因此更加安全的方法是接纳strftime方法。
  1. /*
  2. ** @buf:存储输出的时间
  3. ** @maxsize:缓存区的最大字节长度
  4. ** @format:指定输出时间的格式
  5. ** @tmptr:指向结构体tm的指针
  6. */
  7. size_t strftime(char* buf, size_t maxsize, const char *format, const struct tm *tmptr);
复制代码
我们可以根据format指向字符串中格式,将timeptr中存储的时间信息按照format指定的形式输出到buf中,最多向缓冲区buf中存放maxsize个字符。该函数返回向buf指向的字符串中放置的字符数。

函数strftime()的利用有些类似于sprintf():辨认以百分号(%)开始的格式命令聚集,格式化输出结果放在一个字符串中。格式化命令阐明串 strDest中各种日期和时间信息的确切表示方法。格式串中的其他字符原样放进串中。格式命令列在下面,它们是区分大小写的。
  1. %a 星期几的简写
  2. %A 星期几的全称
  3. %b 月分的简写
  4. %B 月份的全称
  5. %c 标准的日期的时间串
  6. %C 年份的后两位数字
  7. %d 十进制表示的每月的第几天
  8. %D 月/天/年
  9. %e 在两字符域中,十进制表示的每月的第几天
  10. %F 年-月-日
  11. %g 年份的后两位数字,使用基于周的年
  12. %G 年分,使用基于周的年
  13. %h 简写的月份名
  14. %H 24小时制的小时
  15. %I 12小时制的小时
  16. %j 十进制表示的每年的第几天
  17. %m 十进制表示的月份
  18. %M 十时制表示的分钟数
  19. %n 新行符
  20. %p 本地的AM或PM的等价显示
  21. %r 12小时的时间
  22. %R 显示小时和分钟:hh:mm
  23. %S 十进制的秒数
  24. %t 水平制表符
  25. %T 显示时分秒:hh:mm:ss
  26. %u 每周的第几天,星期一为第一天 (值从0到6,星期一为0)
  27. %U 第年的第几周,把星期日做为第一天(值从0到53)
  28. %V 每年的第几周,使用基于周的年
  29. %w 十进制表示的星期几(值从0到6,星期天为0)
  30. %W 每年的第几周,把星期一做为第一天(值从0到53)
  31. %x 标准的日期串
  32. %X 标准的时间串
  33. %y 不带世纪的十进制年份(值从0到99)
  34. %Y 带世纪部分的十制年份
  35. %z,%Z 时区名称,如果不能得到时区名称则返回空字符。
  36. %% 百分号
复制代码
调用示例:
  1. #include <time.h>
  2. #include <sys/time.h>
  3. #include <iostream>
  4. #include <stdlib.h>
  5. using namespace std;
  6. int main()
  7. {
  8. time_t dwCurTime1;
  9. dwCurTime1 = time(NULL);
  10. struct tm* pTime;
  11. pTime = localtime(&dwCurTime1);
  12. char buf[100];
  13. strftime(buf, 100, "time: %r, %a %b %d, %Y", pTime);
  14. cout << buf << endl;
  15. return 0;
  16. }
复制代码
结果:
  1. time: 08:18:12 PM, Fri Aug 03, 2018
复制代码
时间函数之间的关系图

历程时间

历程时间是历程被创建后利用CPU的时间 ,历程时间被分为以下两个部分:
      
  • 用户CPU时间:在用户态模式下利用CPU的时间  
  • 内核CPU时间:在内核态模式下利用CPU的时间。这是执行内核调用或其他特殊任务所需要的时间。
clock函数

clock函数提供了一个简单的接口用于取得历程时间,它返回一个值描述历程利用的总的CPU时间(包括用户时间和内核时间),该函数定义如下:
  1. #include <time.h>
  2. clock_t clock(void)
  3. //if error, return -1
复制代码
clock函数返回值得计量单元是CLOCKS_PER_SEC,将返回值除以这个计量单元就得到了历程时间的秒数

times函数

times函数也是一个历程时间函数,有更加详细的历程时间表示,函数定义如下:
  1. #include <sys/times.h>
  2. clock_t times(struct tms* buf);
  3. struct tms{
  4. clock_t tms_utime;
  5. clock_t tms_stime;
  6. clock_t tms_cutime;
  7. clock_t tms_cstime;
  8. };
复制代码
times函数虽然返回范例还是clock_t,但是与clock函数返回值的计量单元差异。times函数的返回值得计量单元要通过sysconf(SC_CLK_TCK)来得到。

Linux体系编程手册上一个完备的利用案例如下:
  1. #include <time.h>
  2. #include <sys/times.h>
  3. #include <unistd.h>
  4. #include <stdio.h>
  5. static void displayProcessTime(const char* msg)
  6. {
  7. struct tms t;
  8. clock_t clockTime;
  9. static long clockTick = 0;
  10. if (msg != NULL)
  11. {
  12. printf("%s\n", msg);
  13. }
  14. if (clockTick == 0)
  15. {
  16. clockTick = sysconf(_SC_CLK_TCK);
  17. if (clockTick < 0) return;
  18. }
  19. clockTime = clock();
  20. printf("clock return %ld CLOCKS_PER_SEC (%.2f seconds)\n", (long)clockTime, (double)clockTime/CLOCKS_PER_SEC);
  21. times(&t);
  22. printf("times return user CPU = %.2f; system CPU = %.2f\n", (double)t.tms_utime / clockTick, (double)t.tms_stime / clockTick);
  23. }
  24. int main()
  25. {
  26. printf("CLOCKS_PER_SEC = %ld, sysconf(_SC_CLK_TCK) = %ld\n", (long)CLOCKS_PER_SEC, sysconf(_SC_CLK_TCK));
  27. displayProcessTime("start:");
  28. for (int i = 0; i < 1000000000; ++i)
  29. {
  30. getpid();
  31. }
  32. printf("\n");
  33. displayProcessTime("end:");
  34. return 0;
  35. }
复制代码
参考

[1] http://www.runoob.com/w3cnote/cpp-time_t.html
[2] Unix高级情况编程(第三版)

[3] Unix体系编程手册
总结
以上就是这篇文章的全部内容了,渴望本文的内容对各人的学习大概工作具有一定的参考学习代价,如果有疑问各人可以留言交换,谢谢各人对脚本之家的支持。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

帖子地址: 

回复

使用道具 举报

分享
推广
火星云矿 | 预约S19Pro,享500抵1000!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

草根技术分享(草根吧)是全球知名中文IT技术交流平台,创建于2021年,包含原创博客、精品问答、职业培训、技术社区、资源下载等产品服务,提供原创、优质、完整内容的专业IT技术开发社区。
  • 官方手机版

  • 微信公众号

  • 商务合作