时区信息数据库

<image>

时区信息数据库，又称TZ database、Zoneinfo database，是一个主要应用于电脑程序以及操作系统的，可协作编辑世界时区信息的数据库。由于该数据库由David Olson创立，因而有些地方也将其称作Olson数据库。数据库由Paul Eggert进行编辑和维护。

它的显著特色是由上面提到的Paul Eggert设计的一套通用时区命名规则，例如"America/New_York"和"Europe/Paris"。数据库试图记录自1970年（Unix元年）以来时区和城市的变化，并且还包含一些时间的转换，例如夏令时和闰秒。

## 历史

该项目可以追溯至1986年之前。项目的数据库和一些涉及到的源代码已经释放到公有领域。通常，数据库会每年更新若干次，并发布变更公告。

## 时区的定义

在时区信息数据库中，“时区”被定义为自1970年当地时间统一的国家及地区。这种定义方法关注于一个具有相同时间的地理区域，它与其他对时区的定义方法不同的是，其他方法关注于不同时区与本初子午线之间的时差。因而数据库中定义的每个时区都会记录一系列对协调世界时的时差，同一时区内一般会包含标准时间和夏令时两种。

## 时区的命名

为了更容易地理解，每个时区按照“区域/位置”格式，得到一个独有的名称，例如“America/New_York”。英文地名中的空格用下划线“_”代替，连词符“-”只在英文地名本身包含时使用。

### 区域

“区域”指的是大洲、大洋名称以及Etc。大陆和海洋名称中包括：非洲、美洲、亚洲、欧洲、大洋洲、南极洲，太平洋、大西洋、印度洋、北冰洋。

Etc用作一些管理时区，具体而言例如“Etc/UTC”，意为协调世界时（Coordinated Universal Time）。为了与POSIX标准统一，以“Etc/GMT”标记的时区将保留时区符号，即在格林威治时间（GMT）以西的区域的时区符号为正，以东区域符号为负。

### 地点

“地点”指的是是在区域中的特定地点的名称，通常是城市或小岛屿的名称。

由于政权更替以及边界的变动，国家名称不能稳定地描述一个区域，故不适合用来命名时区。相比之下，大城市的名称更加固定。然而，数据库的维护者们想为每一个国家代码添加至少一个时区，这样很多用户访问数据库的界面就能够得到优化。另外，（管理者们）还想让时区的地点在地理上更加紧凑，在未来时区可能发生的变化中，不会将原有的时区分割为不同的时区。

通常会选择时区内一个人口多的城市作为该时区的名称，也有使用其他城市名称的情况，例如使用一些更加有名或不易引起歧义的城市作为名称。如果一个城市名发生了变化，则会在未来的版本中生成该城市的别名，这样无论通过哪个名称访问，结果都会指向数据库中同一条记录。

有时候，“地点”本身也是一个复合名称，例如“America/Indiana/Indianapolis”时区。目前数据库中存在的三级时区名称包括：“America/Argentina/...”、“America/Kentucky/...”、“America/Indiana/...”和“America/North_Dakota/...”。

由于“地点”的命名会选取这个区域具有代表性的名称，因而不是每个城市都有一个以它命名的时区，例如没有“America/Boston”这个时区。此外，数据库中不同位置尽管有不同的名称，它们也有可能目前拥有同一个时区，例如一些历史上曾经分处不同时区（“America/Detroit”和“America/New_York”）和一些在不同国家的位置（“Europe/Prague”和“Europe/Bratislava”）。

## 时区数据

对于那些有多个时间偏移（通常指的是标准情况和夏令时情况下两个变量）的时区，时区信息数据库会记录准确的偏移变换时刻。数据记录的格式也可以将转换过程中日期和时间的变化记录起来。

### Zone.tab文件

zone.tab文件存在于互联网中，文件格式的相关说明可参考文件中的注释，如下所示：

原文

```
# This file contains a table with the following columns:
# 1.  [[ISO 3166-1二位字母代码|ISO 3166 2-character country code]].  See the file `iso3166.tab'.
# 2.  Latitude and longitude of the zone's principal location
#     in [[ISO 6709]] sign-degrees-minutes-seconds format,
#     either +-DDMM+-DDDMM or +-DDMMSS+-DDDMMSS,
#     first latitude (+ is north), then longitude (+ is east).
# 3.  Zone name used in value of TZ environment variable.
# 4.  Comments; present if and only if the country has multiple rows.
#
# Columns are separated by a single tab.
# The table is sorted first by country, then an order within the country that
# (1) makes some geographical sense, and
# (2) puts the most populous zones first, where that does not contradict (1).
```

译文

文件中的表格包含以下几列：

- ISO 3166 2个字符的国家/地区代码。详见文件“iso3166.tab”。
- 时区代表位置的经纬度，使用ISO 6709标准（符号-度-分-秒）格式表示，即±度度分分±度度度分分或±度度分分秒秒±度度度分分秒秒。前半部分为纬度（北半球为正数），后半部分为经度（东半球为正数）。
- `TZ`环境变量中使用的时区名称。
- 注解，当且仅当该国家有多行记录时存在。

列之间以一个定位字元分隔。

表格首先依据国家进行排序，对同一国家内部的不同记录，以下列方式进行排序：

(1) : 按照地理位置进行排序

(2) : 在不与(1)冲突的先前下，将人口最多的区域插入首位。

## 1970年之前的数据

1970年之前的数据由于城市区域的变化需要进行修正，没有必要对整个区域的时区信息进行修正，这是由于新划分的区域仅需要与1970年至今的时钟进行时差比较。

例如，在1963年10月23日至1963年12月9日，巴西只有米纳斯吉拉斯（Minas Gerais）、圣埃斯皮里图州（Espirito Santo）、里约热内卢州（Rio de Janeiro）和圣保罗（Sao Paulo）有夏令时，由于自1970年以来圣保罗整个区域内时钟相同，导致一个区域无法从America/Sao_Paulo时区中划分出来，这是1970年之前的数据需要修正的原因之一。

以柏林时间（Europe/Berlin）为准的德国标准时间，在1945年之后的英、美、苏三国共同占领区域则是一段时间并未按照柏林时间进行夏令时变换。

## 文件格式

时区信息数据库（Tz database）以文本文件的形式发布，文件以可阅读的形式记录了的条目规则和时区过渡信息。为便于使用，这些文本文件被编译为与操作系统无关的二进制文件，每个时区对应一个文件。相关的代码包括，被称为zic（Zone Information Compiler，时区信息编译器），以及用来读取其他文件，并将文件中的时区信息应用于应用程序接口（例如`localtime()`和`mktime()`）。

## 维护

时区信息相关的代码和数据库由一群志愿者维护。Arthur David Olson侧重于代码的编辑，Paul Eggert则侧重于数据库。计划变更的条目会被送到项目的邮件列表中，在Usenet的comp.time.tz讨论组中。项目源文件发布在FTP服务器elsie.nci.nih.gov上，这些源文件被类似于Debian的软件发行商编译、打包后成为发行版本中的一部分。终端用户可以通过对发行版本的升级来更新数据库，当然这样更新会有一些滞后，或者直接从 获得源代码，自己编译生成二进制文件。基于类似原则的一个 未来维护计划 已经由互联网号码分配局起草完成。

## 其他标准下的应用

通用当地数据储存库使用UN/LOCODE对区域进行判断。这意味着字符将与国家对应，这是时区信息数据库想要避免的状况。

## 软件系统中的应用

时区信息数据库用来处理时区和进行时区转换，已经应用于很多的计算机系统中，包括：

- BSD衍生操作系统，包括FreeBSD、NetBSD、OpenBSD、DragonFly BSD和Mac OS X。
- GNU C 库以及使用它的系统，包括GNU、大多数的Linux发行版、BeOS、Haiku、Nexenta OS以及Cygwin。
- System V Release 4衍生系统，例如Solaris和UnixWare。
- AIX 6.1及更高版本（自AIX 5.2开始的较早版本，仅为支持MySQL之类的第三方软件而加入时区信息，但其并未将时区信息应用到操作系统中。）。
- 一些其他的Unix操作系统，包括Tru64和UNICOS/mp（还有IRIX，维护而不发行）。
- OpenVMS;
- JAVA运行时环境 1.4（2002）以后的发行版。
- Perl的 DateTime::TimeZone 以及 DateTime::LeapSecond 组件，2003年起。
- PHP发行版 5.1.0（2005）及以后。
- Python组件 pytz。
- .NET Framework的 zoneinfo 组件。
- Oracle 10g（2004）以后的发行版。
- PostgreSQL 8.0 （2005）以后的版本。
- 嵌入式软件，例如IP钟表中的固件。

通用当地数据储存库和国际统一码部件采纳了Olson时区编号被采纳。例如，这里 是微软Windows操作系统中的时区ID与Olson标准名称的映射关系。

## 参考文献

- "tz mailing list"; archives of these messages are available at .

## 外部链接

- ITU LEGAL TIME 2011
- The tz database home page
- The tz mailing list archive
- Current tz source and data raw files
- Current tz data files compiled to multiple formats
- Lists of tz-zones by tz-group
- The tz database converted to SQL format
- Olson Database converted to Windows Standard Format
- “A literary appreciation of the Olson/Zoneinfo/tz database” by Jon Udell