Unix内核通过计算从1970年1月1日0点0分0秒纪元(UTC)开始经过的秒数来提供的基本时间和日期服务。在用户层,这个值是以time_t(在Unix中以t结尾的数据类型被称作基本系统数据类型,int的定义类型)数据类型标识的,一般被称作日历时间(calendar time),并通过函数time获得当前的值。
time函数原型:
#include
time_t time(time_t *timeptr);
当获取这个值后,就可以通过调用其他函数来将它转换成可读的日期和时间,它们之间的关系如下图(来自Unix高级环境编程):
struct tm结构为:
struct tm {
int tm_sec; // 秒 [0 - 60]
int tm_min; // 分 [0 - 59]
int tm_hour; // 小时 [0 - 23]
int tm_mday; // 一月中的天数 [1 - 31]
int tm_mon; // 月 [0 - 11]
int tm_year; // 从1900 年开始过的年数
int tm_wday; // 星期 [0 - 6]
int tm_yday; // 一年中的天数 [0 - 365]
int tm_isdst; // 夏令时标志 <0不可用, 0非夏令时, >0为夏令时
};
#include
struct tm *gmtime(const time_t *calptr);
struct tm *localtime(const time_t *calptr);
time_t mktime(struct tm *tmptr);
localtime函数将日历时间转换成本地时间而购买time则转换为UTC时间,mktime则将本地时间转换为日历时间。
函数ctime和actime分别以time_t和struct tm的指针数据类型为参数,返回可读性很好的时间表示字符串,函数原型为
#include
char *asctime(const struct tm *tmptr);
char *ctime(const time_t *calptr);
strftime函数类似于snprintf函数,但它是专用于存储转换时间和日期的,并定义有特定的format,函数原型:
#include
size_t strftime(char *restrict buf, size_t maxsize, const char *restrict format, const struct tm *restrict tmptr);
前3个参数和snprintf函数相同,第四个参数为struct tm结构体(通常由time函数获得),具体的format可以通过manpage 3获得。
上述的所有函数只能提供秒级的精度,如果想获得更高的精度,则可以使用函数gettimeofday(微秒级精度)和clock_gettime函数(纳秒级精度)。不过它们都是基于单独的Unix规范和POSIX规范的。
gettimeofday函数原型和相关数据结构
#include
int gettimeofday(struct timeval *restrict tp, void *restrict tzp);
struct timeval {
time_t tv_sec; // 秒
long tv_usec; // 微秒
};
参数tzp在目前单独Unix规范中只能是NULL。
clock_gettime函数:
#include
int clock_gettime(clockid_t clk_id, struct timespec *tp);
struct timespec {
time_t tv_sec; // 秒
long tv_nsec; // 纳秒
};
参数clk_id标识特定的时钟(系统时钟,进程特定时钟,线程特定时钟等),系统时钟所有进程可见。根据系统实现(硬件软件)的不同,获得的精度可能也是不同的,可以通过函数clock_getres获得特定系统的精度,而函数clock_settime则可以设定时钟,具体可从manpage 3获取。
将clk_id置为CLOCK_REALTIME则可以获得当前具体时间(从纪元开始)。