libc中的时间函数

下面看一下localtime, gmtime,mktime的实现

如下图所示:localtime和gmtime共同使用全局内存_tmbuf存入计算的结果。所以多线程要避免使用这两个函数。__tz_convert依次调用tzset_internal(也是tzset的调用方法,用于从环境变量和文件中获取时区信息),__offtime计算时间。

 

libc中的时间函数_第1张图片image.png(图中函数签名是一种老的c风格,先列出函数参数,然后再指定它们的类型)

tzset_internal函数:此函数首先获取tz = getenv ("TZ"),若TZ为NULL则将tz赋值为localtime;然后调用__tzfile_read (tz, 0, NULL);该函数将tz拼接到tzdir = getenv ("TZDIR")路径后面组成一个完整的文件名,接着读取此文件中的时区信息。若TZ不是一个有效的时区文件(如TZ='GMT-8'),则文件读取会失败。此时就会对TZ进行如下解析:1)跳过字符串到+-号的位置(左图);2)对后面数值处理。需要注意的是GMT-8的‘-’对offset的影响是+数。

最后这个函数修改全局变量timezone的值:__timezone = -tz_rules[0].offset;  timezone的符号与”GMT-8“的符号一致

libc中的时间函数_第2张图片libc中的时间函数_第3张图片

 

 __offtime函数:

左边是__offtime在__tz_convert中被调用的实参情况,刚计算的offset传入进去。右边的图中显示这个offset被加到t上!!

libc中的时间函数_第4张图片libc中的时间函数_第5张图片

总上得出:

1)日历时 + 时区 = 本地时间       (日历时就是time函数的输出值,是从1970年1月1日起的一个绝对时间)

2)涉及文件操作,频繁变动时区会影响性能

mktime函数:

此函数的入参是本地时间,返回值是日历时。此函数还会校正输入的本地时间。

此函数做这样的运算:日历时 = 本地时间 - 时区

 

附: 全球划分24个时区,东西半球各12个时区,东为正(GMT-1...GMT-12),表现为比格林尼治早,西为负(GMT+1...GMT+12)。GMT后面的符号决定日历时和时区的加减,后面的数字无谓大小(可以设置GMT-22,这是没有约束的);我们必须自我约束数字的大小和符号,不然就会破坏约定,得不到正确的时间。

你可能感兴趣的:(时区,time,localtime)