LInux中的time处理(C语言)

在Linux系统应用中,经常需要获得当前的时间信息,Linux内核提供了一些相应函数用于操作,对其标准调用格式格式说明如下:

#include <time.h>

char *asctime(const struct tm *tm);
char *asctime_r(const struct tm *tm, char *buf);
char *ctime(const time_t *timep);
char *ctime_r(const time_t *timep);

struct tm *gmtime(const time_t *timep);
struct tm *gmtime_r(const time_t *timep, struct tm *result);
struct tm *localtime(const time_t *timep);
struct tm *localtime_r(const time_t *timep, struct tm *result);

time_t mktime(struct tm *tm);

int gettimeofday(struct timeval *tv, struct timezone *tz);
int settimeofday(const struct timeval *tv, const struct timezone *tz);

各个时间函数的关系说明如图1所示,对其详细说明如下:

                          

                                                                      图1 Linux的时间函数的相互关系

时间函数的介绍:在#include <sys/time.h>的头文件中 

  •  asctime 函数:将参数timeptr所指的tm结构中的信息转换成真实世界所使用的时间日期表示方法,然后将结构以字符串形态返回。此函数已经由时区转换成当地时间,字符串格式为:“Wed JUN 30 21:49:08 1990/n”。该函数的参数是tm指针指向的存储空间,返回值是表示目前当地时间日期的字符串
  • asctime_r 函数:是asctime函数的一个扩展,提供了一个缓冲器件buf用于存放返回值,该缓冲区的长度不能低于26个字节。
  • ctime 函数:将参数timep所指的time_t结构中的信息转换成真实世界所使用的时间日期表示方法,然后将结果以字符串形态返回。此函数已经由时区转换成当地时间,字符串格式为"Wed Oct 12 20:23:10 1997/n"。若再调用相关的时间日期函数,此字符串可能会被破环。
// 若再调用相关的时间日期函数,此字符串可能会被破环。
// 此函数与ctime函数的不同之处在于传入的参数是不同的结构
// 对asctime函数中涉及的tm时间信息结构体说明如下。

struct tm
{
    int tm_sec;    // 秒
    int tm_min;    // 分钟
    int tm_hour;   // 小时
    int tm_mday    // 日期
    int tm_mon;    // 月份
    int tm_year;   // 年份
    int tm_wday;   // 星期
    int tm_yady;   // 从1月1日开始到当日日期编号
    int tm_isdst;

    // 夏令时标识符,实行夏令时的时候,tm_isdat为正
    // 不实行夏令时的时候,tm_isdst为0
    // 不了解情况时,tm_isdat()为负
};
  • char *ctime_r 函数:和ctime函数功能相同,也是提供了一个缓冲区用于存放返回值。
  • gmtime 函数:将所指的time_t结构体中的信息转换为真实世界所使用的时间日期表示方法,用于存放返回值。此时得到的为:格林威治(GMT)时间,于北京时间相差8个小时。
  • gmtime_r 函数:和gmtime函数类似,同时提供了一个由result指针指向的内存空间
  • localtime 函数:当地的目前时间和日期,其将参数timep所指的结构体中的信息转换为真实世界所使用的时间日期表示方法,然会返回。
  • localtime_r 函数:和localtime函数类似,同时提供了一个由result指针指向的内存空间,用于存放返回值。
  • mktime 函数:将参数tm所指向的结构体数据转换为从1970年1月1日0时0分0秒开始所经历的秒数,然后返回。
  • gettimeofday 函数:获取当前时间和时区信息,这个需要超级用户的权限,tz 参数用于指向存放返回时间信息的缓冲区,可以获得当前精确时间(1970年1月1日到现在的时间,可以精确到微秒量级(1e-6s))。对其结构说明如下:
Struct timeval {
    time_t      tv_sec;  // 秒
    suseconds_t tv_usec; // 微妙
}

注意事项:

// tz用于存放相应的时钟信息,说明如下

struct timezone {
    int tz_minuteswest;    // minutes west of Greenwich
    int tz_dsttime;        // type of DST correction

}
  • settimeofday 函数:用于设置当前时间和时区信息,其参数和使用方法可以参考 gettimeofday。

例一:打印当前Linux系统时间信息

这是一个系统时间函数的应用实例,其调用了time、localtime和asctime函数用于在屏幕上打印当前的Linux系统的时间。应用代码首先调用gmtime函数获得当前时间的秒数据,然会使用asctime函数将该秒数据转换为正常的显示格式:

// 打印系统的当前时钟

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

int main(void){
	time_t timetemp; // 定义一个时间结构体变量
	char *wday[] = {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
	struct tm *p;	 // 结构体指针
	time(&timetemp); // 获得时间参数

	printf("%s",asctime(gmtime(&timetemp)));
	
	p = localtime(&timetemp);

	printf("%d:%d:%d\n", (1900+p->tm_year),(1+p->tm_mon),p->tm_mday);

	printf("%s  %d:%d:%d\n", wday[p->tm_wday], p->tm_hour, p->tm_min, p->tm_sec);

	return 0;
}

运行结果为(在Ubantu上运行,版本号为:1804):

可以观察到此时时间时19:53:55秒,而使用asctime(gmtime(&timetemp))得到的时间为11:53:55(格林威治(GMT)时间)。其中相差了8个小时。

例二:计算代码运行时间(单位为微秒,不精确)

使用时间函数来测试当前程序所需的运行时间

// 这是一个使用时间函数来测试当前程序所需运行时间的实例,应用代码首先调用gettimeofday获得当前的时间信息
// 然后讲这些时间信息分门别类地输出,最后测试了本身的执行时间

// 获得秒和微妙时间,显示和Greenwich的时间差,并且测试运行这段程序所需要的时间
//

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

int main(void){
	
	// 创建timeval结构体time1、time2,timval结构体用来存放秒(tv_sec)和微秒(tv_used)时间
	struct timeval time1, time2;

	// 创建timezone结构体timez
	// timezone函数用来存放Greenwich时间差和type of DST correction
	// 一定要包含<sys/time.h>头文件,否则没有struct timezone的实现体
	struct timezone timez;

	// 获得当前时间,该函数需要超级用户权限
	// gettimeofday:获取当前时间和时区信息,tz参数用于指向存放返回时间信息的缓冲区
	gettimeofday(&time1,&timez);

	printf("tv_sec: %d\n",time1.tv_sec);	//打印时间:秒
	printf("tv_usec: %d\n", time1.tv_usec); //打印时间:微秒

	printf("tz_minuteswest: %d\n", timez.tz_minuteswest);// 打印minutes west of Greenwich
	printf("tz_dsttime: %d\n", timez.tz_dsttime);		// 打印type of DST correction

	// 再次获取当前时间,并与time1的时间比较,计算程序执行时间
	gettimeofday(&time2, &timez);
	printf("time2_usec-time1_use: %d\n", (time1.tv_usec-time2.tv_usec));
	
	// 计算程序执行时间
	return 0;
}

运行结果为:

note:在使用gcc进行编译过程中,由于案例二中存在着变量类型不匹配,因此有几个警告,但不影响运行结果。

          类型不匹配的原因:是struct timeval结构体中的为long int整型,这是使用的是int整型,如果想要消除警告,只需将“%d”改为"%ld"即可。

 

note:time.h 是baiISO C99 标准日期时间头文件。
           sys/time.h 是duLinux 系统的日期时间头文件。
           sys/time.h 通常会包含zhiinclude time.h
           编写的代码如果是和平台无关的,则需要在代码里include time.h.
           但这样的话,使用time_t等数据结构的话可能需要自己转化一下
           通常如果代码可以是平台相关的,则只需要include sys/time.h


参考文献:程国钢, 张玉兰. Linux C编程从基础到实践, 清华大学出版社, 2015.

                  https://zhidao.baidu.com/question/1513557645630350940.html

                  https://baike.baidu.com/item/gettimeofday/3369586?fr=aladdin

©️2020 CSDN 皮肤主题: 书香水墨 设计师:CSDN官方博客 返回首页