时间函数

引言

从整理到最后,我越来越觉得通过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 value */

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;     /* seconds */
suseconds_t tv_usec;    /* microseconds */
};

这里多了参数tz,其结构体声明如下:
struct timezone {
int tz_minuteswest;     /* minutes west of Greenwich */
int tz_dsttime;         /* type of DST correction */
};

看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;        /* seconds */
               long     tv_nsec;       /* nanoseconds */
           };

参数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;             /* Seconds since boot */
               unsigned long loads[3];  /* 1, 5, and 15 minute load averages */
               unsigned long totalram;  /* Total usable main memory size */
               unsigned long freeram;   /* Available memory size */
               unsigned long sharedram; /* Amount of shared memory */
               unsigned long bufferram; /* Memory used by buffers */
               unsigned long totalswap; /* Total swap space size */
               unsigned long freeswap;  /* swap space still available */
               unsigned short procs;    /* Number of current processes */
               unsigned long totalhigh; /* Total high memory size */
               unsigned long freehigh;  /* Available high memory size */
               unsigned int mem_unit;   /* Memory unit size in bytes */
               char _f[20-2*sizeof(long)-sizeof(int)]; /* Padding for libc5 */
           };






设置时间函数


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;         /* seconds  0~59,能到达60做闰秒 */
               int tm_min;         /* minutes     0~59 */
               int tm_hour;        /* hours   0~23 */
               int tm_mday;        /* day of the month   1~31 */
               int tm_mon;         /* month  0~11 */
               int tm_year;        /* year  自1900年*/
               int tm_wday;        /* day of the week  自星期日起  0~6*/
               int tm_yday;        /* day in the year    自一月一日起  0~365*/
               int tm_isdst;       /* daylight saving time  夏令时标志,正表示启用,0表示不请用,负表示不可用的*/
           };

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后缀的则是可重入函数,使用自己申请的内存来保存结果。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值