对于某些需要自定义夏令时的需求,CentOS 自带的 tzdata 不能满足要求,因此需要自定义 tzdata,我们可以通过修改 tzdata 定义文件进行实现。下面以修改 Asia/Shanghai
即我国的夏令时为例进行说明。
tzdata 的数据可以在 iana 官方的 ftp 上下载:
ftp://ftp.iana.org/tz/releases/
也可以修改 CentOS 官方的源代码:
http://vault.centos.org/7.5.1804/os/Source/SPackages/tzdata-2018c-1.el7.src.rpm
通常来说我们当然是修改 CentOS 官方的源代码来实现,因为我们需要制作 rpm 包。
首先安装 tzdata-2018c-1.el7.src.rpm,然后切换到 ~/rpmbuild/SOURCES/
目录修改 tzdata2018c.tar.gz 中 asia
文件定义的规则。
假设我们想要从 2017 年开始,在每年 9 月的第一个满足日期条件的周日,日期条件为 >= 9月10日,那一天 0 点进入夏令时,然后在 10 月的第一个满足日期条件的周日,日期条件为 >= 10 月 1 日,那一天 0 点退出夏令时,则需要在 PRC
(即中华人民共和国)的规则之下增加两条规则如下(在 /usr/share/zoneinfo
中,Asia/Shanghai
是指向 PRC
的符号链接):
Rule PRC 2017 max - Sep Sun>=10 0:00 1:00 D
Rule PRC 2017 max - Oct Sun>=1 0:00 0 S
然后重新打包 tzdata2018c.tar.gz(注意这个 tar.gz 包没有文件夹),最后重新制作 rpm 包:
~$ rpmbuild -ba ~/rpmbuild/SPECS/tzdata.spec
安装新制作的 tzdata 包,查看 Asia/Shanghai
的夏令时信息如下:
~$ zdump -v Asia/Shanghai
Asia/Shanghai -9223372036854775808 = NULL
Asia/Shanghai -9223372036854689408 = NULL
Asia/Shanghai Mon Dec 31 15:54:16 1900 UTC = Mon Dec 31 23:59:59 1900 LMT isdst=0 gmtoff=29143
Asia/Shanghai Mon Dec 31 15:54:17 1900 UTC = Mon Dec 31 23:54:17 1900 CST isdst=0 gmtoff=28800
Asia/Shanghai Sun Jun 2 15:59:59 1940 UTC = Sun Jun 2 23:59:59 1940 CST isdst=0 gmtoff=28800
Asia/Shanghai Sun Jun 2 16:00:00 1940 UTC = Mon Jun 3 01:00:00 1940 CDT isdst=1 gmtoff=32400
Asia/Shanghai Mon Sep 30 14:59:59 1940 UTC = Mon Sep 30 23:59:59 1940 CDT isdst=1 gmtoff=32400
Asia/Shanghai Mon Sep 30 15:00:00 1940 UTC = Mon Sep 30 23:00:00 1940 CST isdst=0 gmtoff=28800
Asia/Shanghai Sat Mar 15 15:59:59 1941 UTC = Sat Mar 15 23:59:59 1941 CST isdst=0 gmtoff=28800
Asia/Shanghai Sat Mar 15 16:00:00 1941 UTC = Sun Mar 16 01:00:00 1941 CDT isdst=1 gmtoff=32400
Asia/Shanghai Tue Sep 30 14:59:59 1941 UTC = Tue Sep 30 23:59:59 1941 CDT isdst=1 gmtoff=32400
Asia/Shanghai Tue Sep 30 15:00:00 1941 UTC = Tue Sep 30 23:00:00 1941 CST isdst=0 gmtoff=28800
Asia/Shanghai Sat May 3 15:59:59 1986 UTC = Sat May 3 23:59:59 1986 CST isdst=0 gmtoff=28800
Asia/Shanghai Sat May 3 16:00:00 1986 UTC = Sun May 4 01:00:00 1986 CDT isdst=1 gmtoff=32400
Asia/Shanghai Sat Sep 13 14:59:59 1986 UTC = Sat Sep 13 23:59:59 1986 CDT isdst=1 gmtoff=32400
Asia/Shanghai Sat Sep 13 15:00:00 1986 UTC = Sat Sep 13 23:00:00 1986 CST isdst=0 gmtoff=28800
Asia/Shanghai Sat Apr 11 15:59:59 1987 UTC = Sat Apr 11 23:59:59 1987 CST isdst=0 gmtoff=28800
Asia/Shanghai Sat Apr 11 16:00:00 1987 UTC = Sun Apr 12 01:00:00 1987 CDT isdst=1 gmtoff=32400
Asia/Shanghai Sat Sep 12 14:59:59 1987 UTC = Sat Sep 12 23:59:59 1987 CDT isdst=1 gmtoff=32400
Asia/Shanghai Sat Sep 12 15:00:00 1987 UTC = Sat Sep 12 23:00:00 1987 CST isdst=0 gmtoff=28800
...
Asia/Shanghai Sat Apr 13 15:59:59 1991 UTC = Sat Apr 13 23:59:59 1991 CST isdst=0 gmtoff=28800
Asia/Shanghai Sat Apr 13 16:00:00 1991 UTC = Sun Apr 14 01:00:00 1991 CDT isdst=1 gmtoff=32400
Asia/Shanghai Sat Sep 14 14:59:59 1991 UTC = Sat Sep 14 23:59:59 1991 CDT isdst=1 gmtoff=32400
Asia/Shanghai Sat Sep 14 15:00:00 1991 UTC = Sat Sep 14 23:00:00 1991 CST isdst=0 gmtoff=28800
Asia/Shanghai Sat Sep 9 15:59:59 2017 UTC = Sat Sep 9 23:59:59 2017 CST isdst=0 gmtoff=28800
Asia/Shanghai Sat Sep 9 16:00:00 2017 UTC = Sun Sep 10 01:00:00 2017 CDT isdst=1 gmtoff=32400
Asia/Shanghai Sat Sep 30 14:59:59 2017 UTC = Sat Sep 30 23:59:59 2017 CDT isdst=1 gmtoff=32400
Asia/Shanghai Sat Sep 30 15:00:00 2017 UTC = Sat Sep 30 23:00:00 2017 CST isdst=0 gmtoff=28800
Asia/Shanghai Sat Sep 15 15:59:59 2018 UTC = Sat Sep 15 23:59:59 2018 CST isdst=0 gmtoff=28800
Asia/Shanghai Sat Sep 15 16:00:00 2018 UTC = Sun Sep 16 01:00:00 2018 CDT isdst=1 gmtoff=32400
Asia/Shanghai Sat Oct 6 14:59:59 2018 UTC = Sat Oct 6 23:59:59 2018 CDT isdst=1 gmtoff=32400
Asia/Shanghai Sat Oct 6 15:00:00 2018 UTC = Sat Oct 6 23:00:00 2018 CST isdst=0 gmtoff=28800
...
Asia/Shanghai Sat Sep 10 15:59:59 2022 UTC = Sat Sep 10 23:59:59 2022 CST isdst=0 gmtoff=28800
Asia/Shanghai Sat Sep 10 16:00:00 2022 UTC = Sun Sep 11 01:00:00 2022 CDT isdst=1 gmtoff=32400
Asia/Shanghai Sat Oct 1 14:59:59 2022 UTC = Sat Oct 1 23:59:59 2022 CDT isdst=1 gmtoff=32400
Asia/Shanghai Sat Oct 1 15:00:00 2022 UTC = Sat Oct 1 23:00:00 2022 CST isdst=0 gmtoff=28800
...
而 CentOS 自带的 tzdata 包 Asia/Shanghai
夏令时信息如下:
~$ zdump -v Asia/Shanghai
Asia/Shanghai -9223372036854775808 = NULL
Asia/Shanghai -9223372036854689408 = NULL
Asia/Shanghai Mon Dec 31 15:54:16 1900 UTC = Mon Dec 31 23:59:59 1900 LMT isdst=0 gmtoff=29143
Asia/Shanghai Mon Dec 31 15:54:17 1900 UTC = Mon Dec 31 23:54:17 1900 CST isdst=0 gmtoff=28800
Asia/Shanghai Sun Jun 2 15:59:59 1940 UTC = Sun Jun 2 23:59:59 1940 CST isdst=0 gmtoff=28800
Asia/Shanghai Sun Jun 2 16:00:00 1940 UTC = Mon Jun 3 01:00:00 1940 CDT isdst=1 gmtoff=32400
Asia/Shanghai Mon Sep 30 14:59:59 1940 UTC = Mon Sep 30 23:59:59 1940 CDT isdst=1 gmtoff=32400
Asia/Shanghai Mon Sep 30 15:00:00 1940 UTC = Mon Sep 30 23:00:00 1940 CST isdst=0 gmtoff=28800
Asia/Shanghai Sat Mar 15 15:59:59 1941 UTC = Sat Mar 15 23:59:59 1941 CST isdst=0 gmtoff=28800
Asia/Shanghai Sat Mar 15 16:00:00 1941 UTC = Sun Mar 16 01:00:00 1941 CDT isdst=1 gmtoff=32400
Asia/Shanghai Tue Sep 30 14:59:59 1941 UTC = Tue Sep 30 23:59:59 1941 CDT isdst=1 gmtoff=32400
Asia/Shanghai Tue Sep 30 15:00:00 1941 UTC = Tue Sep 30 23:00:00 1941 CST isdst=0 gmtoff=28800
Asia/Shanghai Sat May 3 15:59:59 1986 UTC = Sat May 3 23:59:59 1986 CST isdst=0 gmtoff=28800
Asia/Shanghai Sat May 3 16:00:00 1986 UTC = Sun May 4 01:00:00 1986 CDT isdst=1 gmtoff=32400
Asia/Shanghai Sat Sep 13 14:59:59 1986 UTC = Sat Sep 13 23:59:59 1986 CDT isdst=1 gmtoff=32400
Asia/Shanghai Sat Sep 13 15:00:00 1986 UTC = Sat Sep 13 23:00:00 1986 CST isdst=0 gmtoff=28800
Asia/Shanghai Sat Apr 11 15:59:59 1987 UTC = Sat Apr 11 23:59:59 1987 CST isdst=0 gmtoff=28800
Asia/Shanghai Sat Apr 11 16:00:00 1987 UTC = Sun Apr 12 01:00:00 1987 CDT isdst=1 gmtoff=32400
Asia/Shanghai Sat Sep 12 14:59:59 1987 UTC = Sat Sep 12 23:59:59 1987 CDT isdst=1 gmtoff=32400
Asia/Shanghai Sat Sep 12 15:00:00 1987 UTC = Sat Sep 12 23:00:00 1987 CST isdst=0 gmtoff=28800
...
Asia/Shanghai Sat Apr 13 15:59:59 1991 UTC = Sat Apr 13 23:59:59 1991 CST isdst=0 gmtoff=28800
Asia/Shanghai Sat Apr 13 16:00:00 1991 UTC = Sun Apr 14 01:00:00 1991 CDT isdst=1 gmtoff=32400
Asia/Shanghai Sat Sep 14 14:59:59 1991 UTC = Sat Sep 14 23:59:59 1991 CDT isdst=1 gmtoff=32400
Asia/Shanghai Sat Sep 14 15:00:00 1991 UTC = Sat Sep 14 23:00:00 1991 CST isdst=0 gmtoff=28800
Asia/Shanghai 9223372036854689407 = NULL
Asia/Shanghai 9223372036854775807 = NULL
参考资料
A literary appreciation of the Olson/Zoneinfo/tz database
https://blog.jonudell.net/2009/10/23/a-literary-appreciation-of-the-olsonzoneinfotz-database/
Creating Custom TimeZoneInfo With Daylight Saving Time Transitions
https://www.appliedis.com/creating-custom-timezoneinfo-with-daylight-saving-time-transitions/
最后修改于 2019-01-31