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(<);
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(<1);
newtime=localtime(<1);
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