一、综述
许久没有更新过博客,近来项目中有用到Linux下的时间相关的函数,其中也不乏一些使用误区。不禁想做个简单总结,以备后用。
linux下常用的时间函数如下:
系统调用 | 库函数
读取时间:ftime,gettimeofday | time
格式转换: | ctime/ctime_r,localtime/localtime_r, asctime/asctime_r,strftime/strptime,gmtime/gmtime_r,mktime
设置时间:settimeofday | stime
二、常用到的结构体
- struct timeval
- {
- time_t tv_sec; /* seconds */
- suseconds_t tv_usec; /* microseconds */
- };
- struct timezone
- {
- int tv_minuteswest; /* 格林威治时间往西方的时差 */
- int tv_dsttime; /* 时间的修正方式 */
- };
- struct timeb
- {
- time_t time; /* 为1970-01-01至今的秒数*/
- unsigned short millitm; /* 千分之一秒即毫秒 */
- short timezonel; /* 为目前时区和Greenwich相差的时间,单位为分钟 */
- short dstflag; /* 为日光节约时间的修正状态,如果为非0代表启用日光节约时间修正 */
- };
- struct timespec
- {
- long int tv_sec; /* seconds */
- long int tv_nsec; /* nano second(10E-9 second) */
- };
- struct tm
- {
- int tm_sec; /* 代表目前秒数,正常范围为0-59,但允许至61秒 */
- 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; /* 从今年1月1日算起至今的天数,范围为0-365 */
- int tm_isdst; /* 日光节约时间的旗标 */
- };
struct timeval
{
time_t tv_sec; /* seconds */
suseconds_t tv_usec; /* microseconds */
};
struct timezone
{
int tv_minuteswest; /* 格林威治时间往西方的时差 */
int tv_dsttime; /* 时间的修正方式 */
};
struct timeb
{
time_t time; /* 为1970-01-01至今的秒数*/
unsigned short millitm; /* 千分之一秒即毫秒 */
short timezonel; /* 为目前时区和Greenwich相差的时间,单位为分钟 */
short dstflag; /* 为日光节约时间的修正状态,如果为非0代表启用日光节约时间修正 */
};
struct timespec
{
long int tv_sec; /* seconds */
long int tv_nsec; /* nano second(10E-9 second) */
};
struct tm
{
int tm_sec; /* 代表目前秒数,正常范围为0-59,但允许至61秒 */
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; /* 从今年1月1日算起至今的天数,范围为0-365 */
int tm_isdst; /* 日光节约时间的旗标 */
};
三、读取时间函数
1、time() 取得目前的时间
表头文件:
#include <time.h>
定义函数:time_t time(time_t *t);
函数说明:此函数会返回从公元1970年1月1日的UTC时间从0时0分0秒算起到现在所经过的秒数。如果t 并非空指针的话,此函数也会将返回值存到t指针所指的内存。
返回值:成功则返回秒数,失败则返回((time_t)-1)值,错误原因存于errno中。
范例:
- #include <time.h>
- int main(void)
- {
- int seconds = time((time_t*)NULL);
- printf(“%d\n”,seconds);
- return 0;
- }
#include <time.h>
int main(void)
{
int seconds = time((time_t*)NULL);
printf(“%d\n”,seconds);
return 0;
}
2、gettimeofday() 取得目前的时间表头文件:
#include <sys/time.h>
#include <unistd.h>
定义函数:int gettimeofday ( struct timeval * tv , struct timezone * tz )
函数说明:gettimeofday()会把目前的时间有tv所指的结构返回,当地时区的信息则放到tz所指的结构中。
★★★特别注意:获取时区tz信息依赖于系统,有的系统无法获取,所以一般调用时该函数第二个参数为NULL。
timeval结构定义为:
- struct timeval
- {
- long tv_sec; /*秒*/
- long tv_usec; /*微秒*/
- };
- timezone 结构定义为:
- struct timezone
- {
- int tz_minuteswest; /*和Greenwich 时间差了多少分钟*/
- int tz_dsttime; /*日光节约时间的状态*/
- };
struct timeval
{
long tv_sec; /*秒*/
long tv_usec; /*微秒*/
};
timezone 结构定义为:
struct timezone
{
int tz_minuteswest; /*和Greenwich 时间差了多少分钟*/
int tz_dsttime; /*日光节约时间的状态*/
};
上述两个结构都定义在/usr/include/sys/time.h。tz_dsttime 所代表的状态如下
DST_NONE /*不使用*/
DST_USA /*美国*/
DST_AUST /*澳洲*/
DST_WET /*西欧*/
DST_MET /*中欧*/
DST_EET /*东欧*/
DST_CAN /*加拿大*/
DST_GB /*大不列颠*/
DST_RUM /*罗马尼亚*/
DST_TUR /*土耳其*/
DST_AUSTALT /*澳洲(1986年以后)*/
返回值:成功则返回0,失败返回-1,错误代码存于errno。附加说明EFAULT指针tv和tz所指的内存空间超出存取权限。
范例:
- #include <sys/time.h>
- #include <unistd.h>
- int main(void)
- {
- struct timeval tv;
- struct timezone tz;
- gettimeofday(&tv , &tz);
- printf(“tv_sec; %d\n”, tv,.tv_sec) ;
- printf(“tv_usec; %d\n”,tv.tv_usec);
- printf(“tz_minuteswest; %d\n”, tz.tz_minuteswest);
- printf(“tz_dsttime, %d\n”,tz.tz_dsttime);
- return 0;
- }
#include <sys/time.h>
#include <unistd.h>
int main(void)
{
struct timeval tv;
struct timezone tz;
gettimeofday(&tv , &tz);
printf(“tv_sec; %d\n”, tv,.tv_sec) ;
printf(“tv_usec; %d\n”,tv.tv_usec);
printf(“tz_minuteswest; %d\n”, tz.tz_minuteswest);
printf(“tz_dsttime, %d\n”,tz.tz_dsttime);
return 0;
}
3、ftime() 函数取得目前的时间和日期相关函数:time, ctime, gettimeofday
表头文件:
#include <sys/timeb.h>
函数定义:int ftime(struct timeb *tp);函数说明:ftime()将目前日期由tp所指的结构返回。
返回值 :无论成功或失败都返回0
范例:
- #include <sys/timeb.h>
- int main(void)
- {
- struct timeb tp;
- ftime(&tp);
- printf("%d\n", tp.time);
- return 0;
- }
#include <sys/timeb.h>
int main(void)
{
struct timeb tp;
ftime(&tp);
printf("%d\n", tp.time);
return 0;
}
四、时间格式转换函数
1、ctime() ctime_r() 将时间和日期以字符串格式表示
表头文件:
#include <time.h>
定义函数:char *ctime(const time_t *timep); char *ctime_r(const time_t *timep, char *buf);
函数说明:ctime()将参数timep所指的time_t结构中的信息转换成真实世界所使用的时间日期表示方法,然后将结果以字符串形态返回。此函数已经由时区转换成当地时间,字符串格式为“Wed Jun 30 21 :49 :08 1993\n”。若再调用相关的时间日期函数,此字符串可能会被破坏。
返回值:返回一字符串表示目前当地的时间日期。
★★★特别注意:ctime函数不是线程安全的。多线程应用里面,应该用ctime_r函数替代ctime函数,因为ctime_r是线程安全的。
范例:
- #include <time.h>
- int main(void)
- {
- time_t timep;
- time(&timep);
- printf(“%s\n”,ctime(&timep));
- return 0;
- }
#include <time.h>
int main(void)
{
time_t timep;
time(&timep);
printf(“%s\n”,ctime(&timep));
return 0;
}
2、localtime_r() localtime()取得当地目前时间和日期表头文件:
#include <time.h>
定义函数:struct tm *localtime(const time_t * timep); struct tm* localtime_r( const time_t* timer, struct tm* result );
函数说明:localtime()将参数timep所指的time_t结构中的信息转换成真实世界所使用的时间日期表示方法,然后将结果由结构tm返回。结构tm的定义请参考gmtime()。此函数返回的时间日期已经转换成当地时区。
返回值:返回结构tm代表目前的当地时间。
★★★特别注意:localtime函数可以将时间转换本地时间,但是localtime函数不是线程安全的。多线程应用里面,应该用localtime_r函数替代localtime函数,因为localtime_r是线程安全的。
范例:
- #include <time.h>
- int main(void)
- {
- char *wday[] = {“Sun”,”Mon”,”Tue”,”Wed”,”Thu”,”Fri”,”Sat”};
- time_t timep;
- struct tm *p;
- time(&timep);
- p = localtime(&timep); /*取得当地时间*/
- printf(“%d%d%d ”, (1900+p->tm_year),( l+p->tm_mon), p->tm_mday);
- printf(“%s%d:%d:%d\n”, wday[p->tm_wday],p->tm_hour, p->tm_min, p->tm_sec);
- return 0;
- }
#include <time.h>
int main(void)
{
char *wday[] = {“Sun”,”Mon”,”Tue”,”Wed”,”Thu”,”Fri”,”Sat”};
time_t timep;
struct tm *p;
time(&timep);
p = localtime(&timep); /*取得当地时间*/
printf(“%d%d%d ”, (1900+p->tm_year),( l+p->tm_mon), p->tm_mday);
printf(“%s%d:%d:%d\n”, wday[p->tm_wday],p->tm_hour, p->tm_min, p->tm_sec);
return 0;
}
3、asctime() asctime_r() 将时间和日期以字符串格式表示表头文件:
#include <time.h>
定义函数:char * asctime(const struct tm * timeptr); char *asctime_r(const struct tm *tm, char *buf);
函数说明:asctime()将参数timeptr所指的tm结构中的信息转换成真实世界所使用的时间日期表示方法,然后将结果以字符串形态返回。此函数已经由时区转换成当地时间,字符串格式为:“Wed Jun 30 21:49:08 1993\n”
返回值:若再调用相关的时间日期函数,此字符串可能会被破坏。此函数与ctime不同处在于传入的参数是不同的结构。
附加说明:返回一字符串表示目前当地的时间日期。
★★★特别注意:asctime函数不是线程安全的。多线程应用里面,应该用asctime_r函数替代asctime函数,因为asctime_r是线程安全的。
- #include <time.h>
- int main(void)
- {
- time_t timep;
- time(&timep);
- printf(“%s\n”,asctime(gmtime(&timep)));
- return 0;
- }
#include <time.h>
int main(void)
{
time_t timep;
time(&timep);
printf(“%s\n”,asctime(gmtime(&timep)));
return 0;
}
4、strftime(),strptime() 这两个函数都是时间日期的格式控制函数,在功能上看起来正好相反。strftime将一个tm结构格式化为一个字符串,strptime则是将一个字符串格式化为一个tm结构。表头文件:
#include <time.h>
定义函数: size_t strftime(char *s,size_t maxsize,char *format,const struct tm *timeptr); char *strptime(const char *buf,const char *format,struct tm *timeptr);
函数说明:strftime函数对timeptr指向的tm结构所代表的时间和日期进行格式编排,其结果放在字符串s中。该字符串的长度被设置为(最少)maxsize个字符。格式字符串format用来对写入字符串的字符进行控制,它包含着将被传送到字符串里去的普通字符以及编排时间和日期格式的转换控制符。strptime函数将一个字符串格式化为一个tm结构,功能与strptime相反。。
附加说明:
转换控制符 说明
%a 星期几的简写形式
%A 星期几的全称
%b 月份的简写形式
%B 月份的全称
%c 日期和时间
%d 月份中的日期,0-31
%H 小时,00-23
%I 12进制小时钟点,01-12
%j 年份中的日期,001-366
%m 年份中的月份,01-12
%M 分,00-59
%p 上午或下午
%S 秒,00-60
%u 星期几,1-7
%w 星期几,0-6
%x 当地格式的日期
%X 当地格式的时间
%y 年份中的最后两位数,00-99
%Y 年
%Z 地理时区名称
返回值:strftime()返回向strDest指向的字符串中放置的字符数;strptime()返回一个指针,指向转换过程处理的最后一个字符后面的那个字符。
范例:
- #include <time.h>
- #include <stdio.h>
- int main()
- {
- time_t lt = time(NULL);
- struct tm* ptr = localtime(<);
- char szBuffer[64] = {0};
- const char* pFormat = "The time now is %Y-%m-%d %H:%M:%S";
- strftime(szBuffer, 64, pFormat, ptr);
- printf("%s\n", szBuffer);
- struct tm tmTemp;
- char tmBuffer[64] = {0};
- strptime(szBuffer, pFormat, &tmTemp);
- strftime(tmBuffer, 64, "The time just was %Y-%m-%d %H:%M:%S", &tmTemp);
- printf("%s\n", tmBuffer);
- return 0;
- }
#include <time.h>
#include <stdio.h>
int main()
{
time_t lt = time(NULL);
struct tm* ptr = localtime(<);
char szBuffer[64] = {0};
const char* pFormat = "The time now is %Y-%m-%d %H:%M:%S";
strftime(szBuffer, 64, pFormat, ptr);
printf("%s\n", szBuffer);
struct tm tmTemp;
char tmBuffer[64] = {0};
strptime(szBuffer, pFormat, &tmTemp);
strftime(tmBuffer, 64, "The time just was %Y-%m-%d %H:%M:%S", &tmTemp);
printf("%s\n", tmBuffer);
return 0;
}
5、gmtime() gmtime_r() 取得目前时间和日期表头文件:
#include <time.h>
定义函数:struct tm*gmtime(const time_t*timep); struct tm *gmtime_r(const time_t *timep, struct tm *result);
函数说明:gmtime()将参数timep 所指的time_t 结构中的信息转换成真实世界所使用的时间日期表示方法,然后将结果由结构tm返回。
★★★特别注意:(1)gmtime函数不是线程安全的。多线程应用里面,应该用gmtime_r函数替代gmtime函数,因为gmtime_r是线程安全的;(2)此函数返回的时间日期未经时区转换,而是UTC时间。
返回值:返回结构tm代表目前UTC 时间
范例:
- #include <time.h>
- int main(void)
- {
- char *wday[] = {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
- time_t timep;
- struct tm *p;
- time(&timep);
- p = gmtime(&timep);
- printf(“%d%d%d”,(1900+p->tm_year), (1+p->tm_mon),p->tm_mday);
- printf(“%s%d;%d;%d\n”, wday[p->tm_wday], p->tm_hour, p->tm_min, p->tm_sec);
- return 0;
- }
#include <time.h>
int main(void)
{
char *wday[] = {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
time_t timep;
struct tm *p;
time(&timep);
p = gmtime(&timep);
printf(“%d%d%d”,(1900+p->tm_year), (1+p->tm_mon),p->tm_mday);
printf(“%s%d;%d;%d\n”, wday[p->tm_wday], p->tm_hour, p->tm_min, p->tm_sec);
return 0;
}
6、mktime() 将时间结构数据转换成经过的秒数表头文件:
#include <time.h>
定义函数:time_t mktime(strcut tm * timeptr);
函数说明:mktime()用来将参数timeptr所指的tm结构数据转换成从公元1970年1月1日0时0分0 秒算起至今的UTC时间所经过的秒数。
返回值:返回经过的秒数。
范例:
- /* 用time()取得时间(秒数),利用localtime()
- 转换成struct tm 再利用mktime()将struct tm转换成原来的秒数*/
- #include <time.h>
- int main(void)
- {
- time_t timep;
- strcut tm *p;
- time(&timep);
- printf(“time() : %d \n”,timep);
- p = localtime(&timep);
- timep = mktime(p);
- printf(“time()->localtime()->mktime():%d\n”,timep);
- return 0;
- }
/* 用time()取得时间(秒数),利用localtime()
转换成struct tm 再利用mktime()将struct tm转换成原来的秒数*/
#include <time.h>
int main(void)
{
time_t timep;
strcut tm *p;
time(&timep);
printf(“time() : %d \n”,timep);
p = localtime(&timep);
timep = mktime(p);
printf(“time()->localtime()->mktime():%d\n”,timep);
return 0;
}
五、设置时间函数
1、settimeofday() 设置目前时间
表头文件:
#include <sys/time.h>
#include <unistd.h>
定义函数:int settimeofday ( const struct timeval *tv,const struct timezone *tz);
函数说明:settimeofday()会把目前时间设成由tv所指的结构信息,当地时区信息则设成tz所指的结构。详细的说明请参考gettimeofday()。注意,只有root权限才能使用此函数修改时间。
返回值:成功则返回0,失败返回-1,错误代码存于errno。
错误代码:
EPERM 并非由root权限调用settimeofday(),权限不够。
EINVAL 时区或某个数据是不正确的,无法正确设置时间。
范例:
- #include <sys/time.h>
- #include <unistd.h>
- int main(void)
- {
- struct tm * stime;
- struct timeval tv;
- time_t timep,timeq;
- int rec;
- time(&timep);
- stime = localtime(&timep);
- timeq = mktime(stime);
- tv.tv_sec = (long)timeq;
- printf("the second: %ld\n",tv.tv_sec);
- tv.tv_usec = 0;
- rec = settimeofday(&tv,NULL);
- if(rec <0 )
- {
- printf("settimeofday failed!\n");
- }
- else
- {
- printf("Set system time ok!\n");
- }
- return 0;
- }
#include <sys/time.h>
#include <unistd.h>
int main(void)
{
struct tm * stime;
struct timeval tv;
time_t timep,timeq;
int rec;
time(&timep);
stime = localtime(&timep);
timeq = mktime(stime);
tv.tv_sec = (long)timeq;
printf("the second: %ld\n",tv.tv_sec);
tv.tv_usec = 0;
rec = settimeofday(&tv,NULL);
if(rec <0 )
{
printf("settimeofday failed!\n");
}
else
{
printf("Set system time ok!\n");
}
return 0;
}
2、stime() 设置目前时间,只能精确到秒
表头文件:
#include <time.h>
定义函数:int stime(time_t *t);
函数说明:参数t是以秒为单位的时间值,从GMT1970年1月1日0时0分0秒开始计算。
返回值:成功返回0,错误返回-1,errno错误码,EFAULT表示传递的参数错误,如时间值是无效的值,EPERM表示权限不够,注意只有root用户才有修改系统时间的权限。如果要让普通程序修改系统时间,可以先切换到root用户操作,修改完成后,再切换到普通用户,或者用命令chmod+s给执行文件加上root用户的权限。
范例:
- #include <stdio.h>
- #include <time.h>
- int main(void)
- {
- time_t t;
- t = time(NULL);
- t = t + 120;
- /* 将当前时间调快两分钟*/
- if (0 == stime(&t))
- {
- printf("set system time success!\n");
- }
- else
- {
- printf("stime failed!\n");
- }
- return 0;
- }
#include <stdio.h>
#include <time.h>
int main(void)
{
time_t t;
t = time(NULL);
t = t + 120;
/* 将当前时间调快两分钟*/
if (0 == stime(&t))
{
printf("set system time success!\n");
}
else
{
printf("stime failed!\n");
}
return 0;
}
六、结语
转载:http://blog.csdn.net/tsx86/article/details/49965171
- int getSystemTime()
- {
- time_t timer;
- struct tm* t_tm;
- time(&timer);
- t_tm = localtime(&timer);
- printf("today is %4d%02d%02d%02d%02d%02d/n", t_tm.tm_year+1900,
- t_tm.tm_mon+1, t_tm.tm_mday, t_tm.tm_hour, t_tm.tm_min, t_tm.tm_sec);
- return 0;
- }
- /************************************************
- 设置操作系统时间
- 参数:*dt数据格式为"2006-4-20 20:30:30"
- 调用方法:
- char *pt="2006-4-20 20:30:30";
- SetSystemTime(pt);
- **************************************************/
- int SetSystemTime(char *dt)
- {
- struct rtc_time tm;
- struct tm _tm;
- struct timeval tv;
- time_t timep;
- sscanf(dt, "%d-%d-%d %d:%d:%d", &tm.tm_year,
- &tm.tm_mon, &tm.tm_mday,&tm.tm_hour,
- &tm.tm_min, &tm.tm_sec);
- _tm.tm_sec = tm.tm_sec;
- _tm.tm_min = tm.tm_min;
- _tm.tm_hour = tm.tm_hour;
- _tm.tm_mday = tm.tm_mday;
- _tm.tm_mon = tm.tm_mon - 1;
- _tm.tm_year = tm.tm_year - 1900;
- timep = mktime(&_tm);
- tv.tv_sec = timep;
- tv.tv_usec = 0;
- if(settimeofday (&tv, (struct timezone *) 0) < 0)
- {
- printf("Set system datatime error!/n");
- return -1;
- return 0;