C语言再学习 -- 时间函数
在软件设计中经常会用到关于时间的处理,用来计算语句、函数的执行时间,这时就需要精确到毫秒甚至是微妙的时间。我们首先来介绍一下,时间单位:
时间单位还有:秒(s)、毫秒(ms)、微秒 (μs)、纳秒(ns)、皮秒(ps)、飞秒(fs)、阿秒、渺秒
1 s = 10^3 ms = 10^6 us = 10^9 ns = 10^12 ps = 10^15 fs=10^18阿秒=10^21渺秒=10^43普朗克常数
一、首先介绍几个时间函数,
查看:man ctime
NAME asctime, ctime, gmtime, localtime, mktime, asctime_r, ctime_r, gmtime_r, localtime_r - transform date and time to broken-down time or ASCII SYNOPSIS #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, char *buf); 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); Feature Test Macro Requirements for glibc (see feature_test_macros(7)): asctime_r(), ctime_r(), gmtime_r(), localtime_r(): _POSIX_C_SOURCE >= 1 || _XOPEN_SOURCE || _BSD_SOURCE || _SVID_SOURCE || _POSIX_SOURCE DESCRIPTION The ctime(), gmtime() and localtime() functions all take an argument of data type time_t which represents calendar time. When interpreted as an absolute time value, it represents the number of seconds elapsed since the Epoch, 1970-01-01 00:00:00 +0000 (UTC). The asctime() and mktime() functions both take an argument representing broken-down time which is a representation separated into year, month, day, etc. Broken-down time is stored in the structure tm which is defined in <time.h> as follows: struct tm { int tm_sec; /* seconds */ int tm_min; /* minutes */ int tm_hour; /* hours */ int tm_mday; /* day of the month */ int tm_mon; /* month */ int tm_year; /* year */ int tm_wday; /* day of the week */ int tm_yday; /* day in the year */ int tm_isdst; /* daylight saving time */ };
ctime函数:可以把time函数得到的结果转换成一个时间字符串
gmtime函数:可以把time函数得到的结果按照格林尼治时间转换成一个结构体
localtime函数:可以把time函数得到的结果按照当前时区转换成一个结构体
asctime函数:可以把一个记录时间的结构体转换成字符串,一般与上两个函数合用的
格林时间,与北京时间换算,参看:TIMEBIE
/* 时间函数演示 */
#include <stdio.h>
#include <time.h>
int main()
{ time_t tm = 0;//long int别名 //time(0)是一个long int空地址 time (&tm); printf ("%s\n", ctime (&tm)); struct tm *p_tm = gmtime (&tm); printf ("%s\n", asctime (p_tm)); struct tm *p_tm1 = localtime (&tm); //声明语句 printf ("%s\n", asctime (p_tm1)); return 0;
}
输出结果:
Sat Jan 14 14:48:10 2017 Sat Jan 14 06:48:10 2017 Sat Jan 14 14:48:10 2017
二、Linux 获取时间戳
第一种方法:微秒级时间戳
查看:man gettimeofday
功能:获取/设置时间
NAME gettimeofday, settimeofday - get / set time SYNOPSIS #include <sys/time.h> int gettimeofday(struct timeval *tv, struct timezone *tz); int settimeofday(const struct timeval *tv, const struct timezone *tz); Feature Test Macro Requirements for glibc (see feature_test_macros(7)): settimeofday(): _BSD_SOURCE DESCRIPTION The functions gettimeofday() and settimeofday() can get and set the time as well as a timezone. The tv argument is a struct timeval (as specified in <sys/time.h>): struct timeval { time_t tv_sec; /* seconds */ suseconds_t tv_usec; /* microseconds */ }; and gives the number of seconds and microseconds since the Epoch (see time(2)). The tz argument is a struct timezone: struct timezone { int tz_minuteswest; /* minutes west of Greenwich */ int tz_dsttime; /* type of DST correction */ }; If either tv or tz is NULL, the corresponding structure is not set or returned.
下面是个简单的例子,用来统计程序的执行时间:
#include <stdio.h>
#include <sys/time.h> int main(void)
{ struct timeval start,end; gettimeofday( &start, NULL ); /*测试起始时间*/ usleep (10000); //使用 usleep gettimeofday( &end, NULL ); /*测试终止时间*/ int timeuse = (end.tv_usec - start.tv_usec); printf("运行时间为:%d us\n",timeuse); return 0; }
输出结果:
10193 us
NAMEftime - return date and timeSYNOPSIS#include <sys/timeb.h>int ftime(struct timeb *tp);DESCRIPTIONThis function returns the current time as seconds and milliseconds since the Epoch, 1970-01-01 00:00:00 +0000 (UTC). The time isreturned in tp, which is declared as follows:struct timeb {time_t time;unsigned short millitm;short timezone;short dstflag;};Here time is the number of seconds since the Epoch, and millitm is the number of milliseconds since time seconds since the Epoch.The timezone field is the local timezone measured in minutes of time west of Greenwich (with a negative value indicating minuteseast of Greenwich). The dstflag field is a flag that, if nonzero, indicates that Daylight Saving time applies locally during theappropriate part of the year.POSIX.1-2001 says that the contents of the timezone and dstflag fields are unspecified; avoid relying on them.RETURN VALUEThis function always returns 0. (POSIX.1-2001 specifies, and some systems document, a -1 error return.)
tp结构定义:
struct timeb{
time_t time; /* 为1970-01-01至今的秒数*/
unsigned short millitm; /* 千分之一秒即毫秒 */
short timezonel; /* 为目前时区和Greenwich相差的时间,单位为分钟 */
short dstflag; /* 为日光节约时间的修正状态,如果为非0代表启用日光节约时间修正 */
};
#include <stdio.h>
#include <sys/timeb.h> long long getSystemTime() { struct timeb t; ftime(&t); return (1000 * t.time + t.millitm) * 1000;
} int main() { long long start = getSystemTime(); usleep(3000); long long end = getSystemTime(); printf("time: %lld us\n", end-start); return 0;
}
输出结果:
3000 us
NAMEdifftime - calculate time differenceSYNOPSIS#include <time.h>double difftime(time_t time1, time_t time0);DESCRIPTIONThe difftime() function returns the number of seconds elapsed between time time1 and time time0, represented as a double. Each ofthe times is specified in calendar time, which means its value is a measurement (in seconds) relative to the Epoch, 1970-01-0100:00:00 +0000 (UTC).
#include <stdio.h>
#include <time.h> int main(){ time_t t_start, t_end; t_start = time(NULL) ; sleep(3); t_end = time(NULL) ; printf("time: %.0f s\n", difftime(t_end,t_start)) ; return 0;
}
输出结果:
time: 3 s
clock_t clock(void) ;
简单而言,就是该程序从启动到函数调用占用CPU的时间。这个函数返回从“开启这个程序进程”到“程序中调用clock()函数”时之间的CPU时钟计时单元(clock tick)数,在MSDN中称之为挂钟时间(wal-clock);若挂钟时间不可取,则返回-1。其中clock_t是用来保存时间的数据类型。
#ifndef _CLOCK_T_DEFINED
typedef long clock_t;
#define _CLOCK_T_DEFINED
#endif
很明显,clock_t是一个长整形数。在time.h文件中,还定义了一个常量CLOCKS_PER_SEC,它用来表示一秒钟会有多少个时钟计时单元,其定义如下:
#define CLOCKS_PER_SEC ((clock_t)1000)
可以看到每过千分之一秒(1毫秒),调用clock()函数返回的值就加1。下面举个例子,你可以使用公式clock()/CLOCKS_PER_SEC来计算一个进程自身的运行时间:
void elapsed_time()
{
printf("Elapsed time:%u secs.\n",clock()/CLOCKS_PER_SEC);
}
当然,你也可以用clock函数来计算你的机器运行一个循环或者处理其它事件到底花了多少时间:
#include"time.h"
#include"stdlib.h"
#include"stdio.h" void sleep (clock_t wait); int main (void)
{ long i = 600000000L; clock_t start, finish; double duration; printf( "延时3秒\n" ); sleep( (clock_t)3 * CLOCKS_PER_SEC ); printf( "Done!\n" ); start = clock(); printf("程序启动,start = %ld\n", start); while( i-- ) ; finish = clock(); printf("循环结束,finish = %ld\n", finish); duration = (double)(finish - start) / CLOCKS_PER_SEC; printf( "CPU 占用的总时间: %2.1f seconds\n", duration ); printf("程序退出...\n");return 0;
} void sleep( clock_t wait )
{ clock_t goal; goal = wait + clock(); while( goal > clock() ) ;
}
输出结果:
延时3秒
Done!
程序启动,start = 3000000
循环结束,finish = 4810000
CPU 占用的总时间: 1.8 seconds
程序退出...
#include <stdio.h>
#include<time.h>
int main(void)
{int b = 0, i = 0;b=clock()/CLOCKS_PER_SEC;for(i=0;i<10;)//完成100秒定时{i = i-b;i = clock()/CLOCKS_PER_SEC;}printf ("finish\n");return 0;
}
输出结果:
time ./a.out
finishreal 0m10.171s
user 0m2.180s
sys 0m7.820s
time ./a.out
real 0m10.171s
user 0m2.180s
sys 0m7.820s
查看:man getitimer
NAME getitimer, setitimer - get or set value of an interval timer SYNOPSIS #include <sys/time.h> int getitimer(int which, struct itimerval *curr_value); int setitimer(int which, const struct itimerval *new_value, struct itimerval *old_value); DESCRIPTION The system provides each process with three interval timers, each decrementing in a distinct time domain. When any timer expires, a signal is sent to the process, and the timer (potentially) restarts. ITIMER_REAL decrements in real time, and delivers SIGALRM upon expiration. ITIMER_VIRTUAL decrements only when the process is executing, and delivers SIGVTALRM upon expiration. ITIMER_PROF decrements both when the process executes and when the system is executing on behalf of the process. Coupled with ITIMER_VIRTUAL, this timer is usually used to profile the time spent by the application in user and kernel space. SIGPROF is delivered upon expiration. Timer values are defined by the following structures: struct itimerval { struct timeval it_interval; /* next value */ struct timeval it_value; /* current value */ };
The function getitimer() fills the structure pointed to by curr_value with the current setting for the timer specified by which (one of ITIMER_REAL, ITIMER_VIRTUAL, or ITIMER_PROF). The element it_value is set to the amount of time remaining on the timer, or zero if the timer is disabled. Similarly, it_interval is set to the reset value. The function setitimer() sets the specified timer to the value in new_value. If old_value is non-NULL, the old value of the timer is stored there. Timers decrement from it_value to zero, generate a signal, and reset to it_interval. A timer which is set to zero (it_value is zero or the timer expires and it_interval is zero) stops. Both tv_sec and tv_usec are significant in determining the duration of a timer. Timers will never expire before the requested time, but may expire some (short) time afterward, which depends on the system timer resolution and on the system load; see time(7). (But see BUGS below.) Upon expiration, a signal will be generated and the timer reset. If the timer expires while the process is active (always true for ITIMER_VIRTUAL) the signal will be delivered immediately when generated. Otherwise the delivery will be offset by a small time dependent on the system loading. RETURN VALUE On success, zero is returned. On error, -1 is returned, and errno is set appropriately.
第一个参数:计时器的类型
ITIMER_REAL--真实计时器,主要描述进程运行的真实时间,通过产生SIGALRM信号工作(掌握)
ITIMER_VIRTUAL 虚拟计时器,主要描述进程在用户空间消耗的时间,通过产生SIGVTALRM信号工作(了解)
ITIMER_PROF--实用计时器,主要描述进程在用户空间和内核空间共同消耗的时间,通过产生SIGPROF信号工作(了解)
第二个参数:计时器的新值
struct itimerval
{
struct timeval it_interval; /* next value */ //间隔时间
struct timeval it_value; /* current value */ //启动时间
};
struct timeval
{
long tv_sec; /* seconds */ //秒数
long tv_usec; /* microseconds */ //微秒
};
第三个参数:用于获取计时器的旧值,不想带直接给NULL
函数功能:主要用于用户获取/设置计时器的数值
下面是个简单的例子:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/time.h>void fa(int signo)
{printf("贪吃蛇移动了一步\n");
}int main()
{struct itimerval t_start, t_end;getitimer (ITIMER_REAL, &t_start);printf("Start time: %ld us\n", t_start.it_value.tv_usec);//设置SIGALRM进行自定义处理signal(SIGALRM,fa);struct itimerval timer;//设置启动时间timer.it_value.tv_sec=0;//秒数timer.it_value.tv_usec=30000;//微秒//设置间隔时间timer.it_interval.tv_sec=1;timer.it_interval.tv_usec=0;//设置真实计时器开始工作int res=setitimer(ITIMER_REAL,&timer,NULL);if(-1==res){perror("settimer"),exit(-1);}getitimer (ITIMER_REAL, &t_end);printf("End time: %ld us\n", t_end.it_value.tv_usec);long cost_time = t_end.it_value.tv_usec - t_start.it_value.tv_usec;printf("Cost time: %ld us\n", cost_time);while (1);return 0;
}
输出结果:
Start time: 0 us
End time: 29997 us
Cost time: 29997 us
贪吃蛇移动了一步
贪吃蛇移动了一步
贪吃蛇移动了一步
贪吃蛇移动了一步
贪吃蛇移动了一步
^C
扩展:
1、预定义宏里有 __TIME__
__TIME__源文件编译时间,格式为“hh: mm: ss”
#include <stdio.h>
int main (void)
{ printf ("The time is %s\n", __TIME__); return 0;
}
输出结果:
The time is 18:24:24
2、头文件 time.h
日期和时间函数: 本类别给出时间和日期处理函数
----------------------------------------
下面的函数感兴趣的可以自行百度
时间操作函数得到处理器时间 clock
得到时间差difftime
设置时间mktime
得到时间time
时间转换函数 得到以ASCII码表示的时间asctime
得到字符串表示的时间ctime
得到指定格式的时间strftime
__BEGIN_NAMESPACE_STD
/* Time used by the program so far (user time + system time).The result / CLOCKS_PER_SECOND is program time in seconds. */
extern clock_t clock (void) __THROW;/* Return the current time and put it in *TIMER if TIMER is not NULL. */
extern time_t time (time_t *__timer) __THROW;/* Return the difference between TIME1 and TIME0. */
extern double difftime (time_t __time1, time_t __time0)__THROW __attribute__ ((__const__));/* Return the `time_t' representation of TP and normalize TP. */
extern time_t mktime (struct tm *__tp) __THROW;/* Format TP into S according to FORMAT.Write no more than MAXSIZE characters and return the numberof characters written, or 0 if it would exceed MAXSIZE. */
extern size_t strftime (char *__restrict __s, size_t __maxsize,__const char *__restrict __format,__const struct tm *__restrict __tp) __THROW;
__END_NAMESPACE_STD
3、根据文件时间戳的相关属性来查找文件
参看:C语言再学习 -- Linux下find命令用法
我们可以使用 stat 命令来查看一个文件的时间信息,如下:
root@zslf-virtual-machine:/mnt/test# stat ./ 文件:"./" 大小:4096 块:8 IO 块:4096 目录
设备:801h/2049d Inode:291601 硬链接:2
权限:(0755/drwxr-xr-x) Uid:( 1000/ zslf) Gid:( 1000/ zslf)
最近访问:2016-11-25 09:45:24.699140785 +0800
最近更改:2016-11-25 09:45:22.255140690 +0800
最近改动:2016-11-25 09:45:22.255140690 +0800
创建时间:-
-atime、-mtime、-ctime、-amin、-mmin、-cmin
这里的 -atime、-mtime、-ctime 分别对应的是 “最近一次访问时间”,“最近一次内容修改时间”,“最近一次属性修改时间”,这里的atime的单位指的是“天”,amin 的单位是分钟。
参看:Linux之atime,mtime,ctime
文件的 Access time,atime:是在读取文件或者执行文件时更改的。
文件的 Modified time,mtime: 是在写入文件时随文件内容的更改而更改的。
文件的 Create time,ctime :是在写入文件、更改所有者、权限或链接设置时随 Inode 的内容更改而更改的。
文件各种事件标记的显示方法
ls -lc filename 列出文件的 ctime
ls -lu filename 列出文件的 atime
ls -l filename 列出文件的 mtime
查看:man ls
-c with -lt: sort by, and show, ctime (time of last modification of file status information) with -l: show ctime and sort byname otherwise: sort by ctime, newest first-u with -lt: sort by, and show, access time with -l: show access time and sort by name otherwise: sort by access time-l use a long listing format
查找在五天内没有访问过的文件
root@zslfe:/mnt/test# find ./ -atime +5
查找在五天内访问过的文件
root@zslf:/mnt/test# find ./ -atime -5
./
./f.sh
./g.sh
./a.sh
./c.sh
./b.sh
4、UNIX时间戳
将当前时间以Unix时间戳表示:
# date +%s
1492565563
(2)转换指定日期为Unix时间戳:
# date -d '2013-2-22 22:14' +%s
1361542440
(3)将Unix时间戳转换为日期时间
不指定日期时间的格式:
# date -d @1361542596
Fri Feb 22 22:16:36 CST 2013
(4)指定日期格式的转换:
# date -d @1361542596 +"%Y-%m-%d %H:%M:%S"
2013-02-22 22:16:36
C语言再学习 -- 时间函数相关推荐
- C语言再学习 -- 随机数函数
参看:C++中随机函数rand()和srand()的用法 rand ()函数:可以用来获得一个随机数 所在头文件: stdlib.h 函数说明 : rand()的内部实现是用线性同余法做的,它不是真的 ...
- C语言再学习 -- 字符串和字符串函数
最近身体很不给力,很乏累!白天没精神,晚上睡不着,心情还很烦躁.看书都有点看不下去的样子,到了C语言最难掌握的部分了,数组.指针.字符串.硬着头皮看书总结吧. 一.字符串 1.字符串介绍 字符串是以空 ...
- C语言再学习 -- 关键字return和exit ()函数
终于到了最后一个关键字 return 了.感觉时间过的飞快,转眼间又是一年,如果时间可以 return 就好了. 一.return 介绍 参看:C语言中return 用法 1.含义: return 表 ...
- C语言再学习 -- 再论数组和指针
之前有总结指针数组,但是现在看来总结的太简单了.好多重要的知识点都是一带而过的.本想在后面添加后来想想算了,还是再写一篇文章来详细介绍数组和指针这对冤家吧. 之前总结的,参看:C语言再学习 -- 数组 ...
- C语言再学习 -- 关键字const
const 关键字其实我们并不陌生,之前有讲过const修饰数组和指针.现在来详细介绍这个关键字. 参看:[C/C++和指针]著名的<const的思考> 一.const 介绍 1.cons ...
- C语言再学习 -- 存储类型关键字
定义: 是对声明的实现或者实例化.连接器(linker)需要它(定义)来引用内存实体.与上面的声明相应的定义如下:参看:C语言再学习 -- 存储类.链接 C语言中有 5 个作为存储类说明符的关键字,分 ...
- C语言再学习 -- 结构和其他数据形式
一.结构体 结构体可以用来创建新的数据类型,这种数据类型可以把多个其他类型合并成一个整体,采用结构体声明的变量叫做结构变量,结构体需要先声明然后才能使用,声明结构体需要使用struct关键字,结构体声 ...
- C语言再学习 -- C 预处理器
gcc/cc xxx.c 可以编译链接C源程序生成一个可执行文件 a.out 整个过程中可以划分为以下的4步流程: (1)预处理/预编译: 主要用于包含头文件的扩展,以及执行宏替换等 //加上 -E ...
- C语言再学习 -- 存储类、链接
这一章是我看的时间最长的一章了,表面上是有很多关键字和几个函数需要学习,其实我知道是自己最近不在状态了,做项目没进展,看书看不下去,两头都放不下,最后两头都没有做好.不由的想起一句话,你不快乐是因为: ...
最新文章
- Asp.net 的网络打印 – Javascript 控制打印
- 普通用户下变成-bash-3.2$的解决方法
- Bitcoin.com| 比特币现金2019·年度回顾
- B02_NumPy数据属性(ndarray.ndim,ndarray.shape,ndarray.itemsize,ndarray.flags)
- 【FPGA Verilog】实验二:key按键基础实验
- mysql 1055 解决方案_MySQL报错1055解决方案 - 树懒学堂
- linux的poll_wait函数,select() 与 poll()两个函数接口的作用
- Java程序员从笨鸟到菜鸟之(八十七)跟我学jquery(三)jquery动态创建元素和常用函数示例...
- 车牌识别sdk android,Android车牌识别sdk
- mysql msdtc 不支持_如何解决服务器上的msdtc不可用问题
- 华为安全HCIP-Security H12-721、H12-722、H12-723题库,含三套vce软件
- 51单片机LCD1602程序详解
- 分享常见的视频加密算法原理及其优缺点
- PPT之如何设置一个箭头围绕一个顶点旋转?
- [创业-18]:财务报表之资产负债表
- leelen可视对讲怎么接线_电子门铃怎么安装 电子对讲门铃安装方法【详细介绍】...
- 香港伦敦金交易平台排行榜(2022最新版)
- CSDN 下载 版块问题解决日志
- 北京某高端养老机构开业3年 : 1次失信,2场官司,3项处罚,处在高危中的养老行业如何应对多维度经营风险?
- 从制造中来到智造中去