C程序中对时间的处理——time库函数详解<转>
包含文件:<sys/time.h> <time.h> 一、在C语言中有time_t, tm, timeval等几种类型的时间
time_t实际上是长整数类型,定义为:typedef long time_t; /* time value */ |
2、timeval
timeval是一个结构体,在time.h中定义为:
struct timeval
{
__time_ttv_sec; /* Seconds. */
__suseconds_t tv_usec; /* Microseconds. */
};
其中,tv_sec为Epoch(1970-1-1零点零分)到创建struct timeval时的秒数,tv_usec为微秒数,即秒后面的零头。
3、tm
tm是一个结构体,定义为:
struct tm int tm_min; /*代表目前分数,范围0-59*/ int tm_hour; /* 从午夜算起的时数,范围为0-23 */ int tm_mday; /* 目前月份的日数,范围01-31 */ int tm_mon; /*代表目前月份,从一月算起,范围从0-11 */ int tm_year; /*从1900 年算起至今的年数*/ int tm_wday; /* 一星期的日数,从星期一算起,范围为0-6。*/ int tm_yday; /* Days in year.[0-365] */ }; |
|
|
|
二、具体操作函数
说 明:此函数返回的时间日期未经时区转换,而是UTC时间。 返回值:返回结构tm代表目前UTC 时间 程序例 |
|
#include "stdio.h" |
localtime()函数
功能:把从1970-1-1零点零分到当前时间系统所偏移的秒数时间转换为日历时间。
说明:此函数获得的tm结构体的时间,是已经进行过时区转化为本地时间。
用法: struct tm *localtime(const time_t *clock);
返回值:返回指向tm结构体的指针.tm结构体是time.h中定义的用于分别存储时间的各个量(年月日等)
的结构体.
程序例1:
#include <stdio.h>
#include <stddef.h>
#include <time.h>
int main(void)
{
time_t timer;//time_t就是long int类型
struct tm *tblock;
timer = time(NULL);
tblock = localtime(&timer);
printf("Local time is: %s\n",asctime(tblock));
return 0;
}
执行结果:
Local time is: Mon Feb 16 11:29:26 2009
程序例2:
上面的例子用了asctime函数,下面这个例子不使用这个函数一样能获取系统当前时间。
需要注意的是年份加上1900,月份加上1。
#include<time.h>
#include<stdio.h>
int main()
{
struct tm *t;
time_t tt;
time(&tt);
t=localtime(&tt);
printf("%4d年%02d月%02d日 %02d:%02d:%02d\n",
t->tm_year+1900,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec);
return 0;
}
localtime()和gmtime()的区别:
gmtime()函数功能类似获取当前系统时间,只是获取的时间未经过时区转换。
localtime函数获得的tm结构体的时间,是已经进行过时区转化为本地时间。
localtime_r()和gmtime_r()函数
struct tm *gmtime_r(consttime_t *timep, struct tm *result);
struct tm *localtime_r(const time_t *timep, struct tm *result);
gmtime_r()函数功能与此相同,但是它可以将数据存储到用户提供的结构体中。
localtime_r()函数功能与此相同,但是它可以将数据存储到用户提供的结构体中。它不需要设置tzname。
使用gmtime和localtime后要立即处理结果,否则返回的指针指向的内容可能会被覆盖。
一个好的方法是使用gmtime_r和localtime_r,由于使用了用户分配的内存,这两个函数是不会出错的。
asctime()函数
功能:转换日期和时间为相应的字符串(英文简写形式,形如:Mon Feb 16 11:29:26 2009)
用法: char *asctime(const struct tm *tblock);
ctime()函数
功能:把日期和时间转换为字符串。(英文简写形式,形如:Mon Feb 16 11:29:26 2009)
用法: char *ctime(const time_t *time);
说明:ctime同asctime的区别在于,ctime是通过日历时间来生成时间字符串,
而asctime是通过tm结构来生成时间字符串。
mktime()函数
功能:将tm时间结构数据转换成经过的秒数(日历时间)。
原型:time_t mktime(strcut tm * timeptr);。
说明:mktime()用来将参数timeptr所指的tm结构数据转换成
从公元1970年1月1日0时0分0秒算起至今的UTC时间所经过的秒数。
返回值:返回经过的秒数。
difftime()函数
功能:计算时间间隔才长度,以秒为单位,且只能精确到秒。
原型:double difftime(time_t time1, time_t time0);
说明:虽然该函数返回值是double类型的,但这并不说明该时间间隔具有同double一样的精度,
这是由它的参数决定的。
strftime()函数
功能:将时间格式化,或者说:格式化一个时间字符串。我们可以使用strftime()函数将时间格式化为我们想要的格式。
原型:size_tstrftime(char *strDest,size_t maxsize,const char *format,const struct tm*timeptr);
参数:我们可以根据format指向字符串中格式命令把timeptr中保存的时间信息放在strDest指向的字符串中,
最多向strDest中存放maxsize个字符。
返回值:该函数返回向strDest指向的字符串中放置的字符数。
类似于sprintf():识别以百分号(%)开始的格式命令集合,格式化输出结果放在一个字符串中。
格式化命令说明串strDest中各种日期和时间信息的确切表示方法。格式串中的其他字符原样放进串中。
格式命令列在下面,它们是区分大小写的。
%a 星期几的简写
%A 星期几的全称
%b 月份的简写
%B 月份的全称
%c 标准的日期的时间串
%C 年份的后两位数字
%d 十进制表示的每月的第几天
%D 月/天/年
%e 在两字符域中,十进制表示的每月的第几天
%F 年-月-日
%g 年份的后两位数字,使用基于周的年
%G 年份,使用基于周的年
%h 简写的月份名
%H 24小时制的小时
%I 12小时制的小时
%j 十进制表示的每年的第几天
%m 十进制表示的月份
%M 十时制表示的分钟数
%n 新行符
%p 本地的AM或PM的等价显示
%r 12小时的时间
%R 显示小时和分钟:hh:mm
%S 十进制的秒数
%t 水平制表符
%T 显示时分秒:hh:mm:ss
%u 每周的第几天,星期一为第一天(值从0到6,星期一为0)
%U 第年的第几周,把星期日作为第一天(值从0到53)
%V 每年的第几周,使用基于周的年
%w 十进制表示的星期几(值从0到6,星期天为0)
%W 每年的第几周,把星期一做为第一天(值从0到53)
%x 标准的日期串
%X 标准的时间串
%y 不带世纪的十进制年份(值从0到99)
%Y 带世纪部分的十制年份
%z,%Z时区名称,如果不能得到时区名称则返回空字符。
%% 百分号
提示:与 gmstrftime()的行为相同,不同的是返回时间是本地时间。
参考
http://wenku.baidu.com/view/bce42784bceb19e8b8f6ba31.html?from=rec&pos=0&weight=14&lastweight=6&count=5
gettimeofday
localtime(const time_t *t) 和 localtime_r(const time_t *t, struct tm *ts)
[c-sharp] view plaincopy
1. #include <cstdlib>
2. #include <iostream>
3. #include <time.h>
4. #include <stdio.h>
5.
6. using namespace std;
7.
8. int main(int argc, char *argv[])
9. {
10. time_t tNow =time(NULL);
11. time_t tEnd = tNow + 1800;
12. //注意下面两行的区别
13. struct tm* ptm = localtime(&tNow);
14. struct tm* ptmEnd = localtime(&tEnd);
15.
16. char szTmp[50] = {0};
17. strftime(szTmp,50,"%H:%M:%S",ptm);
18. char szEnd[50] = {0};
19. strftime(szEnd,50,"%H:%M:%S",ptmEnd);
20.
21.
22. printf("%s /n",szTmp);
23. printf("%s /n",szEnd);
24.
25.
26. system("PAUSE");
27. return EXIT_SUCCESS;
28. }
最后出来的结果是:
21:18:39
21:18:39
和最初想法不一致。
查阅localtime的文档,发现这段话:
This structure is statically allocated andshared by the functions gmtime and localtime. Each time either one of these functions is called the content of thisstructure is overwritten.
也就是说每次只能同时使用localtime()函数一次,要不就会被重写!
The localtime()function need not be reentrant. A function that is not required to be reentrantis not required to be thread-safe.
因此localtime()不是可重入的。同时libc里提供了一个可重入版的函数localtime_r();
Unlike localtime(),the reentrant version is not required to set tzname。
修改程序:
[c-sharp] view plaincopy
1. #include <cstdlib>
2. #include <iostream>
3. #include <time.h>
4. #include <stdio.h>
5.
6. using namespace std;
7.
8. int main(int argc, char *argv[])
9. {
10. time_t tNow =time(NULL);
11. time_t tEnd = tNow + 1800;
12.
13. //在这里修改程序
14. //struct tm* ptm = localtime(&tNow);
15. //struct tm* ptmEnd = localtime(&tEnd);
16. struct tm ptm = { 0 };
17. struct tm ptmEnd = { 0 };
18. localtime_r(&tNow, &ptm);
19. localtime_r(&tEnd, &ptmEnd);
20.
21. char szTmp[50] = {0};
22. strftime(szTmp,50,"%H:%M:%S",&ptm);
23. char szEnd[50] = {0};
24. strftime(szEnd,50,"%H:%M:%S",&ptmEnd);
25. printf("%s /n",szTmp);
26. printf("%s /n",szEnd);
27.
28.
29. system("PAUSE");
30. return EXIT_SUCCESS;
31. }
最后出来的结果是:
10:29:06
10:59:06