时区数据库

1,325 阅读2分钟

时区相关的名词解释

见上篇: 时区

通用时区数据库

Time Zone Database,时区数据库,通常称为 tz 或 zoneinfo,是一组包含大量代码和数据用来表示全球许多有代表性的地点的本地时间的历史信息,他会根据各个政体对时区边界和夏令时规则的改变而不定期的更新。目前由IANA维护。

tzdata是Time Zone Database发布的组件之一,其他还有tzcode等。

tzdata软件包,全称time zone and daylight-saving time(DST) data,供各个Linux系统安装以读取Time Zone Database中数据。

该数据库由一套通用时区命名规则,每个时区按照“区域/位置”格式,得到一个独有的名称,例如“America/New_York”。

通用时间格式

操作系统中TZ环境变量代表时区信息。TZ时区名字有两种形式:时区名格式和POSIX时区格式。

1. 时区名格式

:characters 该种形式以冒号开始,后面的字符处理与实现相关。linux上表示从某个文件读时区信息,例如TZ=":Pacific/Auckland"。

go1.18.4/src/time/zoneinfo_unix.go 
// Many systems use /usr/share/zoneinfo, Solaris 2 has 
// /usr/share/lib/zoneinfo, IRIX 6 has /usr/lib/locale/TZ. 
var zoneSources = []string{ 
    "/usr/share/zoneinfo/", 
    "/usr/share/lib/zoneinfo/", 
    "/usr/lib/locale/TZ/", 
    runtime.GOROOT() + "/lib/time/zoneinfo.zip", 
} 
func initLocal() { 
    // consult $TZ to find the time zone to use. 
    // no $TZ means use the system default /etc/localtime. 
    // $TZ="" means use UTC. 
    // $TZ="foo" or $TZ=":foo" if foo is an absolute path, then the file pointed 
    // by foo will be used to initialize timezone; otherwise, file 
    // /usr/share/zoneinfo/foo will be used. 
    
    tz, ok := syscall.Getenv("TZ") 
    switch { 
    case !ok: 
        z, err := loadLocation("localtime", []string{"/etc"}) 
        if err == nil { 
            localLoc = *z 
            localLoc.name = "Local" 
            return 
        } 
    case tz != "": 
        if tz[0] == ':' { 
            tz = tz[1:] 
        } 
        if tz != "" && tz[0] == '/' { 
            if z, err := loadLocation(tz, []string{""}); err == nil { 
                localLoc = *z 
                if tz == "/etc/localtime" { 
                    localLoc.name = "Local" 
                } else { 
                    localLoc.name = tz 
                } 
                return 
            } 
        } else if tz != "" && tz != "UTC" { 
            if z, err := loadLocation(tz, zoneSources); err == nil { 
                localLoc = *z return 
            } 
        } 
    } 
    
    // Fall back to UTC. 
    localLoc.name = "UTC" 
}

2. POSIX时区格式

格式:std offset[ dst[offset][,startdate[/time], enddate[/time]] ]

std: 标准时区,必须

dst:日光制时区 ,可选,代表支持夏令时

offset:代表本地时间加上多少能得到UTC时间

举例:"UTC-8:00:00DST-09:00:00,M3.2.0/02:00:00,M11.1.0/02:00:00"

表示本地时间为UTC以东减8小时,支持夏令时且夏令时为UTC减9小时(及提前一小时),夏令时从3月第2周第0天凌晨2点开始,到11月第1周第0天凌晨2点结束。

POSIX时区格式由于无法表示不使用公历的时间(比如希腊),因此并未被广泛采用。

修改服务器时区

1. 查看日期

bash-4.2# date -R

Tue, 01 Nov 2022 10:37:54 +0000

2. 安装时区设置

apk add tzdata

3. 复制上海时区

cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

4. 指定为上海时区

echo "Asia/Shanghai" > /etc/timezone

5. 验证

bash-4.2# date -R

Tue, 01 Nov 2022 18:51:22 +0800

6. 删除其他时区配置,节省空间

apk del tzdata

/etc/localtime和/etc/timezone区别

/etc/localtime是用来描述本机时间

/etc/timezone是用来描述本机所属的时区

参考: zhuanlan.zhihu.com/p/389530522