时间详解
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 *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
本文来自博客园,作者:moonのsun,转载请注明原文链接:https://www.cnblogs.com/moon-sun-blog/p/16253919.html

浙公网安备 33010602011771号