时间详解

1. UTC、GMT、墙上时间

Coordinated Universal Time(UTC)

Greenwich Mean Time(GMT)

两者都表示标准时间,或世界时,几乎没有差异,后者更加精确

墙上时间也就是本地时间,说出墙上时间的时候,需要告知时区信息,这样才有意义。

 

 

2. typedef uint32 time_t

time_t表示“当前时刻”与“UTC 1970.1.1 0时0分0秒”的时间差,单位s

 

 

3. time(&time_t)

获取上面的值,即此函数会返回从公元1970年1月1日的UTC时间从0时0分0秒算起到现在所经过的秒数。

问题:time()返回的结果和时区有关吗?

UTC “0时0分0秒”是一个唯一的精确的时刻,“现在”也是一个唯一的精确的时刻,两者之间的差值唯一,和时区无关!

无论你是在0时区,还是东八区,返回的都是UTC “0时0分0秒” => 现在 的时间差(秒),这是一个客观存在的值。

(之所以会认为和时区有关,是因为该值的大小等于“UTC(墙上)时间 - 1970.1.1 0:0:0”,不过这个不用多考虑)

正是因为该值客观存在,所以文件的创建时间就可以用time_t表示,和时区无关,且有:

创建时间 = 墙上时间 - 时区

 

 

4. struct tm

墙上时间,带有时区信息

struct tm {
int tm_sec;
int tm_min;
int tm_hour;
int tm_mday;
int tm_mon;
int tm_year; /* 年份,其值等于实际年份减去1900 */
int tm_wday; /* 星期 – 取值区间为[0,6],其中0代表星期天,1代表星期一,以此类推 */
int tm_yday; /* 从每年的1月1日开始的天数 – 取值区间为[0,365],其中0代表1月1日,1代表1月2日,以此类推 */
int tm_isdst; /* 夏令时标识符,实行夏令时的时候,tm_isdst为正。不实行夏令时的时候,tm_isdst为0;不了解情况时,tm_isdst()为负。
};
注意两个年份基准:1970和1900
 
 
 
5. gmtime()和gmtime_r()

struct tm *gmtime(const time_t *timep) // 线程不安全

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

根据time_t计算得到GMT时间,即格林威治墙上时间

根据此函数的定义,只有在想要获取GMT的时候,才会使用该函数,机器代码中一般用不到!

关于线程安全:

通过观察gmtime()返回值是结构体指针,那么结构体在哪里?

其实使用localtime和gmtime获取的返回时间是保存在一个全局的变量中的;

如果调用了localtime后,返回值没有做处理,然后接着调用gmtime,gmtime会将localtime的返回值给覆盖掉

(前者函数有一个好处,那就是时间只有一套,不会乱)

 

 

6. localtime()和localtime_r()

struct tm *localtime(const time_t *timep) // 线程不安全

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

 根据time_t计算得到GMT时间,然后再根据时区信息(隐藏在localtime()函数内部的调用中)调整为本地时间。

比如在东八区,相比gmtime(),localtime()获得的值会大8h。

该函数比gmtime()更加常用。

 

 

7. mktime()

mktime()的作用和localtime()正好相反,用来把墙上时间转化为标准时差值(距UTC 1970.1.1 00:00的时间差);

标准时差值以UTC为准,localtime()和mktime()实现的时候都需要参考timezone。

 

 

8. 常用方法

方法1:

time_t = mktime(&tm)  // 拿到墙上时间,转化为标准时差值(此刻距UTC 1970.1.1 00:00 的时间差)

tm = localtime(time_t)  // 把标准时差值转化为墙上时间

方法2:

time(&time_t);    // 通过其他方法获取标准时差值

tm = localtime(time_t)  // 把标准时差值转化为墙上时间

 

 

https://blog.csdn.net/weixin_52622200/article/details/111478915

https://zhuanlan.zhihu.com/p/363203858

https://evian-zhang.github.io/introduction-to-linux-x86_64-syscall/src/filesystem/stat-fstat-lstat-newfstatat-statx.html

 

posted @ 2022-05-10 15:52  moonのsun  阅读(287)  评论(0)    收藏  举报