天天看点

时间函数引言术语介绍辅助时间命令获取时间函数设置时间函数转换时间函数

引言

从整理到最后,我越来越觉得通过man手册去了解一个函数更好,虽然英文水平差了点,读起来吃力甚至看不懂啥意思,但坚持看,又提升英语,弄明白之后也方便之后查询别的函数,所以在此还是要说明下,通过man手册来查询函数,还是很有必要的!当然我整理了还是发表下~  这过程中也学了不少东西。中间有错误不完善的地方,望指正,谢谢!

术语介绍

  • Epoch指的是一个特定的时间:1970-01-01 00:00:00 UTC。
  • UTC:协调世界时(Universal Time Coordinated),各时区以其进行时间校准
  • GMT:格林威治标志时间,原作为标准时间使用,因存在时间偏差,现用UTC
  • 时区:如北京在东八区,其时区名与UTC的偏移量 (CCT+8:00),表示北京时间比UTC时间慢8小时,如果得知北京时间算UTC时间,则是-8小时
  • DST daylight saving time  夏时制 ,又称夏令时。因夏天天亮的早,人为的将时间修改提前,就可以使人早睡早起,节约照明时间,从而节约能源。

辅助时间命令

  • date 可查看设置系统时间
  • hwclock 可查看设置RTC时间,需要超级权限

获取时间函数

time

#include <time.h>

typedef long time_t;

time_t time(time_t *t);

函数返回的是当前UTC时间自Epoch经过的秒数,而不是你本地时间自Epoch经过的秒数,如果参数t不为空,则也将返回值保存至该参数指向的内存中。

gettimeofday

gettimeofday与time功能一样,获取自Epoch经过的时间,只是相对更精确,单位可至微秒,其函数声明如下:

#include <sys/time.h>

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

结构体

struct timeval 

{

time_t      tv_sec;    

suseconds_t tv_usec;    

};

这里多了参数tz,其结构体声明如下:

struct timezone {

int tz_minuteswest;    

int tz_dsttime;        

};

看man手册说“The use of the timezone structure is obsolete, the tz argument should normally be specified as NULL”,所以在使用gettimeofday的时候,第二个参数应该设置为NULL。

在看CONFORMING TO说明中,推荐使用clock_gettime替代gettimeofday。

clock_gettime

clock_gettime比gettimeofday获取的时间更为精确,可精确到纳秒。但除像gettimeofday获取自Epoch经过的时间,还可以获取自系统启动经过的时间等,具体看clk_id参数设置。函数原型如下:

#include <time.h>

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

链接的时候加上选项 -lrt

结构体

struct timespec {

               time_t   tv_sec;        

               long     tv_nsec;      

           };

参数clk_id类型有:

CLOCK_REALTIME:获取自Epoch经过的时间

CLOCK_MONOTONIC:获取自系统启动经过的时间

CLOCK_PROCESS_CPUTIME_ID:进程运行的CPU时间

CLOCK_THREAD_CPUTIME_ID:线程运行的CPU时间

sysinfo 

除了clock_gettime可得知系统启动运行时间,sysinfo函数也可以获取自系统启动的时间

#include <sys/sysinfo.h>

int sysinfo(struct sysinfo *info);

结构体

Since Linux 2.3.23 (i386), 2.3.48 (all architectures) the structure is:

           struct sysinfo {

               long uptime;            

               unsigned long loads[3];  

               unsigned long totalram;  

               unsigned long freeram;  

               unsigned long sharedram;

               unsigned long bufferram;

               unsigned long totalswap;

               unsigned long freeswap;  

               unsigned short procs;    

               unsigned long totalhigh;

               unsigned long freehigh;  

               unsigned int mem_unit;  

               char _f[20-2*sizeof(long)-sizeof(int)];

           };

设置时间函数

settimeofday

与gettimeofday相对的是 settimeofday,函数声明如下:

int settimeofday(const struct timeval *tv, const struct timezone *tz);

settimeofday改的是系统时间,并没有改RTC时间,重启后内核读取RTC时间来初始化系统时间。

参数tv基于UTC时间偏差的秒数,相应增减当前的系统时间,tz参数则仍旧使用NULL。

该函数的执行需要用户具有超级权限。

stime

#include <time.h>

int stime(time_t *t);

stime的功能可以说和settimeofday是一样的,同样也需要超级权限才能执行。

clock_settime

与clock_gettime相对的是clock_settime

int clock_settime(clockid_t clk_id, const struct timespec *tp);

但其不能对系统运行时间进行设置。

转换时间函数

最开始介绍的获取时间函数并不易于查看,通过以下函数,可以转换成易于阅读的时间格式。

#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);

结构体:

struct tm {

               int tm_sec;        

               int tm_min;        

               int tm_hour;        

               int tm_mday;        

               int tm_mon;        

               int tm_year;        

               int tm_wday;        

               int tm_yday;        

               int tm_isdst;      

           };

gmtime函数和localtime函数可以将time_t类型数据转化成struct tm结构体类型数据,所不同的是gmtime转化的是基于UTC的tm结构体,而localtime则会转化成基于当地时区的tm结构体。

asctime和ctime都是返回字符串格式的时间,其格式是“星期  月份  日期  时:分:秒  年份\n”,不同的是ctime传入的是time_t *类型数据,而asctime传入的是struct tm *类型数据。

ctime(t) 相当于 asctime(localtime(t)),t是同一个参数;就是ctime直接调用time返回的UTC时间,转换成当地的可读时间,而asctime需将time返回的时间先转化成当地的tm结构体再转换成当地可读的时间。

mktime则可以将tm结构体转换成time_t类型数据,需要注意的是它把入参作为UTC时间,忽略tm结构体中的成员变量tm_wday和tm_yday,并转换成当地时区的time_t。

最后同一功能的函数名加_r后缀的则是可重入函数,使用自己申请的内存来保存结果。

继续阅读