几种时间的认识
DST(daylight-saving-time)——夏令时
UTC(Coordinated Universal Time)——协调世界时,可看作等价于GMT,相差不到1秒
UT(Universal Time)——世界时,国际标准时(=GMT,Greenwich Mean Time格林尼治标准时)
头文件、宏及类型
在该头文件中,定义了两个宏,声明了几种类型和一些函数来操纵时间。一些函数处理表示当前日期的日历时间(阳历,Gregorian Calendar)和时间。而另一些函数处理本地时间(表示特定时区的日历时间)和夏令时(Daylight Saving Time)。其中,本地时区和夏令时是实现相关的。
定义的宏是NULL和CLOCKS_PER_SEC。其中CLOCKS_PER_SEC被宏扩展为类型为clock_t的常量表达式,表示每秒由clock函数返回的值的数目。
类型clock_t和time_t是算术类型,能够足够表示时间,它们的范围和精度是由实现定义的(implementation-defined)。
类型struct tm容纳日历时间的各分量(称为broken-down时间)。struct tm结构必须包含下面的成员,其含义如注释所述:
struct tm {
int tm_sec; // seconds after the minute —
[0, 60](注(1))
int tm_min; // minutes after the hour — [0, 59]
int tm_hour; // hours since midnight — [0, 23]
int tm_mday; // day of the month — [1, 31]
int tm_mon; // months since January — [0, 11]
int tm_year; //
years since 1900
int tm_wday; // days since Sunday — [0, 6]
int tm_yday; // days since January 1 — [0, 365]
int tm_isdst; // Daylight Saving Time flag
// ... others is implementation-defined
(注(2))
};
注:(1)其中tm_sec的取值范围为[0, 60]以允许一个正的闰秒(leap second)。(2)如果夏令时(Daylight Saving Time)是有效的,那么tm_isdst值为正;否则,如果夏令时不是有效状态,则tm_isdst值为0;否则,如果信息不可用,则tm_isdst值为负。
时间操作函数
clock函数
函数原型
clock_t clock(void);
函数说明
计算并返回已用的处理机时间。注:如果已用的处理机时间不可用或者它的值不能够表示,则函数返回值(clock_t)(-1)。
常见使用方法
用来计算两个点之间的时间差(两次调用,然后将结果相减)。
difftime函数
函数原型
double difftime(time_t time1, time_t time0);
函数说明
计算并返回两个日历时间之差:time1 - time0。返回值为以秒表示的double类型的差值。
mktime函数
函数原型
time_t mktime(struct tm *timeptr);
函数说明
mktime函数把由timeptr所指向的的broken-down时间(表示本地时间)转换为日历时间并返回。如果日历时间不能够表示,则返回值(time_t)(-1)。
结构中的tm_wday和tm_yday成员的原始值被忽略,
其它成员的原始值不限于前面struct tm结构所描述的范围(注意:如果tm_isdst为正值或者0,则mktime函数假定对于指定的时间夏令时分别是有效的或者无效的。一个负值会使mktime去尝试确定夏令时对指定时间是否有效。)。在成功转换后,tm_wday和tm_yday成员的值被恰当地设置,其它成员被设置以表示指定的日历时间,但是它们的值被强制到成员值的允许取值范围。如果调用成功,第二次再用该参数去调用mktime函数,参数指向的结构的值不再改变,且函数返回值与第一次相同。
举例
/* What day of the week is July 4, 2001? */
#include
#include
int main() {
static const char *const wday[] = {
"Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday", "-unknown-"
};
struct tm time_str;
time_str.tm_year = 2001 - 1900;
time_str.tm_mon = 7 - 1;
time_str.tm_mday = 4;
time_str.tm_hour = 0;
time_str.tm_min = 0;
time_str.tm_sec = 1;
time_str.tm_isdst = -1;
if (mktime(&time_str) == (time_t)(-1))
time_str.tm_wday = 7;
printf("%s\n", wday[time_str.tm_wday]);
}
Output:
Wednesday
time函数
函数原型
time_t time(time_t *timer);
函数说明
返回当前日历时间。值的编码方法是未指定的。如果日历时间不可用,则返回值(time_t)(-1)。如果参数timer不是空指针,则返回值也将存储到timer所指向的对象中。
时间转换函数
除了strftime函数,这些函数每一个返回一个如下两种类型之一的指针:broken-down时间结构或者字符数组类型。任何一个返回指针的函数的执行可能会重写前一次该函数返回的指针所指向的数据(因为它们一般使用静态存储区)。实现将保证没有其它库函数调用这些函数(否则程序执行结果无法预测)。
asctime函数
函数原型
char *asctime(const struct tm *timeptr);
函数说明
asctime函数转换timeptr所指向的broken-down时间为字符串形式并返回,例如:"Sun Sep 16 01:03:52 1973\n\0"。
该函数的一个
实现如下:
char *asctime(const struct tm *timeptr)
{
static const char wday_name[7][3] = {
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
};
static const char mon_name[12][3] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
static char result[26];
// 注意这儿的静态存储
sprintf(result, "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n",
wday_name[timeptr->tm_wday],
mon_name[timeptr->tm_mon],
timeptr->tm_mday, timeptr->tm_hour,
timeptr->tm_min, timeptr->tm_sec,
1900 + timeptr->tm_year);
return result;
}
ctime函数
函数原型
char *ctime(const time_t *timer);
函数说明
ctime函数转换由timer指向的日历时间为字符串形式的本地时间。其等价于asctime(localtime(timer))。
gmtime函数
函数原型
struct tm *gmtime(const time_t *timer);
函数说明
gmtime函数转换由timer指向的日历时间为broken-down时间(表示UTC时间)。gmtime函数返回broken-down时间的指针,或者如果指定的时间不能够被转换为UTC,则返回空指针。
localtime函数
函数原型
struct tm *localtime(const time_t *timer);
函数说明
localtime函数返回由timer指向的日历时间为broken-down时间(本地时间)。localtime函数返回指向broken-down时间的指针,或者如果转换失败,则返回一个空指针。
strftime函数
函数原型
size_t strftime(char *restrict s, size_t maxsize,
const char *restrict format, const struct tm *restrict timeptr);
函数说明
strftime函数把由timeptr所指向的时间转换为由格式控制串format所控制的字符串,并存放到s所指向的数组中。format是一个格式控制串,类似于printf函数的格式控制串,区别在于它们的转换说明符不同:每个转换说明符也由一个%开始,跟着可选拔的E或者O修饰符,然后是一个决定转换说明符行为的字符。其它非转换说明符被直接拷贝到目的数组中。如果拷贝发生在两个重叠的对象之间,则行为是未定义的。不会有超过maxsize的字符被存放到s所指向的数组中。
如果包括结束空字符在内的结果字符串的长度不超过maxsize,则strftime函数返回s所指向的字符数组中字符个数(不包括结束空字符);否则,返回0,并且数组内容不确定。
每一个转换说明符由下面描述的恰当字符串代替。如果任意一个指定值超出其取值范围,则转换后的字符串是未指定的。
由E或者O修饰的转换说明符是一个可选的说明符,也就是说,如果该说明符对当前locale不存在,则该修饰符被忽略。
由于转换说明符数量众多,不在此一一列举,请参阅相关资料。
应用举例
/* 一个来自MSDN的例子,计算距当前时间的N天的时间 */
#include
#include
int main( void )
{
struct tm when;
time_t now, result;
int days;
time( &now );
when = *localtime( &now );
printf( "Current time is %s\n", asctime( &when ) );
printf( "How many days to look ahead: " );
scanf( "%d", &days );
when.tm_mday = when.tm_mday + days;
if( (result = mktime( &when )) != (time_t)-1 )
printf( "In %d days the time will be %s\n",
days, asctime( &when ) );
else
perror( "mktime failed" );
return 0;
}