linux里所有关于时间的函数整理

来源:互联网 发布:理光软件研究所待遇 编辑:程序博客网 时间:2024/05/19 02:06

东西都是从网上收集整理的

 

1.clock()
clock()是C/C++中的计时函数,表示从程序启动到clock()调用时
之间的CPU时钟计时单元(clock tick)数,即滴答多少下,而
而1秒钟要滴答CLOCKS_PER_SEC多下。数据类型使用clock_t
#include<time.h>
#include<stdio.h>
int main()
{
 clock_t start = clock();
 long i = 100000000l;//定义long型变量
 long j = i;
 while(i--);
 clock_t stop = clock();
 double seconds = double(stop - start)/CLOCKS_PER_SEC;//转换成秒
 printf("run %ld loops cost %f seconds\n",j,seconds);//注意long,double打印
 return 0;
}

2.time命令
Linux中time命令,我们经常用来计算某个程序的运行耗时real,
用户态cpu耗时user,系统态cpu耗时system
运行耗时即程序开始到结束共耗时多少秒
例:
time sleep 2
0.000u 0.000s 0:02.00 0.0% 0+0k 0+0io 0pf+0w
总耗时2秒,用户,核心都为0秒,cpu使用率为(user+system)/real*100%

首先了解下核心态和用户态

核心态(Kernel Mode):
在内核态,代码拥有完全的,不受任何限制的访问底层硬件的能力。
可以执行任意的CPU指令,访问任意的内存地址。内核态通常情况
下,都是为那些最底层的,由操作系统提供的,可信可靠的代码来
运行的。内核态的代码崩溃将是灾难性的,它会影响到整个系统。

用户态(User Mode):
在用户态,代码不具备直接访问硬件或者访问内存的能力,而必
须借助操作系统提供的可靠的,底层的APIs来访问硬件或者内存。
由于这种隔离带来的保护作用,用户态的代码崩溃(Crash),系统
是可以恢复的。我们大多数的代码都是运行在用户态的。

注意下面的几个误区:
real 肯定等于 user+system//程序sleep2秒
real 肯定大于 user+system//单核时成立,多核时不成立
real 肯定小于 user+system//同上
总之就是他们没有任何造价关系

3.time()//返回系统时间
time_t time( time_t *time );
功能: 获取当前的系统时间,返回的结果是一个time_t类型,
其实就是一个大整数,其值表示从CUT(Coordinated Universal Time)
时间1970年1月1日00:00:00(称为UNIX系统的Epoch时间)到当前时刻
的秒数。然后调用localtime将time_t所表示的CUT时间转换为本地时
间(我们是+8区,比CUT多8个小时)并转成struct tm类型,该类型
的各数据成员分别表示年月日时分秒。
补充说明:time函数的原型也可以理解为 long time(long *tloc),
即返回一个long型整数。因为在time.h这个头文件中time_t实际上就是:
typedef long time_t;

#include<time.h>
#include<stdio.h>
int main()
{
 time_t start = time(NULL);
 long i = 100000000l;//定义long长整型变量
 long j = i;
 while(i--);
 time_t stop = time(NULL);
 long seconds = stop - start;//转换成秒
 printf("run %ld loops cost %ld seconds\n",j,seconds);
 return 0;
}

4.localtime
struct tm *localtime( const time_t *time );//注意这里的time_t就是long型,所以可以把已经获得的时间的秒数(也为long),传入从而构造出一个tm型,该用法可以获取timespce类型
返回指向tm 结构体的指针.tm结构体是time.h中定义的用于分
别存储时间的各个量(年月日等)的结构体。
localtime是 把从1970-1-1零点零分到当前时间系统所偏移的秒数时间转
换为本地时间
,而gmtime函数转换后的时间没有经过时区变换,是UTC时间
#include <stdio.h>
#include <time.h>
int main(void)
{
 time_t timer;//time_t就是long int 类型
 struct tm *tblock;
 timer = time(NULL);
 tblock = localtime(&timer);
 printf("Local time is: %s\n",asctime(tblock));
 return 0;
}
上面的例子用了asctime函数,下面这个例子不使用这个函数一样能获取
系统当前时间。需要注意的是年份加上1900,月份加上1。
#include<time.h>
#include<stdio.h>
int main()
{
 struct tm *t;
 time_t tt;
 time(&tt);
 t=localtime(&tt);
 printf("%4d年%02d月%02d日 %02d:%02d:%02d\n",t->tm_year+1900,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec);//注意虽然转换为本地时间,但用tm类型时还要自己给年加1900,月分加1
 return 0;
}
 

5.asctime
char* asctime (const struct tm * timeptr).
把timeptr指向的tm结构体中储存的时间转换为字符串字符串格式
返回,格式为:Www Mmm dd hh:mm:ss yyyy。其中Www为星期;Mmm为
月份;dd为日;hh为时;mm为分;ss为秒;yyyy为年份。

6.gmtime
struct tm *gmtime( const time_t *time );
gmtime函数转换后的时间没有经过时区变换,是UTC时间
#include <stdio.h>
#include <time.h>
int main(void)
{
 time_t t;
 struct tm *gmt, *area;
 //tzset(); /*tzset()*/
 t = time(NULL);
 area = localtime(&t);
 printf("Local time is: %s", asctime(area));
 gmt = gmtime(&t);
 printf("GMT is: %s", asctime(gmt));
 return 0;
}

7.ctime
char * ctime(const time_t *t);
等同于
asctime(localtime(t));

8.struct tm
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代表一月) - 取值区间为[0,11] */
int tm_year; /* 年份,其值从1900开始 */
int tm_wday; /* 星期–取值区间为[0,6],其中0代表星期天,1代表星期一,以此类推 */
int tm_yday; /* 从每年的1月1日开始的天数–取值区间为[0,365],其中0代表1月1日,1代表1月2日,以此类推 */
int tm_isdst; /* 夏令时标识符,实行夏令时的时候,tm_isdst为正。不实行夏令时的进候,tm_isdst为0;不了解情况时,tm_isdst()为负。*/
long int tm_gmtoff; /*指定了日期变更线东面时区中UTC东部时区正秒数或UTC西部时区的负秒数*/
const char *tm_zone; /*当前时区的名字(与环境变量TZ有关)*/
};

9.difftime
double difftime( time_t time2, time_t time1 );
功能:函数返回时间参数time2和time1之差的秒数表示

10.mktime
time_t mktime( struct tm *time );
功能:函数转换参数time 类型的本地时间至日历时间,并返回结果。如果发生错误,返回-1。

11.strftime
size_t strftime( char *str, size_t maxsize, const char *fmt, struct tm *time );
功能:函数按照参数fmt所设定格式将time类型的参数格式化为日期时间信息,然后存
储在字符串str中(至多maxsize 个字符)。用于设定时间不同类型的代码为:
代码
 含义
%a
 星期的缩略形式
%A
 星期的完整形式
%b
 月份的缩略形式
%B
 月份的完整形式
%c
 月份的缩略形式
%d
 月中的第几天(1-31)
%H
 小时, 24小时格式 (0-23)
%I
 小时, 12小时格式  (1-12)
%j
 年中的第几天(1-366)
%m
 月份 (1-12). Note: 某些版本的Microsoft Visual C++ 可能使用取值范围0-11.
%M
 分钟(0-59)
%p
 本地时间的上午或下午(AM or PM)
%S
 秒钟(0-59)
%U
 年中的第几周,星期天是一周的第一天
%w
 星期几的数字表示(0-6, 星期天=0)
%W
 一年中的第几周,星期天是一周的第一天
%x
 标准日期字符串
%X
 标准时间字符串
%y
 年(0-99)
%Y
 用CCYY表示的年(如:2004)
%Z
 时区名
%%
 百分号
函数strftime()返回值为处理结果字符串str中字符的个数,如果发生错误返回零。

12.gettimeofday(取得目前的时间)
#include <sys/time.h>
#include <unistd.h>
int gettimeofday ( struct timeval * tv , struct timezone * tz )
gettimeofday()会把目前的时间有tv所指的结构返回,当地时区的信息则放到tz所指的结构中。
timeval结构定义为:
struct timeval{
long tv_sec; /*秒*/
long tv_usec; /*微秒*/
};
timezone 结构定义为:
struct timezone{
int tz_minuteswest; /*和Greenwich 时间差了多少分钟*/
int tz_dsttime; /*日光节约时间的状态*/
};
上述两个结构都定义在/usr/include/sys/time.h。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年以后)*/
 
返回值
 成功则返回0,失败返回-1,错误代码存于errno。附加说
 明EFAULT指针tv和tz所指的内存空间超出存取权限。
 
#include<stdio.h>
#include<sys/time.h>
#include<unistd.h>
int main()
{
 struct timeval tv;
 struct timezone tz;
 gettimeofday (&tv , &tz);
 printf("tv_sec; %d\n", tv,.tv_sec) ;
 printf("tv_usec; %d\n",tv.tv_usec);
 printf("tz_minuteswest; %d\n", tz.tz_minuteswest);
 printf("tz_dsttime, %d\n",tz.tz_dsttime);
 return 0;
}
 
执行
tv_sec; 1406626912
tv_usec; 555104
tz_minuteswest; -480   //我们是东八区,应该是用UTC时间-东八区时间的分差
tz_dsttime, 0

13.settimeofday(设置目前时间)
#include<sys/time.h>
#include<unistd.h>
int settimeofday ( const struct timeval *tv,const struct timezone *tz);
函数说明
settimeofday()会把目前时间设成由tv所指的结构信息,当地时区信息则设成tz所指的结构。详细的说明请参考gettimeofday()。注意,只有root权限才能使用此函数修改时间。
返回值
 成功则返回0,失败返回-1,错误代码存于errno。
错误代码
EPERM 并非由root权限调用settimeofday(),权限不够。
EINVAL 时区或某个数据是不正确的,无法正确设置时间。

14.struct timespec
typedef long time_t;
#ifndef _TIMESPEC
#define _TIMESPEC
struct timespec {
time_t tv_sec; // seconds
long tv_nsec; // and nanoseconds
};
#endif
struct timespec有两个成员,一个是秒,一个是纳秒, 所以最高精确度是纳秒。
一般由函数int clock_gettime(clockid_t, struct timespec *)获取特定时钟的时
间,常用如下4种时钟:
CLOCK_REALTIME 统当前时间,从1970年1.1日算起
CLOCK_MONOTONIC 系统的启动时间,不能被设置
CLOCK_PROCESS_CPUTIME_ID 本进程运行时间
CLOCK_THREAD_CPUTIME_ID 本线程运行时间
struct tm *localtime(const time_t *clock);  //线程不安全
struct tm* localtime_r( const time_t* timer, struct tm* result );//线程安全
size_t strftime (char* ptr, size_t maxsize, const char* format,const struct tm* timeptr );

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

void nowtime_ns()
{
    printf("---------------------------struct timespec---------------------------------------\n");
    printf("[time(NULL)]     :     %ld\n", time(NULL));
    struct timespec ts;
    clock_gettime(CLOCK_REALTIME, &ts);
    printf("clock_gettime : tv_sec=%ld, tv_nsec=%ld\n", ts.tv_sec, ts.tv_nsec);
   
    struct tm t;
    char date_time[64];
    strftime(date_time, sizeof(date_time), "%Y-%m-%d %H:%M:%S", localtime_r(&ts.tv_sec, &t));
    printf("clock_gettime : date_time=%s, tv_nsec=%ld\n", date_time, ts.tv_nsec);
}
void nowtime_us()
{
    printf("---------------------------struct timeval----------------------------------------\n");
    printf("[time(NULL)]    :    %ld\n", time(NULL));
    struct timeval us;
    gettimeofday(&us,NULL);
    printf("gettimeofday: tv_sec=%ld, tv_usec=%ld\n", us.tv_sec, us.tv_usec);
   
    struct tm t;
    char date_time[64];
    strftime(date_time, sizeof(date_time), "%Y-%m-%d %H:%M:%S", localtime_r(&us.tv_sec, &t));
    printf("gettimeofday: date_time=%s, tv_usec=%ld\n", date_time, us.tv_usec);
}

int main(int argc, char* argv[])
{
    nowtime_ns();
    printf("\n");
    nowtime_us();
    printf("\n");
    return 0;
}

编译要链接librt 
  

0 0