Unix提供的最基本的时间服务室日历时间(纪元时间),也就是计算1970年1月1日0时0分0秒到当前的秒数。该秒数用time_t表示。
typedef long time_t; /* 时间值time_t 为长整型的别名*/
1、获取/设置时间
1.1 time和time_t
函数time()可以用于获取当前日历时间
#include <time.h> time_t time(time_t *calptr); Returns: value of time if OK,−1 on error
当前时间值(即1970年1月1日0时0分0秒到现在的秒数)保存给calptr指针指向的地址,也作为返回值。
1.2 指定时钟类型
Unix提供指定时钟类型来获取/设置时间的方法。
#include <time.h> int clock_getres(clockid_t clk_id, struct timespec *res); int clock_gettime(clockid_t clk_id, struct timespec *tp); int clock_settime(clockid_t clk_id, const struct timespec *tp); Link with -lrt.编译时使用链接库lrt
clock_gettime()和clock_settime();函数提供了纳秒级别的时间,并且会根据clk_id的时间类型进行取值。
clock_getres 用于获取时间的分辨率。 clock_gettime()和clock_settime()使用的时间必须是时间分辨率的整数倍,不是整数倍也要切割成整数倍。
clockid_tclk_id用于指定计时时钟的类型,有以下选项:
CLOCK_REALTIME:系统实时时间,使用此选项时功能相当于time(),如果系统时间被用户修改过,则对应的时间相应改变 CLOCK_MONOTONIC:从系统启动这一刻起开始计时,不受系统时间被用户改变的影响 CLOCK_PROCESS_CPUTIME_ID:本进程运行的CPU时间 CLOCK_THREAD_CPUTIME_ID:本线程运行的CPU时间
struct timespec { time_t tv_sec; /* seconds */ long tv_nsec; /* nanoseconds */ };
1.3 gettimeofday()与settimeofday()
Unix/Linux提供了微秒级别获取和设置时间的函数gettimeofday()与settimeofday(),但根据man手册的描述,这两个函数已经过时,此处不做介绍。仅列出原型(这两个函数编译需要glibc的支持)
#include <sys/time.h> int gettimeofday(struct timeval *tv, struct timezone *tz); int settimeofday(const struct timeval *tv, const struct timezone *tz);
2、时间格式转换
我们使用time()等函数获取的时间是一个time_t获取的从新纪元开始到当前所经过的秒数,是一个整数值。(calender time)
我们很多情况下需要将其转换成我们可读的,向时分秒这样的时间(broken down time)。这就需要进行转化。
时间转换图如 Figure6.9 所示
我们使用struct tm来保存broken-down time
struct tm { /* a broken-down time */ int tm_sec; // 秒 【0~60】 60存在的原因是闰秒的存在 int tm_min; //分 int tm_hour; //时 int tm_mday; //日 int tm_mon; //月 int tm_year; //年 结构中记录的是从1900至今的年数 int tm_wday; //星期几 【0~6】 int tm_yday; // 一年中第几天 int tm_isdst; // 夏时制标志 };
夏时制,夏时令(Daylight Saving Time:DST),又称“日光节约时制”和“夏令时间”,是一种为节约能源而人为规定地方时间的制度,在这一制度实行期间所采用的统一时间称为“夏令时间”。一般在天亮早的夏季人为将时间提前一小时,可以使人早起早睡,减少照明量,以充分利用光照资源,从而节约照明用电。
Unix提供了时间格式转换的函数:
2.1 time_t与struct tm相互转化
time_t转化成struct tm
#include <time.h> struct tm *gmtime(const time_t *calptr); struct tm *localtime(const time_t *calptr); Both return: pointer to broken-down time,NULLon error
gmtime 转换成国际标准时间
localtime转换成本地时间(考虑到本地时区和夏时制标志)
struct tm转化成time_t
#include <time.h> time_t mktime(struct tm *tmptr); Returns: calendar time if OK,−1 on error
example:
#include<stdio.h> #include <time.h> #include<sys/time.h> int main(void) { time_t calptr; if (time(&calptr) == -1) { printf("Error: time() failed! "); exit(0); } printf("Time(time_t) now is: %d ",(long) calptr); /* * 转换成可读到时间 */ struct tm *gmptr; //国际标准时间 struct tm *localptr; //本地时间 /* 转换成国际标准时间 */ printf(" ----------gm time-------------- "); if (NULL == (gmptr = gmtime(&calptr))) { printf("Error: can't convert time_t to struct tm by gmtime()! "); exit(0); } printf("year:%d, Month:%d, Day:%d, Week:%d ", gmptr->tm_year, gmptr->tm_mon, gmptr->tm_mday, gmptr->tm_wday); printf("Hour:%d, Min:%d, ,sec:%d ", gmptr->tm_hour, gmptr->tm_min, gmptr->tm_sec); /* 转换成本地标准时间 */ printf(" ----------local time-------------- "); if (NULL == (localptr = localtime(&calptr))) { printf("Error: can't convert time_t to struct tm by localtime()! "); exit(0); } printf("year:%d, Month:%d, Day:%d, Week:%d ", localptr->tm_year, localptr->tm_mon, localptr->tm_mday, localptr->tm_wday); printf("Hour:%d, Min:%d, ,sec:%d ", localptr->tm_hour, localptr->tm_min, localptr->tm_sec); return 0; }
运行结果:
windeal@ubuntu:~/Windeal/apue$ ./exe Time(time_t) now is: 1409207607 ----------gm time-------------- year:114, Month:7, Day:28, Week:4 Hour:6, Min:33, ,sec:27 ----------local time-------------- year:114, Month:7, Day:28, Week:4 Hour:14, Min:33, ,sec:27
东八区,快了8个小时
2.2 转换成格式化字符串
#include <time.h> size_t strftime(char *restrict buf,size_t maxsize, const char *restrict format, const struct tm *restrict tmptr); size_t strftime_l(char *restrict buf,size_t maxsize, const char *restrict format, const struct tm *restrict tmptr,locale_t locale); ——Both return: number of characters stored in array if room, 0 otherwise
Example:
#include <stdio.h> #include <stdlib.h> #include <time.h> int main(void) { time_t t; struct tm *tmp; char buf1[16]; char buf2[64]; time(&t); tmp = localtime(&t); if (strftime(buf1, 16, "time and date: %r, %a %b %d, %Y", tmp) == 0) printf("buffer length 16 is too small "); else printf("%s ", buf1); if (strftime(buf2, 64, "time and date: %r, %a %b %d, %Y", tmp) == 0) printf("buffer length 64 is too small "); else printf("%s ", buf2); exit(0); }
运行结果:
windeal@ubuntu:~/Windeal/apue$ ./exe buffer length 16 is too small time and date: 02:43:55 PM, Thu Aug 28, 2014
字符串转换成struct tm格式
#include <time.h> char *strptime(const char *restrictbuf,const char *restrictformat,struct tm *restricttmptr); Returns: pointer to one character past last character parsed,NULLotherwise