在Linux/UNIX系统中,采用的是全球协调时间计时法(Universal Coordinated Time,UTC),此系统是以自1970年1月1日到现在所经过的秒数。这个值的数据类型是time_t,是一个长整型数据。
在Linux/Unix系统中使用函数time为进城提供当前的时间,函数定义如下:
#include<time.h>
time_t time (time_t *t);
函数参数t为一个time_t类型的指针,当它不为空函数返回时将从纪元至今的时间写入t中。函数返回值为从纪元至今的时间(以秒数计算)。函数成功返回时间值,失败则返回-1.
为了满足精度上的要求,在Linux/Unix系统中还可以使用函数gettimeofday来得到对时间精度更高的值,函数定义如下:
#include <sys/time.h>
#include <unistd.h>
int gettimeofday(struct timeval *tv, struct timezone *tz);
函数中参数 tv 是一个timeval结构类型的指针,在函数成功返回后,其存放当前的系统时间值。参数 tz 是一个timezone结构的指针(时区)。tz 参数的作用需要系统支持,在某些系统中可能会产生错误的值,所以在调用时请参阅系统手册。
当然默认下可以指定为NULL,则函数只返回系统当前时间。函数无论成功与否返回值总为0。在函数中的结构struct timeval 及struct timezone定义如下:
struct timeval{
time_t tv_sec;
long tv_usec;
};
struct timezone{
int tz_minuteswest;
int tz_dsttime;
};
在头文件(sys/time.h)中同时定义了5个宏来对struct timeval结构进行算术运算,集体定义及意义如下:
# define timerisset (tvp) ((tvp)->tv_sec ||(tvp)->tv_usec) //判断tvp所指向的结构体是否被填充
# define timerclear(tvp) ((tvp)-tv_sec =(tvp)->tv_usec = 0) //将tvp所指向的结构体置0
# define timercmp(a, b, CMP) //比较两个结构体中的值 注意CMP不可以为 >= 或 <=
# define timeradd(a, b, result) //执行result =(a+b)
# define timersub(a, b, result) //执行result=a-b
函数 difftime 可以计算两个time_t类型的时间值之间的秒数差,函数定义如下:
#include <time.h>
double dfftime (time_t time1, time_t time2);
函数中的参数time1、time2是两个time_t类型的时间值,返回值为一个浮点数,表示两个时间值之间的秒数差。
在Liunx/Unix系统下,定义了系统日历时间结构体(struct 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;
long int tm_gmtoff;
const char *tm_zone;
};
tm结构中前9个必须的成员,最后两个成员根据系统的不同可能会有区别,tm_gmtoff指定了日期变更线东面时区中UTC东部时区的正秒数或UTC西部时区的负秒数。成员tm_zone保存的是当前时区的名字(与环境变量TZ有关)。
在POSIX.1b的标准中提供了比timeval结构更精确的时间结构timespec, 该结构可以精确到十亿分之一秒。该结构体同时也需要更大的存储空间。其定义如下:
struct timespec {
long int tv_sec;
long int tv_nsec;
};
系统中提供了把time_t的时间值转换成日历时间的函数(localtime, gmtime),使用上述两个函数可以把系统时间转换成日历时间。它们的定义如下:
#include <time.h>
struct tm *gmtime(const time_t *calptr);
struct tm *localtime(const time_t *calptr);
以上两个函数的参数都是time_t类型的指针,它们将该指针所指向的数据转换成日历时间,之后函数成功返回的是国际标准时间的年、月、日、时、分、秒、星期。而 localtime 函数返回的是本地时间(受时区的影响,跟环境变量TZ有关)。函数 mktime 可以把日历时间转换成系统时间,其定义如下:
#include <time.h>
time_t mktime ( struct tm *tmptr);
上述函数中参数tmptr指向日历时间结构,函数成功,则返回相应的系统时间(受系统环境变量TZ影响),失败返回-1。
为了提供更容易理解的时间表达形式,同时还提供了函数 asctime 以及 ctime 将time_t 和tm类型的时间值转换成字符串形式的时间,其定义如下:
#include <time.h>
char * asctime( const struct tm *tmptr );
char * ctime(const time_t *calptr );
参数tmpr为指向tm结构的指针,该结构中存储的是日历时间。参数calptr为time_t指针类型,该结构存储的是系统时间。以上两个函数如果转换成功则返回一个26字节的字符串(类似于Tue Jun 17 01:01:01 2000),失败则返回NULL。函数 strftime 提供了对时间更灵活的输出,其定义如下:
#include <time.h>
size_t strftime( char * buf, size_t maxsize, const char * restrict format, const struct tm * restrict tmptr );
函数中参数buf为字符数组指针,用于存放函数的格式化输出结果,参数maxsize定义了该数组的长度。参数format为时间值格式字符串,参数tmptr为要转换的时间结构体。函数成功返回转换后,字符串的长度不包含NULL符,该字符串放在buf数组中,失败则返回0。
参数format中的格式以及相应的意义如下:
%a:星期值的三字符形式缩写
%A:星期值的全名
%b:月名的三字符形式缩写
%B:月的全名
%C:日期和时间首选的本地表现形式,由ctime函数和asctime函数分别返回
%d:每个月中的天数,从0算起
%H:24小时形式的每天中的小时,从0算起
%I:12小时形式的每天中的小时,从0算起
%j:每年中的天数,从1算起
%m:每年中的月数,从1算起
%M:每小时的分钟数,从0算起
%p:AM或者PM的本地等价形式,即本地用来表示AM或者PM的正确字符串
%S:每分钟的秒数,从0算起
%U:每年中的星期数,第一个星期从每年中的第一个星期天算起
%W:每年种的星期数,第一个星期从每年种的第一个星期一算起
%w:每星期中的天数,从0算起
%x:只含有时间的首选本地表示方法,不包括时间
%X:只含有时间的首选本地表示方法,不包括日期
%y:年的两位数表示法,不带有世纪数
%Y:年完整的四位数字表示方法
%Z:时区的标准简写名
%%:%字符
函数 strptime 将转换成系统是被的tm结构时间值。它的定义如下:
#include <time.h>
char * strptime( char *strtime, const char *format, struct tm *tmptr );
函数中参数strtime为所要转换的字符串,可以是strftime函数转换出时间字符串。参数strptime中的格式描述串,参数tmptr为tm结构指针类型,函数执行结构后的结果输出在tmptr所指向的结构体中。如果函数转换成功,则返回最后解析成功的字符串在参数strtime中的位置,如果失败,则返回NULL。
strptime函数格式参数的类型与strftime中相同,但由于其并不区别大小写所以不能识别%U和%W参数。同时strptime还支持一些额外的参数,format格式如下:
%h:等价于%b和%B
%c:读入由strftime函数以%X, %x格式打印的日期和时间
%C:读入由strftime函数以%c格式打印的日期和时间
%e:等价于%d
%D:读入由strftime函数以%m、%d、%y格式打印的日期和时间
%k:等价于%H
%l:等价于%I
%r:读入由strftime函数以%H:%M:%S:%P格式打印的日期和时间
%R:读入由strftime函数以%H:%M格式打印的日期和时间
%T:读入由strftimr函数以%H:%M:%S格式打印的日期和时间
%y:读入20世纪的年份,只允许0-99知之间的值,最终值前加上1900
%Y:读入完整的年份
函数strptime在标准ANSI和POSIX中均没有定义,所以其不具有可移植性,读者在使用中请查阅相应的系统手册。
时间函数:
gettimeofday()
difftime()
gmtime()
localtime()
mktime()
asctime()
ctime()