tzfile格式:处理istd和isgmt

时间:2015-09-24 20:47:48

标签: timezone

我正在尝试解析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根据这些值进行了一些调整。

1 个答案:

答案 0 :(得分:1)

按照上面的要求,我在邮件列表上询问。答案是查看代码。所以相关代码在zic.c(区域编译器)和glib的tzfile.c中。两个源代码都可以在github上找到。 zic.c的相关代码是

switch (lowerit(*ep)) {
        case 's':   /* Standard */
            rp->r_todisstd = true;
            rp->r_todisgmt = false;
            *ep = '\0';
            break;
        case 'w':   /* Wall */
            rp->r_todisstd = false;
            rp->r_todisgmt = false;
            *ep = '\0';
            break;
        case 'g':   /* Greenwich */
        case 'u':   /* Universal */
        case 'z':   /* Zulu */
            rp->r_todisstd = true;
            rp->r_todisgmt = true;
            *ep = '\0';
            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为真,我们可以忽略其他一切。如果它是假的,那么如果前一个转换是DST并且当前的转换不是标准的(即上面的情况'w',因为它也不是gmt)应用dst偏移量(文件中找到的最后一个)。否则应用标准偏移量。

这似乎意味着glibc会忽略个别tt_types和case''中的偏移量。我在localtime.c包中查看了tz,它的工作原理相同。

我只能从这一切中得出结论,tzfile中的大多数信息实际上并未在任何地方使用。其中一些可能是由于POSIX要求。如果有人可以扩展下面的详细信息,请执行。除了C源代码之外,将这种行为记录在互联网上的某个地方会很好。