第四章 时间函数
//需要的头文件
typedef long time_t;
asctime : char *asctime(const struct tm *timeptr);
将struct tm 数据转换为世界时间
time_t timep;
time(&timep);
printf("%s\n",asctime(gmtime(&timep)); // Tue Dec 5 11:53:23 2017
clock : clock_t clock(void);
返回进程所占用CPU的大约时间。
//clock 时间单位是微秒;
long i = 100000000L;
clock_t start;
clock_t finish;
start = clock();
while(i--); //模拟耗时操作
//sleep(5); //sleep时间不会计算到clock时间;
finish = clock();
printf("clock start is %ld\n", start);
printf("clock finish is %ld\n", finish);
ctime : char *ctime(const time_t *timep);
将time_t 结构体中的信息转换为世界时间
time_t timep;
time(&timep);
printf("%s\n",ctime(&timep));
difftime : double difftime(time_t time1, time_t time0);
用来计算参数时间time_t1 time_t0 所代表的时间差距,结果是以double型值返回。
两个参数的时间皆是以1970.1.1 00:00:00算起的UTC时间。
time_t timetp1, timetp2;
time(&timep1);
sleep(3);
time(&timept2);
double diff = difftime(timept2, timep1); //3.000000
ftime : int ftime(struct timeb *tp);
将当前时间日期由tp所指的结构返回,tp结构定义:
struct timeb{
time_t time; //公元1970年1月1日零点零分 至今多少秒数;
unsigned short millitm; //为千分之一秒;
short timezone; //为目前时区和Greenwich相差的时间,单位为分钟;
short dstflag; //为日光节约时间的修正状态,如果为非0代表启用日光节约修正时间;
};
返回值固定为0;
struct timeb tp;
ftime(&tp);
printf("time %ld\n",(long int) tp.time);
printf("millitm %ld\n", (long int)tp.millitm);
printf("timezone %d\n", tp.timezone);
printf("dstflag %d\n", tp.dstflag);
gettimeofday : int gettimeofday(struct timeval *tv, struct timezone *tz);
把目前的时间由tv所指的结构返回,当地时区的信息则放到tz所指的结构中,成功返回0,失败返回-1,错误原因存于errno中。
错误代码:EFAULT指针tv或tz所指的内存空间超出存取权限;
sturct timeval {
long tv_sec; /*秒*/
long tv_usec; /*微秒*/
};
struct timezone{
int tz_minuteswest; /*和Greenwich时间差了多少分钟*/
int tz_dsttime; /*日光节约时间的状态*/
};
上述两个结构体定义在/usr/include/sys/time.h;
tz_dsttime所代表的状态如下:
DST_NONE /*不使用*/
DST_USA /*美国*/
DST_AUST /*澳洲*/
DST_WET /*西欧(Western European)*/
DST_MET /*中欧 (Middle European)*/
DST_EET /*东欧 (Eastern European)*/
DST_CAN /*加拿大*/
DST_GB /*大不列颠*/
DST_RUM /*罗马尼亚*/
DST_TUR /*土耳其*/
DST_AUSTALT /*澳洲(1986年以后)*/
struct timeval tv;
struct timezone tz;
gettimeofday(&tv, &tz);
printf("tv_sec :%ld\n", tv.tv_sec);
printf("tv_usec :%ld\n", tv.tv_usec);
printf("tz_minuteswest:%d\n", tz.tz_minuteswest);
printf("tz_dsttime:%d\n", tz.tz_dsttime);
gmtime :struct tm *gmtime(const time_t *timep);
将参数timep所指向的time_t结构体中的信息转换成真实世界所使用的时间日期表示方法,然后将结果由tm返回;
些函数返回的时间日期未经时区转换,而是UTC时间;返回结构tm代表目前的UTC时间;
struct tm {
int tm_sec; //目前的秒数,范围0~59;
int tm_min; //目前的分数,范围0~59;
int tm_hour; //从午夜算起的时数,范围0~23;
int tm_mday; //目前月份的日数,范围1~31;
int tm_mon; //代表目前月份,从一月算起,范围0~11;
int tm_year; //从1900年算起至今的年数;
int tm_wday; //一星期中的日数,从星期日算起,范围0~6;
int tm_yday; //从今年1月1日算起至今的天数,范围0~365;
int tm_isdst; //日光节约时间的旗标;
};
time_t timet;
struct tm *p;
time(&timet);
p = gmtime(&timet);
printf("year %d, month %d, day %d\n", (1900+p->tm_year), p->tm_mon, p->tm_mday);
printf("weak %d, hour %d, min %d, sec %d\n", p->tm_wday, p->tm_hour, p->tm_min, p->tm_sec);
localtime : struct tm *localtime(const time_t *timep);
将参数timep所指的是time_t结构中的信息转换成真实世界所使用的时间日期表示方法,然后将结果由结构体tm返回;
些函数返回的时间日期已经转换成当地时区;
time_t timep;
struct tm *p;
time(&timep);
p = localtime(&timep); /*获取当地时间*/
printf("%d-%d-%d\n", (1990+p->tm_year), (1+p->tm_mon), p->tm_mday);
printf("%d-%d-%d-%d\n", p->tm_wday, p->tm_min, p->tm_sec);
mktime : time_t mktime(struct tm *timeptr);
用来将timeptr所指的tm结构数据转换成从公元1970年1月1日0时0分0秒算起至今的UTC时间所经过的秒数;
/*用time()取得时间(秒数),再用localtime()转换struct tm,再用mktime()将tm转换成原来的秒数*/
time_t timep;
struct tm *p;
time(&timep);
printf("1 %ld\n",timep);
p = localtime(&timep);
timep = mktime(p);
printf("2 %ld\n",timep);
settimeofday : int settimeofday(const struct timeval *tv, const struct timezone *tz);
设置目前的时间;会把目前的时间设置成由tv所指向的结构信息,当地时区的信息设置成tz所在的结构。
注:只有root权限才能使用此函数修改时间;
成功返回0,否则返回-1,错误原因存于errno中。
EPERM :非root权限调用settimeofday();权限不够。
EINVAL :时区或某个数据不正确,无法设置时间;
strftime : size_t strftime(char *s, size_t max, const char *format, const struct tm *tm);
格式化日期和时间;将参数tm的时间结构,依照参数format所指定的字符串格式做转换,转换后的字符串内容将复制到参数s所指向的
数组中,该字符串的最大长度为参数max所控制;
参数format的格式和一般格式化字符串相当类似,都是以‘%’字符做控制,下面是其格式指令:
%a 当地星期日期的名称缩写,如sun;
%A 当地星期日期的完整名称,如Sunday;
%b 当地月份缩写;
%B 当地月份完整名称;
%c 当地适当的日期与时间表示法;
%C 以year/100表示年份;
%d 月里的天数,表示法为01-31;
%D 相当于“%m/%d/%y” 格式;
%e 同%d为一个月里的天数,表示法为1-31;
%h 和%b相同;
%H 以24小时制表示小时数(00-23);
%I 以12小时制表示小时数(01-12);
%j 一年中的天数(001-366);
%k 同%H,但表示法为0-23;
%l 同%I, 但表示法为1-12;
%m 月份(01-12);
%M 分数(00-59);
%n 同\n;
%p 显示对应的AM 或 PM表示;
%P 和%p相同,但是用小写的am 和 pm表示;
%r 相当于使用“%I:%M:%S %P”;
%R 相当于使用“%H:%M”格式;
%s 从1970-01-01 00:00 UTC算起至今的秒数;
%S 秒数(00-61);
%t 同%t;
%T 24小时时间表示,相当于使用“%H:%M:%S”格式;
%u 一星期中的星期日期,范围1-7,星期一从1开始;
%U 一年中的星期数(00-53),一月第一个星期日开始为01;
%w 一星期中的星期日期,范围0-6,星期日从0开始;
%W 一年中的星期数(00-53),一月第一个星期日开始为01;
%x 当地适当的日期表示;
%X 当地适当的时间表示;
%y 一世纪中的年份(00-99);
%Y 完整的公元年份表示;
%Z 使用的时区名称;
%% ‘%’符号;
环境变量TZ和TC_TIME会影响此函数的结果;
char buf[32];
int n;
time_t clock;
struct tm *tmp;
time(&clock);
tmp = gmtime(&clock);
for (n=0; format[n]!=NULL; n++) {
strftime(buf, sizeof(buf), format[n], tmp);
printf("%s ==> %s\n", format[n], buf);
}
time : time_t time(time_t *t);
获取目前时间,返回从公元1970年1月1日00:00:00的UTC时间算起到现在的秒数。
t为非空指针返回值将存于t;成功返回秒数,失败返回(time_t)-1值,错误原因存于errno中;
int seconds = time_t((time_t*)NULL);
printf("%d\n", seconds);
tzset : void tzset(void);
extern char *tzname[2];
设置时区以供时间转换,用来将环境变量TZ设给全局变量tzname,也就是从环境变量取得目前当地的时区,
时间转换函数会自动设用此函数。若环境变量TZ未设置,全局变量tzname会依照/etc/localtime找出最接近当地的时区。
如果环境变量TZ为NULL,或无法判认,则使用UTC时间;
此函数总能调用成功,并且初始化全局变量tzname;
利用gettimeofday()函数可以获取系统时间,其中,比较重要的结构体为
struct timeval {
time_t tv_sec;
suseconds_t tv_usec;
};
#include
#include
#include
#include
double difftimeval(const struct timeval *start, const struct timeval *end)
{
double d;
time_t s;
suseconds_t u;
s = start->tv_sec - end->tv_sec;
u = start->tv_usec - end->tv_usec;
d = s;
d *= 1000000.0;
d += u;
return d;
}
char *strftimeval(const struct timeval *tv, char *buf)
{
struct tm tm;
size_t len = 28;
localtime_r(&tv->tv_sec, &tm);
strftime(buf, len, "%Y-%m-%d %H:%M:%S", &tm);
len = strlen(buf);
sprintf(buf + len, ".%06.6d", (int)(tv->tv_usec));
return buf;
}
int main(int argc, char *argv[])
{
char buf[28];
struct timeval start,end;
gettimeofday(&start, NULL);
usleep(100);
gettimeofday(&end, NULL);
printf("%s\n", strftimeval(&start, buf));
printf("%s\n", strftimeval(&end, buf));
printf("%.0f\n", difftimeval(&end, &start));
return 0;
}