一、综述
许久没有更新过博客,近来项目中有用到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; /* 日光节约时间的旗标 */
};
三、读取时间函数
1、time() 取得目前的时间
表头文件:
#include
定义函数:time_t time(time_t *t);
函数说明:此函数会返回从公元1970年1月1日的UTC时间从0时0分0秒算起到现在所经过的秒数。如果t 并非空指针的话,此函数也会将返回值存到t指针所指的内存。
返回值:成功则返回秒数,失败则返回((time_t)-1)值,错误原因存于errno中。
范例:
#include
int main(void)
{
int seconds = time((time_t*)NULL);
printf(“%d\n”,seconds);
return 0;
}
2、gettimeofday() 取得目前的时间★★★特别注意:获取时区tz信息依赖于系统,有的系统无法获取,所以一般调用时该函数第二个参数为NULL。
timeval结构定义为:
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 所代表的状态如下
#include
#include
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() 函数取得目前的时间和日期表头文件:
#include
#include
int main(void)
{
struct timeb tp;
ftime(&tp);
printf("%d\n", tp.time);
return 0;
}
四、时间格式转换函数
1、ctime() ctime_r() 将时间和日期以字符串格式表示
表头文件:
#include
定义函数: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
int main(void)
{
time_t timep;
time(&timep);
printf(“%s\n”,ctime(&timep));
return 0;
}
2、localtime_r() localtime()取得当地目前时间和日期#include
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() 将时间和日期以字符串格式表示附加说明:返回一字符串表示目前当地的时间日期。
★★★特别注意:asctime函数不是线程安全的。多线程应用里面,应该用asctime_r函数替代asctime函数,因为asctime_r是线程安全的。
#include
int main(void)
{
time_t timep;
time(&timep);
printf(“%s\n”,asctime(gmtime(&timep)));
return 0;
}
4、strftime(),strptime() 这两个函数都是时间日期的格式控制函数,在功能上看起来正好相反。strftime将一个tm结构格式化为一个字符串,strptime则是将一个字符串格式化为一个tm结构。#include
#include
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
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() 将时间结构数据转换成经过的秒数/* 用time()取得时间(秒数),利用localtime()
转换成struct tm 再利用mktime()将struct tm转换成原来的秒数*/
#include
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
#include
定义函数:int settimeofday ( const struct timeval *tv,const struct timezone *tz);
函数说明:settimeofday()会把目前时间设成由tv所指的结构信息,当地时区信息则设成tz所指的结构。详细的说明请参考gettimeofday()。注意,只有root权限才能使用此函数修改时间。
返回值:成功则返回0,失败返回-1,错误代码存于errno。
错误代码:
EPERM 并非由root权限调用settimeofday(),权限不够。
EINVAL 时区或某个数据是不正确的,无法正确设置时间。
范例:
#include
#include
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
#include
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;
}
六、结语
暂时就总结这么多,待发现新的常用的再添上。另:因作者水平有限,其中若有错漏之处还望各位指正,不胜感谢!