日期与时间函数在time.h中,主要表示处理器时钟的clock_t类型、表示时间的time_t类型、时钟每秒滴答数CLOCKS_PER_SEC、描述日历时间的struct tm结构、函数clock、time、asctime、ctime、gmtime、localtime、mktime、difftime、strftime、wcsftime(宽字符版本),其他的都是非标准扩展。
1、time.h:类型clock_t, time_t的定义,宏CLOCKS_PER_SEC,struct tm结构包括秒数、分钟数、小时数、日期数、月份、年份(从1900年算起)、星期、是当年的第几天、夏时制标志共9个成员。
/* ISO C99 Standard: 7.23 日期和时间 <time.h> */ #ifndef _TIME_H #if (! defined __need_time_t && !defined __need_clock_t && / ! defined __need_timespec) # define _TIME_H 1 # include <features.h> __BEGIN_DECLS #endif #ifdef _TIME_H /* 从<stddef.h>中获得size_t和NULL */ # define __need_size_t # define __need_NULL # include <stddef.h> /* 这里定义常量CLOCKS_PER_SEC,为处理器每秒的时钟滴答数 */ # include <bits/time.h> /* 这里是针对一同常量的过时的POSIX.1-1988中的宏名 */ # if !defined __STRICT_ANSI__ && !defined __USE_XOPEN2K # ifndef CLK_TCK # define CLK_TCK CLOCKS_PER_SEC # endif # endif #endif /* <time.h> included */ #if !defined __clock_t_defined && (defined _TIME_H || defined __need_clock_t) # define __clock_t_defined 1 # include <bits/types.h> __BEGIN_NAMESPACE_STD typedef __clock_t clock_t; /* 定义处理器时钟类型,clock函数返回该类型 */ __END_NAMESPACE_STD #if defined __USE_XOPEN || defined __USE_POSIX || defined __USE_MISC __USING_NAMESPACE_STD(clock_t) #endif #endif /* clock_t没有定义,且<time.h>有可能需要clock_t */ #undef __need_clock_t #if !defined __time_t_defined && (defined _TIME_H || defined __need_time_t) # define __time_t_defined 1 # include <bits/types.h> __BEGIN_NAMESPACE_STD typedef __time_t time_t; /* 定义时间类型,是一个整数类型,time函数返回该类型 */ __END_NAMESPACE_STD #if defined __USE_POSIX || defined __USE_MISC || defined __USE_SVID __USING_NAMESPACE_STD(time_t) #endif #endif /* time_t没有定义,且<time.h>有可能需要time_t */ #undef __need_time_t #if !defined __clockid_t_defined && / ((defined _TIME_H && defined __USE_POSIX199309) || defined __need_clockid_t) # define __clockid_t_defined 1 # include <bits/types.h> typedef __clockid_t clockid_t; /* 定义表示时钟ID的类型,clock和timer函数中会用到它 */ #endif /* clockid_t没有定义,且<time.h>有可能需要clockid_t */ #undef __clockid_time_t #if !defined __timer_t_defined && / ((defined _TIME_H && defined __USE_POSIX199309) || defined __need_timer_t) # define __timer_t_defined 1 # include <bits/types.h> typedef __timer_t timer_t; /* 定义表示时间ID的类型,time_create函数会用到它 */ #endif /* timer_t没有,且<time.h>有可能需要timer_t */ #undef __need_timer_t #if !defined __timespec_defined && / ((defined _TIME_H && / (defined __USE_POSIX199309 || defined __USE_MISC)) || / defined __need_timespec) # define __timespec_defined 1 # include <bits/types.h> /* 这里为我们定义__time_t */ /* POSIX.1b中表示时间值的结构,这类似于struct timeval,但使用纳秒而不是微秒 */ struct timespec { __time_t tv_sec; /* 秒数 */ long int tv_nsec; /* 纳秒数 */ }; #endif /* timespec没有定义,且<time.h>有可能需要timespec */ #undef __need_timespec #ifdef _TIME_H __BEGIN_NAMESPACE_STD /* 被其他时间函数使用的tm结构 */ struct tm { int tm_sec; /* 秒数 [0-60] (允许最多1个闰秒) */ int tm_min; /* 分钟数 [0-59] */ int tm_hour; /* 小时数 [0-23] */ int tm_mday; /* 日期 [1-31] */ int tm_mon; /* 月份 [0-11] */ int tm_year; /* 从1900年起的年份数 - 1900. */ int tm_wday; /* 星期 [0-6] */ int tm_yday; /* 从1月1日算起的天数 [0-365] */ int tm_isdst; /* 夏时制标志,1夏时制,0非夏时制,-1不确定 [-1/0/1]*/ #ifdef __USE_BSD long int tm_gmtoff; /* UTC以东的秒数 */ __const char *tm_zone; /* 时区缩写 */ #else long int __tm_gmtoff; /* UTC以东的秒数 */ __const char *__tm_zone; /* 时区缩写 */ #endif }; __END_NAMESPACE_STD #if defined __USE_XOPEN || defined __USE_POSIX || defined __USE_MISC __USING_NAMESPACE_STD(tm) #endif #ifdef __USE_POSIX199309 /* POSIX.1b中表示时间初始值和时间间隔的结构 */ struct itimerspec { struct timespec it_interval; struct timespec it_value; }; /* 我们可以使用一个简单的前向声明 */ struct sigevent; #endif /* POSIX.1b */ #ifdef __USE_XOPEN2K # ifndef __pid_t_defined typedef __pid_t pid_t; # define __pid_t_defined # endif #endif __BEGIN_NAMESPACE_STD /* 程序到目前为止的使用时间(用户时间+系统时间) 返回的结果/ClOCKS_PER_SEC即为程序运行的时间(单位为秒) */ extern clock_t clock (void) __THROW; /* 返回当前日历时间,保存到TIMER中,如果TIMER不为NULL的话 */ extern time_t time (time_t *__timer) __THROW; /* 返回两个时间TIME1和TIME0的差值(秒数) */ extern double difftime (time_t __time1, time_t __time0) __THROW __attribute__ ((__const__)); /* 返回TP的time_t表示,并且对TP进行规格化 */ extern time_t mktime (struct tm *__tp) __THROW; /* 根据控制串FORMAT对TP进行格式化,并保存到S中,最多写入MAXSIZE个字符到S中,并返回 写入的字符数,如果字符串长超过MAXSIZE,则返回0 */ extern size_t strftime (char *__restrict __s, size_t __maxsize, __const char *__restrict __format, __const struct tm *__restrict __tp) __THROW; __END_NAMESPACE_STD # ifdef __USE_XOPEN /* 根据FORMAT解析S,把二进制的时间信息保存到TP中。返回值为指向S中第一个未 解析的字符的指针 */ extern char *strptime (__const char *__restrict __s, __const char *__restrict __fmt, struct tm *__tp) __THROW; # endif # ifdef __USE_GNU /* 与上面两个函数类似,但从提供的区域设置中获取信息,而不是用全局的区域设置 */ # include <xlocale.h> extern size_t strftime_l (char *__restrict __s, size_t __maxsize, __const char *__restrict __format, __const struct tm *__restrict __tp, __locale_t __loc) __THROW; extern char *strptime_l (__const char *__restrict __s, __const char *__restrict __fmt, struct tm *__tp, __locale_t __loc) __THROW; # endif __BEGIN_NAMESPACE_STD /* 返回TIMER的struct tm表示(为格林尼治标准时间UTC) */ extern struct tm *gmtime (__const time_t *__timer) __THROW; /* 返回TIMER的struct tm表示(为本地时间) */ extern struct tm *localtime (__const time_t *__timer) __THROW; __END_NAMESPACE_STD # if defined __USE_POSIX || defined __USE_MISC /* 返回TIMER的struct tm表示(为格林尼治标准时间UTC), 使用TP来存放结果 */ extern struct tm *gmtime_r (__const time_t *__restrict __timer, struct tm *__restrict __tp) __THROW; /* 返回TIMER的struct tm表示(为本地时间),使用 TP来存放结果 */ extern struct tm *localtime_r (__const time_t *__restrict __timer, struct tm *__restrict __tp) __THROW; # endif /* POSIX or misc */ __BEGIN_NAMESPACE_STD /* 返回TP的可打印日期与时间字符串,格式为"Day Mon dd hh:mm:ss yyyy/n" */ extern char *asctime (__const struct tm *__tp) __THROW; /* 等价于asctime(localtime (timer)) */ extern char *ctime (__const time_t *__timer) __THROW; __END_NAMESPACE_STD # if defined __USE_POSIX || defined __USE_MISC /* 上述函数的可重入版本 */ /* 返回TP的可打印日期与时间字符串,格式为"Day Mon dd hh:mm:ss yyyy/n", 存放在BUF中 */ extern char *asctime_r (__const struct tm *__restrict __tp, char *__restrict __buf) __THROW; /* 等价于asctime_r(localtime_r(timer, *TMP*), buf) */ extern char *ctime_r (__const time_t *__restrict __timer, char *__restrict __buf) __THROW; # endif /* POSIX or misc */ /* 在localtime.c中已经定义了 */ extern char *__tzname[2]; /* 当前时区名称 */ extern int __daylight; /* 如果夏时制在使用的话 */ extern long int __timezone; /* UTC以西的秒数 */ /* 下面是其他的一些扩展函数 */ __END_DECLS #endif /* <time.h> included. */ #endif /* <time.h> not already included. */
2、clock函数:返回处理器时间的近似值,用clock_t类型表示,通常以微秒为单位。标准C的clock函数只是处理了一下调用出错时的情况(返回-1并转换成clock_t类型)。真正的实现使用的是Linux的clock函数,标准C的clock函数被直接映射到了Linux的clock函数。
/* clock.c:clock函数的实现 */ #include <sys/times.h> #include <time.h> #include <errno.h> /* 返回程序到目前为止的使用时间(用户时间+系统时间) */ clock_t clock () { __set_errno (ENOSYS); return (clock_t) -1; } stub_warning (clock) #include <stub-tag.h>
3、time函数:返回当前日历时间,用time_t类型表示。time函数与上面的clock函数类似,直接使用Linux的time函数实现(独自地处理了调用出错时的情况,即返回-1并转换成time_t类型)。
/* time.c:time函数的实现 */ #include <errno.h> #include <time.h> /* 返回当前日历时间,保存到TIMER中,如果TIMER不为NULL的话 */ time_t time (timer) time_t *timer; { __set_errno (ENOSYS); if (timer != NULL) *timer = (time_t) -1; return (time_t) -1; } libc_hidden_def (time) stub_warning (time) #include <stub-tag.h>