linux 时间相关结构体和函数详解
1. 时间概念
1.1 本地时间(locale time)
1.2 格林威治时间(Greenwich Mean Time GMT )
世界时是最早的时间标准。
在1884年,国际上将1s确定为全年内每日平均长度的1/8.64×104。以此标准形成的时间系统,称为世界时,即UT1。
1972年国际上开始使用国际原子时标,从那以后,经过格林威治老天文台本初子午线的时间便被称为世界时,即UT2,或称格林威治时间(GMT)。
1.3 时间协调时间 (Universal Time Coordinated UTC )
1.3.1 UTC 出现缘由
世界协调时是以地球自转为基础的时间标准。由于地球自转速度并不均匀,并非每天都是精确的86400原子s,因而导致了自转时间与世界时之间存在18个月有1s的误差。
为纠正这种误差,国际地球自转研究所根据地球自转的实际情况对格林威治时间进行增减闰s的调整,与国际度量衡局时间所联合向全世界发布标准时间,
这就是所谓的世界协调时( UTC :CoordinatdeUniversalTime)。
1.3.2 UTC
UTC的表示方式为:年(y)、月(m)、日(d)、时(h)、分(min)、秒(s),均用数字表示。
我们平时工作当中看到的计算机日志里面写的时间大多数是用UTC时间来计算的
2. linux 时间的处理
linux下存储时间常见的有两种存储方式,一个是从1970年到现在经过了多少秒,一个是用一个结构来分别存储年月日时分秒的。
time_t 这种类型就是用来存储从1970年到现在经过了多少秒,要想更精确一点,可以用结构struct timeval,它精确到微妙。
2.1 time_t
(1) time_t 是一个长整型,一般用来表示用1970年以来的秒数。
一般通过 time_t time = time(NULL); 获取秒数
2.1.1 time_t 代码例子1
#include <time.h>
#include<stdio.h>
int main()
{
time_t timep;
time(&timep); /*当前time_t类型UTC时间*/
printf("time():%d\n",(int)timep);
time(&timep); /*获取time_t类型的当前时间*/
/*用 gmtime 将time_t类型的时间转换为struct tm类型的时间按,//没有经过时区转换的UTC时间
然后再用 asctime 转换为我们常见的格式 Fri Jan 11 17:25:24 2008
*/
printf("%s", asctime(gmtime(&timep)));
return 0;
}
结果:
time():1597287548
Thu Aug 13 01:36:00 2020
说明:
struct tm* gmtime(const time_t *timep);
将time_t表示的时间转换为没有经过时区转换的UTC时间,是一个struct tm结构指针
char asctime(const struct tm timeptr);
将结构中的信息转换为真实世界的时间,以字符串的形式显示
2.1.2 time_t 代码例子2
#include <time.h>
#include<stdio.h>
int main()
{
time_t timep;
time(&timep); /*获取time_t类型当前时间*/
/*转换为常见的字符串:Fri Jan 11 17:04:08 2008*/
printf("%s", ctime(&timep));
return 0;
}
Thu Aug 13 10:29:57 2020
char *ctime(const time_t *timep);
将timep转换为真是世界的时间,以字符串显示,它和 asctime的参数是tm,不同就在于传入的参数形式不一样
2.1.3 time_t 代码例子3
#include <time.h>
#include<stdio.h>
int main()
{
time_t timep;
struct tm *p;
time(&timep); /*当前time_t类型UTC时间*/
printf("time():%d\n",timep);
p = localtime(&timep); /*转换为本地的tm结构的时间按*/
timep = mktime(p); /*重新转换为time_t类型的UTC时间,这里有一个时区的转换*/ //by lizp 错误,没有时区转换, 将struct tm 结构的时间转换为从1970年至p的秒数
printf("time()->localtime()->mktime(): %d\n", timep);
printf("%s", ctime(&timep));
return 0;
}
结果:
time():1597287634
time()->localtime()->mktime(): 1597287634
Thu Aug 13 11:02:33 2020
2.2 timeval
struct timeval 有两个成员,一个是秒,一个是微妙.
struct timeval
{
long tv_sec; /* seconds */
long tv_usec; /* microseconds 微秒 */
};
由int gettimeofday(struct timeval *tv, struct timezone *tz);获取.
gettimeofday //获得距离1970年的秒数和微妙数
2.2.1 timeval 代码例子
#include <time.h>
#include<stdio.h>
#include<sys/time.h>
int main()
{
time_t timep;
struct tm *p;
time(&timep); /*当前time_t类型UTC时间*/
printf("time():%d\n",(int)timep);
struct timeval us;
gettimeofday(&us,NULL);
printf("gettimeofday: tv_sec=%ld, tv_usec=%ld\n", us.tv_sec, us.tv_usec);
return 0;
}
结果:
time():1597288484
gettimeofday: tv_sec=1597288484, tv_usec=430228
2.3 timespec
struct timespec 有两个成员,一个是秒,一个是纳秒, 所以最高精确度是纳秒.
struct timespec
{
time_t tv_sec; /* seconds */
long tv_nsec; /* nanoseconds */ //纳秒
};
一般由函数long clock_gettime (clockid_t which_clock, struct timespec *tp); 获取.
2.3.1 timespec 代码例子
#include <time.h>
#include<stdio.h>
#include<sys/time.h>
int main()
{
time_t timep;
struct tm *p;
time(&timep); /*当前time_t类型UTC时间*/
printf("time():%d\n",(int)timep);
struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
printf("clock_gettime : tv_sec=%ld, tv_nsec=%ld\n", ts.tv_sec, ts.tv_nsec);
return 0;
}
结果:
time():1597288411
clock_gettime : tv_sec=1597288411, tv_nsec=419949167
2.4 tm //获得详细的时间格式
tm结构的这种时间表示为分解时间
可通过tm结构来获得日期和时间
struct tm
{
int tm_sec; /*秒,正常范围0-59, 但允许至61*/
int tm_min; /*分钟,0-59*/
int tm_hour; /*小时, 0-23*/
int tm_mday; /*日,即一个月中的第几天,1-31*/
int tm_mon; /*月, 从一月算起,0-11*/ 1+p->tm_mon;
int tm_year; /*年, 从1900至今已经多少年*/ 1900+ p->tm_year;
int tm_wday; /*星期,一周中的第几天, 从星期日算起,0-6*/
int tm_yday; /*从今年1月1日到目前的天数,范围0-365*/
int tm_isdst; /*日光节约时间的旗标*/
};
3. 时间相关接口说明
3.1 gmtime //将time_t表示的时间转换为没有经过时区转换的UTC时间
struct tm* gmtime(const time_t *timep);
将time_t表示的时间转换为没有经过时区转换的UTC时间,是一个struct tm结构指针
3.2 asctime //将 tm 的信息转换为真实世界的时间,以字符串的形式显示
说明:
#include <time.h>
char asctime(const struct tm timeptr);
将结构中的信息转换为真实世界的时间,以字符串的形式显示
3.3 ctime //time_t 转换为常见的字符串
char *ctime(const time_t *timep);
将timep转换为真是世界的时间,以字符串显示,它和asctime不同就在于传入的参数形式不一样
3.4 difftime //两个时间相差的秒数
double difftime(time_t time1, time_t time2);
返回两个时间相差的秒数
3.5 gettimeofday //获得距离1970年的秒数和微妙数
int gettimeofday(struct timeval *tv, struct timezone *tz);
返回当前距离1970年的秒数和微妙数,后面的tz是时区,一般不用
3.6 localtime //经过时区转换的时间
stuct tm* localtime(const time_t *timep);
和gmtime类似,但是它是经过时区转换的时间。
3.7 mktime //将struct tm 结构的时间转换为从1970年至今的秒数
time_t mktime(struct tm* timeptr);
将struct tm 结构的时间转换为从1970年至今的秒数
参考:
https://www.runoob.com/w3cnote/cpp-time_t.html
https://www.cnblogs.com/hushaojun/p/7990951.html