Linux时间函数札记

关于gmtimegmtime_rlocaltimelocaltime_r


测试环境:vmware 7 + Redhat5.5,系统时间使用UTC,时区为上海。

 1、函数功能介绍

        使用man gmtimeman localtime都可以的得到这几个函数的介绍。原型如下:

        struct tm *gmtime(const time_t *timep);

        struct tm *gmtime_r(const time_t *timep, struct tm *result);

        struct tm *localtime(const time_t *timep);

        struct tm *localtime_r(const time_t *timep, struct tm *result);

man手册中对它们的解释如下:

        The gmtime() function converts the calendar time timep to broken-down time representation, expressed in Coordinated Universal Time (UTC). It may return NULL when the year does not fit into an integer. The return value points to a statically allocated struct which might be overwritten  by subsequent calls to any of the date and time functions. The gmtime_r() function does the same, but stores the data in a user-supplied struct.

        The localtime() function converts the calendar time timep to broken-time representation, expressed relative to the user's specified time zone. The function acts as if it called tzset(3) and sets the external variables tzname with information about the current time zone, timezone with  the difference between Coordinated Universal Time (UTC) and local standard time in seconds, and daylight to a non-zero value if daylight savings time rules apply during some part of the year.  The return value points to a statically allocated struct which might be overwritten by subsequent calls to any of the date and time functions. The localtime_r() function does the same, but stores  the data in a user-supplied struct. It need not set tzname

翻译如下:

        gmtime() 函数将日历时间timep转换为用UTC时间表示的时间。它可能返回NULL,比如年份不能放到一个整数中。返回值指向一个静态分配的结构,该结构可能会被接下来的任何日期和时间函数调用覆盖。gmtime_r()函数功能与此相同,但是它可以将数据存储到用户提供的结构体中。

        localtime() 函数将日历时间timep转换为用户指定的时区的时间。这个函数的行为好像是它调用了tzset(3) 并且将外部变量tzname设置为当前时区的信息,将timezone设为UTC和本地标准时间的差值,并且,如果在一年的部分时间使用日光节约规则时将daylight设置为非空值。返回值指向一个静态分配的结构,该结构可能会被接下来的任何日期和时间函数调用覆盖。localtime_r()函数功能与此相同,但是它可以将数据存储到用户提供的结构体中。它不需要设置tzname

 

2、功能测试

程序一:

#include <stdio.h>

#include <time.h>

int main()

{

time_t cur_time=time(NULL);

if( cur_time < 0 )

{

perror("time");

return -1;

}

 

struct tm utc_tm;;

if( NULL == gmtime_r( &cur_time, &utc_tm ) )

{

perror("gmtime" );

return -1;

}

 

struct tm local_tm;

if( NULL == localtime_r( &cur_time, &local_tm ) )

{

perror("localtime" );

return -1;

}

 

printf("UTC = %s", asctime(&utc_tm) );

printf("LOC = %s", asctime(&local_tm) );

printf("LOC = %s", ctime(&cur_time) );

return 0;

}

程序输出:

UTC = Thu Oct 27 09:16:10 2011

LOC = Thu Oct 27 17:16:10 2011

LOC = Thu Oct 27 17:16:10 2011

由于系统时间使用了UTC,可以看到本地时间= UTC时间 + 8”,输出正确。

 

程序二:

#include <stdio.h>

#include <time.h>

int main()

{

time_t cur_time=time(NULL);

if( cur_time < 0 )

{

perror("time");

return -1;

}

 

struct tm *utc_tm = gmtime( &cur_time );

if( NULL == utc_tm )

{

perror("gmtime" );

return -1;

}

 

printf("UTC = %s", asctime(utc_tm) );

 

struct tm *local_tm = localtime( &cur_time );

if( NULL == local_tm )

{

perror("localtime" );

return -1;

}

 

printf("LOC = %s", asctime(local_tm) );

printf("LOC = %s", ctime(&cur_time) );

return 0;

}

程序输出:

UTC = Thu Oct 27 09:20:45 2011

LOC = Thu Oct 27 17:20:45 2011

LOC = Thu Oct 27 17:20:45 2011

同样是正确的。

 

程序三:

#include <stdio.h>

#include <time.h>

int main()

{

time_t cur_time=time(NULL);

if( cur_time < 0 )

{

perror("time");

return -1;

}

 

struct tm *utc_tm = gmtime( &cur_time );

if( NULL == utc_tm )

{

perror("gmtime" );

return -1;

}

 

struct tm *local_tm = localtime( &cur_time );

if( NULL == local_tm )

{

perror("localtime" );

return -1;

}

 

printf("UTC = %s", asctime(utc_tm) );

printf("LOC = %s", asctime(local_tm) );

printf("LOC = %s", ctime(&cur_time) );

return 0;

}

程序输出:

UTC = Thu Oct 27 17:21:59 2011

LOC = Thu Oct 27 17:21:59 2011

LOC = Thu Oct 27 17:21:59 2011

这程序输出有错,UTC时间和本地时间相同了,这应该就是由于man文档中描述的可能会被接下来的任何日期和时间函数调用覆盖造成的。为验证这个设想,使用程序四:

 

程序四:

#include <stdio.h>

#include <time.h>

int main()

{

time_t cur_time=time(NULL);

if( cur_time < 0 )

{

perror("time");

return -1;

}

 

struct tm *local_tm = localtime( &cur_time );

if( NULL == local_tm )

{

perror("localtime" );

return -1;

}

 

struct tm *utc_tm = gmtime( &cur_time );

if( NULL == utc_tm )

{

perror("gmtime" );

return -1;

}

 

printf("UTC = %s", asctime(utc_tm) );

printf("LOC = %s", asctime(local_tm) );

printf("LOC = %s", ctime(&cur_time) );

return 0;

}

程序输出:

UTC = Thu Oct 27 09:24:23 2011

LOC = Thu Oct 27 09:24:23 2011

LOC = Thu Oct 27 17:24:23 2011

验证了该设想。

 

3、总结

        使用gmtimelocaltime后要立即处理结果,否则返回的指针指向的内容可能会被覆盖,一个好的方法是使用gmtime_rlocaltime_r,由于使用了用户分配的内存,这两个函数是不会出错的。





Linux时间函数

分类: Linux C编程2012-04-28 22:48 22366人阅读 评论(6) 收藏 举报

linuxstructnulltimezonetimer

系统环境:ubuntu10.04


简介

本文旨在为了解Linux各种时间类型与时间函数提供技术文档。


1Linux下常用时间类型

Linux下常用时间类型有四种:time_tstruct tmstruct timevalstruct timespec


1.1 time_t时间类型

time_t类型在time.h中定义:

  1. #ifndef __TIME_T  
  2. #define __TIME_T  
  3. typedef  long  time_t;  
  4. #endif  

可见,time_t实际是一个长整型。其值表示为从UTC(coordinated universal time)时间197011000000(也称为Linux系统的Epoch时间)到当前时刻的秒数。由于time_t类型长度的限制,它所表示的时间不能晚于2038119031407(UTC)。为了能够表示更久远的时间,可用64位或更长的整形数来保存日历时间,这里不作详述。

使用time()函数获取当前时间的time_t值,使用ctime()函数将time_t转为当地时间字符串。

备注UTC时间有时也称为GMT时间,其实UTCGMT两者几乎是同一概念。它们都是指格林尼治标准时间,只不过UTC的称呼更为正式一点。两者区别在于前者是天文上的概念,而后者是基于一个原子钟。


1.2 struct tm时间类型

tm结构在time.h中定义:

  1. #ifndef _TM_DEFINED  
  2. struct tm{  
  3.     int tm_sec; /* - 取值区间为[0, 59]*/  
  4.     int tm_min; /* - 取值区间为[0, 59]*/  
  5.     int tm_hour; /* - 取值区间为[0, 23]*/  
  6.     int tm_mday; /* - 取值区间为[1, 31]*/  
  7.     int tm_mon; /*月份 - 取值区间为[0, 11]*/  
  8.     int tm_year; /*年份 - 其值为1900年至今年数*/  
  9.     int tm_wday; /*星期 - 取值区间[0, 6]0代表星期天,1代表星期1,以此类推*/  
  10.     int tm_yday; /*从每年的11日开始的天数-取值区间为[0, 365]0代表11*/  
  11.     int tm_isdst; /*夏令时标识符,使用夏令时,tm_isdst为正,不使用夏令时,tm_isdst0,不了解情况时,tm_isdst为负*/  
  12. };  
  13. #define _TM_DEFINED  
  14. #endif  

ANSI C标准称使用tm结构的这种时间表示为分解时间(broken-down time)

使用gmtime( )localtime( )可将time_t时间类型转换为tm结构体;

使用mktime( )tm结构体转换为time_t时间类型;

使用asctime( )struct tm转换为字符串形式。

 

1.3 struct timeval时间类型

timeval结构体在time.h中定义:

  1. Struct tmieval{  
  2.     time_t tv_sec; /*s*/  
  3.     suseconds_t tv_usec; /*微秒us*/  
  4. };  

设置时间函数settimeofday( )与获取时间函数gettimeofday( )均使用该事件类型作为传参。

 

1.4 struct timespec时间类型

timespec结构体在time.h定义:


  1. struct timespec{  
  2.     time_t tv_sec; /*s*/  
  3.     long tv_nsec; /*纳秒ns*/  
  4. };  

 

2Linux下常用时间函数

Linux下常用时间函数有:time( )ctime( )gmtime( )localtime( )mktime( )asctime( )difftime( )gettimeofday( )settimeofday( )


2.1 time( )函数

头文件:#include <time.h>

函数定义:time_t time(time_t *timer)

功能描述:该函数返回从197011000000秒至今所经过的秒数。如果time_t *timer非空指针,函数也会将返回值存到timer指针指向的内存。

返回值:成功则返回秒数,失败则返回((time_t)-1)值,错误原因存于errno中。

例:


  1. time_t seconds;  
  2. seconds = time((time_t *)NULL);  


2.2 ctime( )函数

头文件:#include <time.h>

函数定义:char *ctime(const time_t *timep);

功能描述:ctime( )将参数timep指向的time_t时间信息转换成实际所使用的时间日期表示方法,并以字符串形式返回。字符串格式为:"Wed Jun 20 21:00:00 2012\n"

例:

  1. time_t timep;  
  2. tmep = time(NULL);  
  3. printf("%s\n", ctime(&timep));  


2.3 gmtime( )函数

头文件:#include <time.h>

函数定义:struct tm *gmtime(const time_t *timep)

功能描述:gmtime( )将参数timep指向的time_t时间信息转换成以tm结构体表示的GMT时间信息,并以struct tm*指针返回。

GMTGMT是中央时区,北京在东8,相差8个小时,所以北京时间=GMT时间+8小时。

例:

  1. int main(void)  
  2. {  
  3.     char *wday[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};  
  4.     time_t timep;  
  5.     struct tm *p_tm;  
  6.     timep = time(NULL);  
  7.     p_tm = gmtime(&timep); /*获取GMT时间*/  
  8.     printf("%d-%d-%d ", (p_tm->tm_year+1900), (p_tm->mon+1), p_tm->tm_mday);  
  9.     printf("%s %d:%d:%d\n", wday[p_tm->tm_wday], p_tm->tm_hour, p_tm->tm_min, p_tm->tm_sec);  
  10. }  


2.4 localtime( )函数

头文件:#include <time.h>

函数定义:struct tm *localtime(const time_t *timep);

功能描述:localtime( )将参数timep指向的time_t时间信息转换成以tm结构体表示的本地时区时间(如北京时间= GMT+小时)

例:

  1. int main(void)  
  2. {  
  3.     char *wday[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};  
  4.     time_t timep;  
  5.     struct tm *p_tm;  
  6.     timep = time(NULL);  
  7.     p_tm = localtime(&timep); /*获取本地时区时间*/  
  8.     printf("%d-%d-%d ", (p_tm->tm_year+1900), (p_tm->mon+1), p_tm->tm_mday);  
  9.     printf("%s %d:%d:%d\n", wday[p_tm->tm_wday], p_tm->tm_hour, p_tm->tm_min, p_tm->tm_sec);  
  10.     return 0;  
  11. }  


2.5 mktime( )函数

头文件:#include <time.h>

函数定义:time_t mktime(struct tm *p_tm);

功能描述:mktime( )将参数p_tm指向的tm结构体数据转换成从197011000000秒至今的GMT时间经过的秒数。

例:

  1. int main(void)  
  2. {  
  3.     time_t timep:  
  4.     struct tm *p_tm;  
  5.     timep = time(NULL);  
  6.     pintf("time( ):%d\n", timep);  
  7.     p_tm = local(&timep);  
  8.     timep = mktime(p_tm);  
  9.     printf("time( )->localtime( )->mktime( ):%d\n", timep);  
  10.     return 0;  
  11. }  


2.6 asctime( )函数

头文件:#include <time.h>

函数定义:char *asctime(const struct tm *p_tm);

功能描述:asctime( )将参数p_tm指向的tm结构体数据转换成实际使用的时间日期表示方法,并以字符串形式返回(ctime函数相同)。字符串格式为:"Wed Jun 20 21:00:00 2012\n"

例:

  1. int main(void)  
  2. {  
  3.     time_t timep;  
  4.     timep = time(NULL);  
  5.     printf("%s\n", asctime(gmtime(&timep)));  
  6.     return 0;  
  7. }  


2.7 difftime( )函数

头文件:#include <time.h>

函数定义:double difftime(time_t timep1, time_t timep2);

功能描述:difftime( )比较参数timep1timep2时间是否相同,并返回之间相差秒数。

例:

  1. int main(void)  
  2. {  
  3.     time_t timep1, timep2;  
  4.     timep1 = time(NULL);  
  5.     sleep(2);  
  6.     timep2 = time(NULL);  
  7.     printf("the difference is %f seconds\n", difftime(timep1, timep2));  
  8.     return 0;  
  9. }  


2.8 gettimeofday( )函数

头文件:#include <sys/time.h>

        #include <unistd.h>

函数定义:int gettimeofday(struct timeval *tv, struct timezone *tz);

功能描述:gettimeofday( )把目前的时间信息存入tv指向的结构体,当地时区信息则放到tz指向的结构体。

struct timezone原型:

  1. struct timezone{  
  2.     int tz_minuteswest; /*miniutes west of Greenwich*/  
  3.     int tz_dsttime; /*type of DST correction*/  
  4. };  

例:

  1. struct timeval tv;  
  2. struct timeval tz;  
  3. gettimeofday(&tv, &tz);  


附:

使用time函数族获取时间并输出指定格式字符串例子(strftime( )函数):

  1. int main(void)  
  2. {  
  3.     char strtime[20] = {0};  
  4.     time_t timep;  
  5.     struct tm *p_tm;  
  6.     timep = time(NULL);  
  7.     p_tm = localtime(&timep);  
  8.     strftime(strtime, sizeof(strtime), "%Y-%m-%d %H:%M:%S", p_tm);  
  9.     return 0;  
  10. }  


2.9 settimeofday( )函数

头文件:#include <sys/time.h>

        #include <unistd.h>

函数定义:int settimeofday(const struct timeval *tv, const struct timezone *gz);

功能描述:settimeofday( )把当前时间设成由tv指向的结构体数据。当前地区信息则设成tz指向的结构体数据。

例:


  1. int main(void)  
  2. {  
  3.     char t_string[] = "2012-04-28 22:30:00";  
  4.     struct tm time_tm;  
  5.     struct timeval time_tv;  
  6.     time_t timep;  
  7.     int ret = 0;  
  8.  
  9.     sscanf(t_string, "%d-%d-%d %d:%d:%d", &time_tm.tm_year, &time_tm.tm_mon, &time_tm.tm_mday, &time_tm.tm_hour, &time_tm.tm_min, &time_tm.tm_sec);  
  10.     time_tm.tm_year -= 1900;  
  11.     time_tm.tm_mon -= 1;  
  12.     time_tm.tm_wday = 0;  
  13.     time_tm.tm_yday = 0;  
  14.     time_tm.tm_isdst = 0;  
  15.  
  16.     timep = mktime(&time_tm);  
  17.     time_tv.tv_sec = timep;  
  18.     time_tv.tv_usec = 0;  
  19.  
  20.     ret = settimeofday(&time_tv, NULL);  
  21.     if(ret != 0)  
  22.     {  
  23.         fprintf(stderr, "settimeofday failed\n");  
  24.         return -1;  
  25.     }  
  26.     return 0;  
  27. }  

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章