关于gmtimegmtime_rlocaltimelocaltime_r

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

1、函数功能介绍

使用man gmtime或man 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、总结

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

Linux时间函数

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

linuxstructnulltimezonetimer

系统环境:ubuntu10.04

简介

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

1Linux下常用时间类型

Linux下常用时间类型有四种:time_t、struct tm、struct timeval、struct 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)时间1970年1月1日00时00分00秒(也称为Linux系统的Epoch时间)到当前时刻的秒数。由于time_t类型长度的限制,它所表示的时间不能晚于2038年1月19日03时14分07秒(UTC)。为了能够表示更久远的时间,可用64位或更长的整形数来保存日历时间,这里不作详述。

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

备注:UTC时间有时也称为GMT时间,其实UTC和GMT两者几乎是同一概念。它们都是指格林尼治标准时间,只不过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; /*从每年的1月1日开始的天数-取值区间为[0, 365],0代表1月1日*/
  11. int tm_isdst; /*夏令时标识符,使用夏令时,tm_isdst为正,不使用夏令时,tm_isdst为0,不了解情况时,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)

功能描述:该函数返回从1970年1月1日00时00分00秒至今所经过的秒数。如果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*指针返回。

GMT:GMT是中央时区,北京在东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结构体数据转换成从1970年1月1日00时00分00秒至今的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( )比较参数timep1和timep2时间是否相同,并返回之间相差秒数。

例:

  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. 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);
  9. time_tm.tm_year -= 1900;
  10. time_tm.tm_mon -= 1;
  11. time_tm.tm_wday = 0;
  12. time_tm.tm_yday = 0;
  13. time_tm.tm_isdst = 0;
  14. timep = mktime(&time_tm);
  15. time_tv.tv_sec = timep;
  16. time_tv.tv_usec = 0;
  17. ret = settimeofday(&time_tv, NULL);
  18. if(ret != 0)
  19. {
  20. fprintf(stderr, "settimeofday failed\n");
  21. return -1;
  22. }
  23. return 0;
  24. }

Linux时间函数札记相关推荐

  1. linux时间函数详解

    一.时间相关说明 格林威治时间表示0时区的标准时间.其他时区的时间和此标准时间均有时间差.UTC(Universal Time Coordinated)是世界协调时间,是格林威治时间在互联网中的表示方 ...

  2. linux 时间函数

    下面讲解的是linux中 时间相关的函数和将时间转换相关函数 1.获取时间相关函数 1.1 获取秒级时间差函数 #include <time.h> time_t time(time_t * ...

  3. Linux 时间函数小结

    下面叙述两方面的东西.第一部分,介绍自己写的两个获取时间的示例,这是比较常用的用法:第二部分,各种时间函数的用法汇总,来自网上,已经无法追溯出处了.搜索了下,在以下博客<c语言中时间的获取> ...

  4. Linux时间函数time()、ctime()、ctime_r()、localtime()、localtime_r()、asctime()、strftime()的转换关系

    上面这个图就是它们所有函数的关系转换,比较清晰,不需要太多文字描述. 下面是它们的代码实现过程: #include<stdio.h> #include<unistd.h> #i ...

  5. Linux 时间函数的使用

    头文件 #include <chrono> #include <functional>namespace hsm { namespace common {class Timer ...

  6. linux几种时间函数总结

    一.linux时间函数总结 最近的工作中用到的时间函数比较频繁,今天抽时间总结一下,在linux下,常用的获取时间的函数有如下几个:  asctime,  ctime, gmtime, localti ...

  7. c语言时间函数状态,C语言的时间函数

    下面是C语言的获取本地时间和构造时间进行格式化时间显示输出的相关函数: This page is part of release 3.35 of the Linux man-pages project ...

  8. 三种睡眠时间函数的区别:linux 的sleep()、usleep()、nanosleep()函数

    三种睡眠时间函数的区别:linux 的sleep().usleep().nanosleep()函数 (1)sleep()-------以秒为单位 unsigned int sleep(unsigned ...

  9. linux '$^t' 时间,Linux C时间函数 time_t struct tm

    Linux C时间函数 time_t struct tm #include 关于时间的类型: time_t long型,表示从1970年1月1日到现在经过的秒数. struct tm { int tm ...

最新文章

  1. 2021-03-21 jdk中体统的URL能访问的协议非常有限(当然可以进行扩展,不过很麻烦),常用的有http,file,ftp等等
  2. 棋盘游戏的人工智能(二)------剪支
  3. 51nod 修改数组
  4. 使用函数统计指定c语言,浙大版《C语言程序设计(第3版)》题目集 习题5-5 使用函数统计指定数字的个数...
  5. 用Yum安装最新的MySQL版本
  6. J - DNA Consensus String
  7. 蓝桥杯 ADV-61 算法提高 矩阵乘方
  8. PML调用PDMS内核命令研究
  9. 机器学习之分类决策树节点划分指标
  10. Canvas 画直线
  11. 【PIMF】OpenHarmony啃论文俱乐部:拼音输入法原理_从触摸事件到汉字
  12. 计算机论文中期考核报告,计算机与人工智能学院硕士研究生中期考核办法
  13. ios使用theos tweak logify.pl自动hook .h头文件中所有的方法
  14. Typora基本技巧
  15. js立即执行函数,jqueryReady和Onload执行顺序比较
  16. 利用SQL语句创建、修改、删除、查看与使用数据库
  17. ieee754最小规格化正数C语言,IEEE754标准浮点格式
  18. 被言情小说泡大的人工智能,随便写几行字都是情诗
  19. 艾灸是不是真那么神奇?
  20. 如何解决Bat脚本中包含中文,运行乱码

热门文章

  1. MVC View显示详解(RenderBody,RenderPage,RenderSection,Partial)
  2. Ajax与CustomErrors的尴尬
  3. 【Hexo】deploy出错的解决方法
  4. 【转】phpize学习
  5. 《Linux内核分析》 第四节 扒开系统调用的三层皮(上)
  6. 对于shell脚本参数获取时的一点小技巧
  7. 智能课程表Android版-学年学期星期的实现
  8. Together与Visual.Studio.NET的结合使用(三)
  9. body onload 控制窗口大小 html,如何实现在调整浏览器窗口大小时缩放的网页?
  10. android手机连接无线路由器上网设置,手机连接无线网络怎么设置?手机Wifi无线网设置教程...