近来项目中有用到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; /* 日光节约时间的旗标 */
};
#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;
}
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
#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;
}
#include
函数定义:int ftime(struct timeb *tp);
函数说明:ftime()将目前日期由tp所指的结构返回。
返回值 :无论成功或失败都返回0
范例:
#include
int main(void)
{
struct timeb tp;
ftime(&tp);
printf("%d\n", tp.time);
return 0;
}
★★★特别注意:ctime函数不是线程安全的。多线程应用里面,应该用ctime_r函数替代ctime函数,因为ctime_r是线程安全的。
范例:
#include
int main(void)
{
time_t timep;
time(&timep);
printf(“%s\n”,ctime(&timep));
return 0;
}
#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;
}
★★★特别注意:asctime函数不是线程安全的。多线程应用里面,应该用asctime_r函数替代asctime函数,因为asctime_r是线程安全的。
范例:
#include
int main(void)
{
time_t timep;
time(&timep);
printf(“%s\n”,asctime(gmtime(&timep)));
return 0;
}
表头文件:
#include
定义函数: 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
#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;
}
表头文件:
#include
定义函数: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
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_t mktime(strcut tm * timeptr);
函数说明:mktime()用来将参数timeptr所指的tm结构数据转换成从公元1970年1月1日0时0分0 秒算起至今的UTC时间所经过的秒数。
返回值:返回经过的秒数。
范例:
/* 用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;
}
表头文件:
#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;
}
表头文件:
#include
定义函数:int stime(time_t *t);
函数说明:参数t是以秒为单位的时间值,从GMT1970年1月1日0时0分0秒开始计算。
返回值:成功返回0,错误返回-1,errno错误码,EFAULT表示传递的参数错误,如时间值是无效的值,EPERM表示权限不够,注意只有root用户才有修改系统时间的权限。如果要让普通程序修改系统时间,可以先切换到root用户操作,修改完成后,再切换到普通用户,或者用命令chmod+s给执行文件加上root用户的权限。
范例:
#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;
}