我正在尝试解析Unix系统上的tzfile (Olson)格式。在tzfile(5)手册页中,它声明如下:
Then there are tzh_ttisstdcnt standard/wall indicators, each stored
as a one-byte value; they tell whether the transition times
associated with local time types were specified as standard time or
wall clock time, and are used when a timezone file is used in
handling POSIX-style timezone environment variables.
Finally, there are tzh_ttisgmtcnt UTC/local indicators, each stored
as a one-byte value; they tell whether the transition times
associated with local time types were specified as UTC or local time,
and are used when a timezone file is used in handling POSIX-style
timezone environment variables.
这是否意味着我可以忽略isstd和isgmt,仍然得到正确的时间?在抽查中,似乎是这样,但在C源文件中挖掘,我看到unix根据这些值进行了一些调整。
按照上面的要求,我在邮件列表中询问了。答案是查看代码。因此,相关代码在zic.c
(区域编译器)和glib的tzfile.c
中。在撰写本文时,可以在github上找到两者的源代码。zic.c
的相关代码为
switch (lowerit(*ep)) {
case 's': /* Standard */
rp->r_todisstd = true;
rp->r_todisgmt = false;
*ep = ' ';
break;
case 'w': /* Wall */
rp->r_todisstd = false;
rp->r_todisgmt = false;
*ep = ' ';
break;
case 'g': /* Greenwich */
case 'u': /* Universal */
case 'z': /* Zulu */
rp->r_todisstd = true;
rp->r_todisgmt = true;
*ep = ' ';
break;
它说有3种可能的情况:isstd = true && isgmt = false
,既假又真。因此,要查看这些标志的作用,tzfile.c
中的相关代码是
if (trans_type->isgmt)
/* The transition time is in GMT. No correction to apply. */ ;
else if (isdst && !trans_type->isstd)
/* The type says this transition is in "local wall clock time", and
wall clock time as of the previous transition was DST. Correct
for the difference between the rule's DST offset and the user's
DST offset. */
transitions[i] += dstoff - rule_dstoff;
else
/* This transition is in "local wall clock time", and wall clock
time as of this iteration is non-DST. Correct for the
difference between the rule's standard offset and the user's
standard offset. */
transitions[i] += stdoff - rule_stdoff;
所以这似乎说,如果isgmt
为真,我们可以忽略其他一切。如果它是false,那么如果之前的转换是DST,而当前的转换不是标准的(即上面的情况'w',因为它也不是gmt),则应用dst
偏移量(在文件中找到的最后一个)。否则应用标准偏移量。
这似乎意味着glibc忽略了单个tt_types和case 's'中的偏移量。我在tz
包中查看了localtime.c
,它以相同的方式工作。
我只能从所有这些得出结论,tzfile中的大多数信息实际上并没有在任何地方使用。其中一些可能是由于POSIX要求。如果有人可以详细说明下面的细节,请做。除了C源代码之外,最好在互联网上的某个地方记录此行为。