Linux时间的获取与使用

这篇具有很好参考价值的文章主要介绍了Linux时间的获取与使用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Linux系统时间有两种。

(1)日历时间。该值是自协调世界时(UTC)1970年1月1日00:00:00这个特定时间以来所经过的秒数累计值。基本数据类型用time_t保存。最后通过转换才能得到我们平时所看到的24小时制或者12小时间制的时间。

(2)进程时间。也被称为CPU时间,用以度量进程使用的中央处理器资源。进程时间以时钟滴答计算。

日历时间

time()获取时间戳

time函数用来获取日历时间的时间戳,该时间戳是从1970年1月1日0点(00:00:00 UTC, January 1, 1970)到现在经历的秒数。

函数定义如下:

#include <time.h>
time_t time(time_t *calptr) 
  • time返回当前时间的时间戳,也就是从世界时到现在的秒数;
  • time_t实际系统自定义的时间戳类型,函数正常返回当前时间戳,出错返回(time_t)-1
  • calptr不为空时,时间戳也会写入到该指针中;

调用示例:

#include <time.h>
#include <iostream>
#include <stdlib.h>

using namespace std;

int main()
{
	time_t curTime;
	curTime = time(NULL);
	cout << curTime << endl;
	return 0;
} 

结果: 返回一串数值,如1533287924

gettimeofday()和clock_gettime()获取更高精度的时间

time函数只能得到秒精度的时间,为了获得更高精度的时间戳,需要其他函数。gettimeofday函数可以获得微秒精度的时间戳,用结构体timeval来保存;clock_gettime函数可以获得纳秒精度的时间戳,用结构体timespec来保存。

#include <sys/time.h>

int gettimeofday(struct timeval *tp, void *tzp);
因为历史原因tzp的唯一合法值是NULL,因此调用时写入NULL即可。

int clock_gettime(clockid_t clock_id, strcut timespec *tsp);
clock_id有多个选择,当选择为CLOCK_REALTIME时与time的功能相似,但是时间精度更高。 

两个函数使用的结构体定义如下:

struct timeval
{long tv_sec; /*秒*/long tv_usec; /*微秒*/
};

struct timespec
{
	time_t tv_sec;//秒
	long tv_nsec; //纳秒
}; 

调用示例:

#include <time.h>
#include <sys/time.h>
#include <iostream>
#include <stdlib.h>

using namespace std;

int main()
{
	time_t dwCurTime1;
	dwCurTime1 = time(NULL);struct timeval stCurTime2;gettimeofday(&stCurTime2, NULL);struct timespec stCurTime3;clock_gettime(CLOCK_REALTIME, &stCurTime3);cout << "Time1: " << dwCurTime1 << "s" << endl;cout << "Time2: " << stCurTime2.tv_sec << "s, " << stCurTime2.tv_usec << "us" << endl;cout << "Time3: " << stCurTime3.tv_sec << "s, " << stCurTime3.tv_nsec << "ns" << endl;

	return 0;
} 

结果:

编译时要在编译命令最后加上-lrt链接Real Time动态库,如
g++ -o time2 test_time_linux_2.cpp -lrt

Time1: 1533289490s
Time2: 1533289490s, 133547us
Time3: 1533289490s, 133550060ns 

可视化时间-时间戳转化为日/月/年

tm结构体

得到的时间戳不能直观的展示现在的时间,为此需要使用tm结构体来表示成我们日常所见的时间,该结构体定义如下:

struct tm
{int tm_sec;/*秒,正常范围0-59, 但允许至61*/int tm_min;/*分钟,0-59*/int tm_hour; /*小时, 0-23*/int tm_mday; /*日,即一个月中的第几天,1-31*/int tm_mon;/*月, 从一月算起,0-11*/1+p->tm_mon;int tm_year;/*年, 从1900至今已经多少年*/1900+ p->tm_year;int tm_wday; /*星期,一周中的第几天, 从星期日算起,0-6*/int tm_yday; /*从今年1月1日到目前的天数,范围0-365*/int tm_isdst; /*日光节约时间的旗标*/
}; 
time_t转成tm

gmtimelocaltime可以将time_t类型的时间戳转为tm结构体,用法如下:

struct tm* gmtime(const time_t *timep);
//将time_t表示的时间转换为没有经过时区转换的UTC时间,是一个struct tm结构指针

stuct tm* localtime(const time_t *timep);
//和gmtime功能类似,但是它是经过时区转换的时间,也就是可以转化为北京时间。 
固定格式打印时间

得到tm结构体后,可以将其转为字符串格式的日常使用的时间,或者直接从time_t进行转换,分别可以使用以下两个函数达到目的。不过这两个函数只能打印固定格式的时间。

//这两个函数已经被标记为弃用,尽量使用后面将要介绍的函数
char *asctime(const struct tm* timeptr);
char *ctime(const time_t *timep); 

调用示例:

#include <time.h>
#include <sys/time.h>
#include <iostream>
#include <stdlib.h>

using namespace std;

int main()
{
	time_t dwCurTime1;
	dwCurTime1 = time(NULL);struct tm* pTime;pTime = localtime(&dwCurTime1);char* strTime1;char* strTime2;strTime1 = asctime(pTime);strTime2 = ctime(&dwCurTime1);cout << strTime1 << endl;cout << strTime2 << endl;

	return 0;
} 

结果:

Fri Aug3 18:24:29 2018
Fri Aug3 18:24:29 2018 
灵活安全的时间转换函数strftime()

上述两个函数因为可能出现缓冲区溢出的问题而被标记为弃用,因此更加安全的方法是采用strftime方法。

/*
** @buf:存储输出的时间
** @maxsize:缓存区的最大字节长度
** @format:指定输出时间的格式
** @tmptr:指向结构体tm的指针
*/
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中各种日期和时间信息的确切表示方法。格式串中的其他字符原样放进串中。格式命令列在下面,它们是区分大小写的。

%a 星期几的简写
%A 星期几的全称
%b 月分的简写
%B 月份的全称
%c 标准的日期的时间串
%C 年份的后两位数字
%d 十进制表示的每月的第几天
%D 月/天/年
%e 在两字符域中,十进制表示的每月的第几天
%F 年-月-日
%g 年份的后两位数字,使用基于周的年
%G 年分,使用基于周的年
%h 简写的月份名
%H 24小时制的小时
%I 12小时制的小时
%j 十进制表示的每年的第几天
%m 十进制表示的月份
%M 十时制表示的分钟数
%n 新行符
%p 本地的AM或PM的等价显示
%r 12小时的时间
%R 显示小时和分钟:hh:mm
%S 十进制的秒数
%t 水平制表符
%T 显示时分秒:hh:mm:ss
%u 每周的第几天,星期一为第一天 (值从0到6,星期一为0)
%U 第年的第几周,把星期日做为第一天(值从0到53)
%V 每年的第几周,使用基于周的年
%w 十进制表示的星期几(值从0到6,星期天为0)
%W 每年的第几周,把星期一做为第一天(值从0到53)
%x 标准的日期串
%X 标准的时间串
%y 不带世纪的十进制年份(值从0到99)
%Y 带世纪部分的十制年份
%z,%Z 时区名称,如果不能得到时区名称则返回空字符。
%% 百分号 

调用示例:

#include <time.h>
#include <sys/time.h>
#include <iostream>
#include <stdlib.h>

using namespace std;

int main()
{
	time_t dwCurTime1;
	dwCurTime1 = time(NULL);struct tm* pTime;pTime = localtime(&dwCurTime1);char buf[100];strftime(buf, 100, "time: %r, %a %b %d, %Y", pTime);cout << buf << endl;

	return 0;
} 

结果:

time: 08:18:12 PM, Fri Aug 03, 2018 

mktime将struct tm转化为time_t的时间戳

在业务程序中,经常需要对比时间的先后,如果用字符串格式时间进行对比,需要保证格式完全一致,而且转为字符串形式也比较麻烦,因此更多时候用时间戳来进行比较。有的时候就需要将字符串形式的时间或者struct tm表示的时间转化为time_t的时间戳,这个转化是通过mktime函数来实现的。

在介绍mktime函数之前,我们先来看看struct tm这个结构体中埋的坑。

#include <time.h>
#include <stdio.h>

int main() {
	time_t tCurTime = time(NULL);
	printf("tCurTime: %lu\n", (unsigned long)(tCurTime));

	struct tm* pTm;
	pTm = localtime(&tCurTime);

	printf("year:%d\n", pTm->tm_year);
	printf("mon:%d\n", pTm->tm_mon);
	printf("day:%d\n", pTm->tm_mday);
	printf("hour:%d\n", pTm->tm_hour);
	printf("min:%d\n", pTm->tm_min);
	printf("sec:%d\n", pTm->tm_sec);

	time_t tMkTime;
	tMkTime = mktime(pTm);
	printf("tMkTime:%lu\n", (unsigned long)tMkTime);

	return 0;
} 

当前时间是:Fri Apr 12 12:48:40 CST 2019,而这段程序的输出结果是:

tCurTime: 1555044520
year:119
mon:3
day:12
hour:12
min:48
sec:40
tMkTime:1555044520 

不知道你有没有看出猫腻。奇葩的地方在于,打印出来的月份比实际少了1个月,年份少了1900年。 原来通过localtime函数得到的时间是从1900年1月1日开始算的,但是这个月份多1怎么来的,我还没搞清楚。不过在通过字符串保存的当前时间转为时间戳时要记得减1,不然就不能得到想要的结果。

#include <time.h>
time_t mktime(struct tm *tm); 

时间函数之间的关系图

Linux时间的获取与使用

进程时间

进程时间是进程被创建后使用CPU的时间 ,进程时间被分为以下两个部分:

  • 用户CPU时间:在用户态模式下使用CPU的时间
  • 内核CPU时间:在内核态模式下使用CPU的时间。这是执行内核调用或其他特殊任务所需要的时间。

clock函数

clock函数提供了一个简单的接口用于取得进程时间,它返回一个值描述进程使用的总的CPU时间(包括用户时间和内核时间),该函数定义如下:

#include <time.h>
clock_t clock(void)
//if error, return -1 

clock函数返回值得计量单位是CLOCKS_PER_SEC,将返回值除以这个计量单位就得到了进程时间的秒数

times函数

times函数也是一个进程时间函数,有更加具体的进程时间表示,函数定义如下:

#include <sys/times.h>
clock_t times(struct tms* buf);

struct tms{
	clock_t tms_utime;
	clock_t tms_stime;
	clock_t tms_cutime;
	clock_t tms_cstime;
}; 

times函数虽然返回类型还是clock_t,但是与clock函数返回值的计量单位不同。times函数的返回值得计量单位要通过sysconf(SC_CLK_TCK)来获得。

Linux系统编程手册上一个完整的使用案例如下:

#include <time.h>
#include <sys/times.h>
#include <unistd.h>
#include <stdio.h>

static void displayProcessTime(const char* msg) {
	struct tms t;
	clock_t clockTime;
	static long clockTick = 0;

	if (msg != NULL) 
	{
		printf("%s\n", msg);
	}

	if (clockTick == 0)
	{
		clockTick = sysconf(_SC_CLK_TCK);
		if (clockTick < 0) return;
	}

	clockTime = clock();
	printf("clock return %ld CLOCKS_PER_SEC (%.2f seconds)\n", (long)clockTime, (double)clockTime/CLOCKS_PER_SEC);
	
	times(&t);
	printf("times return user CPU = %.2f; system CPU = %.2f\n", (double)t.tms_utime / clockTick, (double)t.tms_stime / clockTick);
}

int main() {
	printf("CLOCKS_PER_SEC = %ld, sysconf(_SC_CLK_TCK) = %ld\n", (long)CLOCKS_PER_SEC, sysconf(_SC_CLK_TCK));

	displayProcessTime("start:");
	for (int i = 0; i < 1000000000; ++i)
	{
		getpid();
	}
	printf("\n");
	displayProcessTime("end:");

	return 0;
} 

参考

[1] www.runoob.com/w3cnote/cpp…

[2] Unix高级环境编程(第三版)

[3] Unix系统编程手册文章来源地址https://www.toymoban.com/news/detail-415688.html

到了这里,关于Linux时间的获取与使用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 《Linux操作系统编程》 第六章 Linux中的进程监控: fork函数的使用,以及父子进程间的关系,掌握exec系列函数

    🌷🍁 博主 libin9iOak带您 Go to New World.✨🍁 🦄 个人主页——libin9iOak的博客🎐 🐳 《面试题大全》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺 🌊 《IDEA开发秘籍》学会IDEA常用操作,工作效率翻倍~💐 🪁🍁 希望本文能够给您带来一定的帮助🌸文章粗浅,敬

    2024年02月11日
    浏览(34)
  • python获取当前时间(年-月-日 时:分:秒:毫秒),提取当前日期/时间数字,获取程序运行的时间差(时:分:秒),让程序停止xx秒【两种方法,第二种方法精度较高】

    目录 》》》第一种方法,代码如下:(获取当前时间,提取当前日期/时间数字) 》》》第二种方法,代码如下:(获取当前时间,提取日期/时间数字,获取时间差【时:分:秒】) 》》》第一种方法,代码如下:(获取当前时间,提取当前日期/时间数字) 第一种方法的运行

    2024年02月16日
    浏览(58)
  • Linux下的系统编程——进程间的通信(九)

    前言:  前面我们已经对进程已经有了一个简单的了解与认识,那么进程间的通信是什么样的呢,什么是父子进程,什么是兄弟进程,没有血缘关系间的进程是如何实现进程通信的,下面让我们一起学习一下什么是进程间的通信吧。 目录 一、进程间通信常用方式 IPC方式:

    2024年02月09日
    浏览(32)
  • 【智能家居项目】FreeRTOS版本——多任务系统中使用DHT11 | 获取SNTP服务器时间 | 重新设计功能框架

    🐱作者:一只大喵咪1201 🐱专栏:《智能家居项目》 🔥格言: 你只管努力,剩下的交给时间! 在上篇文章中,本喵仅进行了单任务的DHT11温湿度传感器使用,相当于裸机使用。 根据上面时序图计算接收一次数据(5个字节)的耗时,不考虑主机发送起始信号的耗时: 最小时间

    2024年02月05日
    浏览(44)
  • 使用消息中间件实现系统间的异步通信和解耦

    ​​​​​​​ 目录 引言 一. 选择合适的消息中间件 二. 定义消息格式和通信协议 1. 定义消息格式 消息头 消息体 2. 定义通信协议 发送消息 接收消息 消息处理 3. 示例代码 定义消息格式 发送消息 接收消息 三、发布-订阅模式 1. 定义发布-订阅模式 2. 示例代码 发布消息 订

    2024年02月19日
    浏览(49)
  • Linux获取纳秒级别时间

    在 Linux 系统中可以使用 gettimeofday 函数来获取时间,这个函数能够以毫秒的精度来获取时间 Linux 系统可以使用 clock_gettime 函数来获取时间精度,其可以以纳秒的精度获取时间

    2024年02月10日
    浏览(32)
  • 【Shell 命令集合 系统管理 】Linux 显示或设置系统时间和日期 date命令 使用指南

    Shell 命令专栏:Linux Shell 命令全解析 date命令是Linux系统中用于显示或设置系统时间和日期的命令。它可以显示当前的系统时间和日期,也可以用于设置系统时间和日期。 当使用date命令不带任何参数时,它会显示当前系统时间和日期。它的输出格式通常是以\\\"星期 月 日 时:分

    2024年02月07日
    浏览(55)
  • Linux C编程基础:获取时间

    对于linux下的编程,无论是用户态还是内核态,时间获取都是经常需要使用到的。以下分别从用户态和内核态整理了几个常用的时间获取接口,供编写代码时快速查阅。 linux时间子系统的发展历史及详细介绍,可以参考:深入理解Linux时间子系统。 2.1 clock_gettime() 作用 :根据

    2024年02月08日
    浏览(25)
  • Linux下获取时间函数gettimeofday()

    在进行获取系统时间时,相关函数 time,ctime,gmtime,localtime。。。,其中asctime是将时间和日期以字符串的形式进行输出, eg: 在Linux环境下 精确到毫秒 精确到秒: #include “stdafx.h” #include windows.h #include using namespace std; int main(int argc, _TCHAR* argv[]) { DWORD time_start, time_end; /* 获取

    2023年04月11日
    浏览(37)
  • C# 获取当前系统时间及时间格式详解

    C# 获取当前系统时间及时间格式详解 在 C# 编程中,获取当前系统时间是一个常见的操作。此外,对于时间的格式化也是开发中经常遇到的需求。本文将详细介绍如何使用 C# 获取当前系统时间,并对常用的时间格式进行解析和格式化。 获取当前系统时间 要获取当前系统时间

    2024年02月07日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包