linux 时间函数

gettimeofday(取得目前的时间)

有时候需要打印代码执行到某处的时间,或者需要计算程序执行的时间差。这时会用到gettimeofday函数,它可以返回自1970-01-01 00:00:00到现在经历的秒数,

函数说明:

#include <sys/time.h>

int gettimeofday ( struct timeval * tv , struct timezone * tz )

参数都是出参

struct timeval {
 time_t tv_sec;				//秒
 suseconds_t tv_usec;		//微秒
};

struct timezone {
 int tz_minuteswest;		//和Greenwich 时间差了多少分钟
 int tz_dsttime;			//日光节约时间的状态
};

返回值

成功则返回0,
失败返回-1,错误代码存于errno。

timeval中的tv_sec是time_t类型的,即long的类型。

在32位下为4个字节,能够表示的最大正整数是2147483647,而这个表示的时间最大能到2038-01-19 03:14:07,超过了之后就变为-2147483648,这就是linux2038年的问题。

而64位系统下的time_t类型即long类型长度为8个字节,可以用到几千亿年,这么长的时间完全不用担心溢出的问题。

tz_dsttime 所代表的状态如下

DST_NONE /*不使用*/

DST_USA /*美国*/

DST_AUST /*澳洲*/

DST_WET /*西欧*/

DST_MET /*中欧*/

DST_EET /*东欧*/

DST_CAN /*加拿大*/

DST_GB /*大不列颠*/

DST_RUM /*罗马尼亚*/

DST_TUR /*土耳其*/

DST_AUSTALT /*澳洲(1986年以后)*/

我们很可能会用到精确到毫秒的时间,这样可以这样写,

struct timeval tv;
gettimeofday(&tv, NULL);
int64_t ts = (int64_t)tv.tv_sec*1000 + tv.tv_usec/1000;

注意:

其中的(int64_t)类型转换对于32位的系统是必须的,否则乘上1000会溢出。

clock_gettime(获取不同要求的精确时间)

#include <time.h>

int clock_gettime(clockid_t clk_id, struct timespec* tp);

参数

入参

clk_id : 检索和设置的clk_id指定的时钟时间。

CLOCK_REALTIME:系统实时时间,随系统实时时间改变而改变,即从UTC1970-1-1 0:0:0开始计时,中间时刻如果系统时间被用户改成其他,则对应的时间相应改变
CLOCK_MONOTONIC:从系统启动这一刻起开始计时,不受系统时间被用户改变的影响
CLOCK_PROCESS_CPUTIME_ID:本进程到当前代码系统CPU花费的时间
CLOCK_THREAD_CPUTIME_ID:本线程到当前代码系统CPU花费的时间

出参

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

clock()

这个函数返回从“开启这个程序进程”到“程序中调用C++ clock()函数”时之间的CPU时钟计时单元数(clock tick)

在用多线程练习程序的时候, 需要测试性能,获取程序的运行时间。

一开始使用的是:

clock_t 类,而且这个用法还很简单如下

int i = 100000000;

clock_t start,finish; 												//定义开始,结束变量 

start = clock();													//初始化 

while( i-- ); 

finish = clock();													//初始化结束时间 

double duration = (double)(finish - start) / CLOCKS_PER_SEC;		//转换浮点型 

printf( "%lf seconds\n", duration );

这样就可以了,乍一看很合理呀, 程序开始获取,程序结束了获取时间,

使用注意:

后来查了资料发现clock()函数的功能:

当程序单线程或者单核心机器运行时,这种时间的统计方法是正确的。但是如果要执行的代码多个线程并发执行时就会出问题,因为最终end-begin将会是多个核心总共执行的时钟嘀嗒数,因此造成时间偏大。

time_t

1、 time.h

line77          typedef __time_t time_t;
line116         #include <bits/types.h>     		/* This defines __time_t for us.  */

2、bit/types.h

l139:      	__STD_TYPE __TIME_T_TYPE __time_t;     	/* Seconds since the Epoch.  */
# define 	__STD_TYPE          __extension__ typedef

3、#include <bits/typesizes.h>

#define 	__TIME_T_TYPE          		__SYSCALL_SLONG_TYPE
# define 	__SYSCALL_SLONG_TYPE     	__SLONGWORD_TYPE

4、bit/types.h

 #define __SLONGWORD_TYPE     long int

所以time_t是long int型。

上位: https://blog.csdn.net/lyz980926/article/details/43122107

时间纪元

UNIX认为1970年1月1日0点是时间纪元

大多数C语言程序都使用到一个叫做“标准时间库”的程序库,这个时间库用一个标准的4字节也就是32位的形式来储存时间信息。当初设计的时候,这个4字节的时间格式把1970年1月1日凌晨0时0分0秒(这个时间名叫 the Unix Epoch)作为时间起点,这时的时间值为0。以后所有的时间都是从这个时间开始一秒一秒累积得来的。

32位最大时间:
2038年1月19日星期二凌晨03:14:07

至于时间的问题随着64位操作系统的产生逐渐得到解决,因为用64位操作,系统可以时间表示到 292278994-08-17 15:12:55 807
即约2900亿年后的。到那时,位于猎户座旋臂的太阳,已经是黑矮星或暗黑物质,猎户座旋臂已经被重力波震断,银河系大概则已经变成小型似星体了。

Strftime函数

函数的功能将时间格式化,或者说格式化一个时间字符串

%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 每周的第几天,星期一为第一天 (值从1到7,星期一为1)
%U 第年的第几周,把星期日作为第一天(值从0到53)
%V 每年的第几周,使用基于周的年
%w 十进制表示的星期几(值从0到6,星期天为0)
%W 每年的第几周,把星期一做为第一天(值从0到53)
%x 标准的日期串
%X 标准的时间串
%y 不带世纪的十进制年份(值从0到99)
%Y 带世纪部分的十制年份
%z,%Z 时区名称,如果不能得到时区名称则返回空字符。
%% 百分号

如果想显示现在是几点了,并以12小时制显示

#include "time.h" 
#include "stdio.h" 

int main(void) 
{ 
	struct tm* ptr; 
	time_t lt; 
	char str[80]; 
	lt=time(NULL); 
	ptr=localtime(&lt); 
	strftime(str,sizeof(str),"Itisnow%I%p",ptr); 
	printf("%s\n",str); 
	return0; 
}

其运行结果为:

It is now 4PM

显示当前的完整日期

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

int main(void) 
{ 
	struct tm* newtime; 
	char tmpbuf[128]; 
	time_t lt1; 
	time(&lt1); 
	newtime=localtime(&lt1); 
	strftime(tmpbuf,128,"Todayis%A,day%dof%Bintheyear%Y.\n",newtime); 
	printf("%s\n",tmpbuf); 
	return0; 
}

运行结果:

Today is Saturday, day 30 of July in the year 2005.
#include<stdio.h> 
#include<time.h> 

int main() 
{ 
	time_t rawtime; 
	struct tm* timeinfo; 
	char timE[80]; 
	time(&rawtime); 
	timeinfo=localtime(&rawtime); 
	strftime(timE,80,"Data:\n%Y-%m-%d\nTime:\n%I:%M:%S\n",timeinfo); 
	printf("%s",timE); 
	return0; 
}

输出:

Data:
2010-09-02
Time:
04:22:11