tz database を読んでみる

# tz database を読んでみる

皆さんは、海外の地域での日時を扱うコードを書いたことはありますか？
サマータイムを考慮したコードを書いたことがありますか？

この記事では、日本も含め、日時を扱う上で気づかないうちにお世話になっている方も多いだろう tz database について紹介しつつ、定義情報を読んだ記録も公開しようと思います。

正確ではないところも多々あると思うので、もしお気づきの点があればコメントや編集リクエストをいただければ幸いです！

## 1. tz database って何？

こちらのページで tz database は公開されています。

* [IANA - Time Zone Database](https://www.iana.org/time-zones)

Wikipedia から引用します。

* [tz database - ウィキペディア (Wikipedia): フリー百科事典 (最終更新日 2019年7月4日 時点)](https://ja.wikipedia.org/wiki/Tz_database)

> tz databaseとは、世界各地域の標準時（time zone、タイムゾーン）情報をボランティアの共同作業により収録したデータである。主にコンピュータ・プログラムやオペレーティングシステムでの利用を意図している[3]。略称はtzdata、別名zoneinfo databaseとも呼ばれ、データベースの作成に貢献したアーサー・デイヴィッド・オルソン（Arthur David Olson）にちなみOlson databaseとも呼ばれる[4]。ポール・エッガート（Paul Eggert）はtz databaseの編集者兼管理者である[5]。また2011年10月からはThe Internet Corporation for Assigned Names and Numbers（ICANN）並びにInternet Assigned Numbers Authority（IANA）が管理に加わっている。

日本は長い間、サマータイムを採用せずに協定世界時(UTC)から+9時間の標準時をずっと採用し続けていますが、外国の地域によっては政治などによって頻繁に変えていたりしています。
たとえば、最近ですと、2019年からブラジルがサマータイムを廃止したり、2018年10月28日からロシアのヴォルゴグラードが標準時を UTC+03 から UTC+04 に変更したりなどしています。

tz database は多くのボランティアの方々の努力によって、各地域がいつからいつまではどういう日時のルールなのかが定義されているデータの集まりで、OS や日時ライブラリはこの tz database を参照することで、指定した地域に合わせた適切な日時を計算できるようになります。

バージョンは「<年><アルファベット一文字>」で構成されていて、2018h -> 2018i -> 2019a -> 2019b のように増えていきます。2019年12月5日現在の最新は 2019c です。

各地域のIDは「<地域>/<都市名など>」のようになっています。

* Asia/Tokyo
* America/New_York
* America/Indiana/Indianapolis

## 2. 利用例

ここでは以下2点を挙げます。

* Linux
* Moment.js

### Linux

手元の Ubuntu 18.04 で tz database を使っているかどうかを確認します。

「tzdata」というパッケージは、のバージョン名などから tz database を扱っているように見受けられます。

```bash
$ apt show tzdata
Package: tzdata
Version: 2019c-0ubuntu0.18.04
Priority: important
Section: libs
Origin: Ubuntu
Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
Original-Maintainer: GNU Libc Maintainers <debian-glibc@lists.debian.org>
Bugs: https://bugs.launchpad.net/ubuntu/+filebug
Installed-Size: 3,107 kB
Provides: tzdata-buster
Depends: debconf (>= 0.5) | debconf-2.0
Replaces: libc0.1, libc0.3, libc6, libc6.1
Homepage: https://www.iana.org/time-zones
Task: minimal
Supported: 5y
Download-Size: 190 kB
APT-Manual-Installed: yes
APT-Sources: http://jp.archive.ubuntu.com/ubuntu bionic-updates/main amd64 Packages
Description: タイムゾーンおよびサマータイムデータ
 本パッケージには、世界中の多くの代表的な場所のローカル時間の実装に必要な データが含まれます。タイムゾーンの境界への政治団体による変更、UTC
 オフセット、 そしてサマータイムルールを反映するため、定期的に更新されています。
```

tzdata パッケージのインストール先を調べると、どうやら /user/share/zoneinfo にインストールしているようです。

```bash
$ dpkg -L tzdata
/.
/usr
/usr/sbin
/usr/sbin/tzconfig
/usr/share
/usr/share/doc
/usr/share/doc/tzdata
/usr/share/doc/tzdata/README.Debian
/usr/share/doc/tzdata/changelog.Debian.gz
/usr/share/doc/tzdata/copyright
/usr/share/zoneinfo
/usr/share/zoneinfo/Africa
/usr/share/zoneinfo/Africa/Abidjan
/usr/share/zoneinfo/Africa/Accra
/usr/share/zoneinfo/Africa/Addis_Ababa
/usr/share/zoneinfo/Africa/Algiers
/usr/share/zoneinfo/Africa/Bangui
/usr/share/zoneinfo/Africa/Bissau
/usr/share/zoneinfo/Africa/Blantyre
/usr/share/zoneinfo/Africa/Casablanca

(略)

/usr/share/zoneinfo/right/US/Hawaii
/usr/share/zoneinfo/right/US/Indiana-Starke
/usr/share/zoneinfo/right/US/Michigan
/usr/share/zoneinfo/right/US/Mountain
/usr/share/zoneinfo/right/US/Pacific
/usr/share/zoneinfo/right/US/Pacific-New
/usr/share/zoneinfo/right/US/Samoa
/usr/share/zoneinfo/right/UTC
/usr/share/zoneinfo/right/Universal
/usr/share/zoneinfo/right/Zulu
```

このデータをどのように扱っているかはこの情報だけでは定かではありませんが、少なくとも Ubuntu は tz database を含んでいるようです。

### Moment.js

JavaScript の日時を扱うライブラリとして、有名なものとして Moment.js があります。
この Moment.js でタイムゾーンを扱うためのプラグインとして、moment-timezone があります。

* [Moment Timezone - Home](https://momentjs.com/timezone/)

以下のようにタイムゾーンを扱えます。

sample.js

```javascript

const moment = require('moment-timezone');

console.log(moment.tz('2019-01-05 12:00', 'UTC').tz('America/New_York').format()); // 2019-01-05T07:00:00-05:00
console.log(moment.tz('2019-07-05 12:00', 'UTC').tz('America/New_York').format()); // 2019-07-05T08:00:00-04:00
```

moment-timezone の data ディレクトリの中をみると、tz database をもとに生成されたような情報があります。

* [moment-timezone/data at 0.5.27 · moment/moment-timezone](https://github.com/moment/moment-timezone/tree/0.5.27/data)

## 3. tz database の定義を読んでみる

ここからは、現在の各地域のタイムゾーンのルールがどうなっているかを見ていきたいと思います。
読み方は tz database に同梱されている [tz-how-to.html](https://data.iana.org/time-zones/tz-how-to.html)に書かれています。

今回読んで見る tz database のバージョンは 2019c です。
また、以降「現在」という言葉は、2019年12月6日時点を指すと解釈してください。

### Asia/Tokyo

今現在の日本はサマータイムを採用しておらず、通年 UTC+9 を採用しています。
それを踏まえて日本の東京の定義をみていきます。

東京の定義は Asia/Tokyo で以下の場所となります。

https://github.com/eggert/tz/blob/2019c/asia#L1910-L1912

```
# Zone	NAME		STDOFF	RULES	FORMAT	[UNTIL]
Zone	Asia/Tokyo	9:18:59	-	LMT	1887 Dec 31 15:00u
			9:00	Japan	J%sT
```

コメントを除いて1行目は UTC 時刻の 1887年12月31日 15:00 までの設定なので、今現在の設定は UNTIL が未設定の2行目の定義が適用されるはずです。

2行目は今現在は UTC のオフセットは 9:00 であり、後述する Japan という Rule の定義にしたがって、そのときに使われるタイムゾーンの略語のフォーマットは「J%sT」に従うとなっています。
「%s」には後述する Japan の Rule の定義のカラムである LETTER の文字が設定され、「S」もしくは「D」が設定され、「JST」(Japan Standard Time)もしくは「JDT」(Japan Daylight Saving Time) になります。

それでは、「Japan」のルールをみてみましょう。

https://github.com/eggert/tz/blob/2019c/asia#L1873-L1877

```
# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
Rule	Japan	1948	only	-	May	Sat>=1	24:00	1:00	D
Rule	Japan	1948	1951	-	Sep	Sat>=8	25:00	0	S
Rule	Japan	1949	only	-	Apr	Sat>=1	24:00	1:00	D
Rule	Japan	1950	1951	-	May	Sat>=1	24:00	1:00	D
```

コメントを除いて1行目は1948年の間だけのルールで、5月第1土曜の24時から JDT になり、標準時より+1時間ずれたサマータイムが実施されます。 
2行目は1948年から1951年の期間のルールで、9月第2土曜の25時から JST になります。
3行目は1949年の間だけのルールで、4月第1土曜の24時から JDT になり、標準時より+1時間ずれたサマータイムが実施されます。
4行目は1950年から1951年の期間のルールで、5月第1土曜の24時から JDT になり、標準時より+1時間ずれたサマータイムが実施されます。
これらは、戦後に一時的にサマータイムが採用されていたときのルールのようです。

そして、確認したい今現在の「Japan」のルールは書かれていないようです。

ルールが設定されていない場合の挙動はどうなるかはみつかりませんでしたが、日本の現状を考慮すると該当期間のルールが見つからなかったの場合は、Zone の定義の STDOFF のままになって、オフセットは 9:00 となるのではないかと推測していますが、どうなのでしょうか？
後日調べたいところです。

JST や JDT などのタイムゾーンの略語の定義がどこかにあるのかなと探しましたが、以下のコメント以外にはみつかりませんでした。

https://github.com/eggert/tz/blob/2019c/asia#L40-L55

```
# The following alphabetic abbreviations appear in these tables
# (corrections are welcome):
#	     std  dst
#	     LMT	Local Mean Time
#	2:00 EET  EEST	Eastern European Time
#	2:00 IST  IDT	Israel
#	5:30 IST	India
#	7:00 WIB	west Indonesia (Waktu Indonesia Barat)
#	8:00 WITA	central Indonesia (Waktu Indonesia Tengah)
#	8:00 CST	China
#	8:00 HKT  HKST	Hong Kong (HKWT* for Winter Time in late 1941)
#	8:00 PST  PDT*	Philippines
#	8:30 KST  KDT	Korea when at +0830
#	9:00 WIT	east Indonesia (Waktu Indonesia Timur)
#	9:00 JST  JDT	Japan
#	9:00 KST  KDT	Korea when at +09
```

### America/Los_Angeles

今現在、アメリカ合衆国では3月の第2日曜の2時から11月の第1日曜の2時までをサマータイムとしています。
それを踏まえて、アメリカ合衆国のロサンゼルスの定義をみていきます。

ロサンゼルスの定義は America/Los_Angeles で以下の場所となります。

https://github.com/eggert/tz/blob/2019c/northamerica#L562-L566

```
# Zone	NAME		STDOFF	RULES	FORMAT	[UNTIL]
Zone America/Los_Angeles -7:52:58 -	LMT	1883 Nov 18 12:07:02
			-8:00	US	P%sT	1946
			-8:00	CA	P%sT	1967
			-8:00	US	P%sT
```

FORMAT の「%s」には後述する US のルールの定義のカラムである LETTER の文字が設定され、「PDT」、「PST」などになります。

コメントを除いて1行目から3行目は1967以前のものであり、今現在の America/Los_Angeles の定義は４行目となります。
4行目は今現在のオフセットは -8:00 であり、後述する US というルールにしたがって、そのフォーマットは「P%sT」となっています。

それでは、US のルールをみてみましょう。

https://github.com/eggert/tz/blob/2019c/northamerica#L173-L186

```
# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
Rule	US	1918	1919	-	Mar	lastSun	2:00	1:00	D
Rule	US	1918	1919	-	Oct	lastSun	2:00	0	S
Rule	US	1942	only	-	Feb	9	2:00	1:00	W # War
Rule	US	1945	only	-	Aug	14	23:00u	1:00	P # Peace
Rule	US	1945	only	-	Sep	30	2:00	0	S
Rule	US	1967	2006	-	Oct	lastSun	2:00	0	S
Rule	US	1967	1973	-	Apr	lastSun	2:00	1:00	D
Rule	US	1974	only	-	Jan	6	2:00	1:00	D
Rule	US	1975	only	-	Feb	lastSun	2:00	1:00	D
Rule	US	1976	1986	-	Apr	lastSun	2:00	1:00	D
Rule	US	1987	2006	-	Apr	Sun>=1	2:00	1:00	D
Rule	US	2007	max	-	Mar	Sun>=8	2:00	1:00	D
Rule	US	2007	max	-	Nov	Sun>=1	2:00	0	S
```

今現在は、以下の部分を参照すればよさそうです。

> Rule	US	2007	max	-	Mar	Sun>=8	2:00	1:00	D
> Rule	US	2007	max	-	Nov	Sun>=1	2:00	0	S

2007年から今現在の「US」のルールは、3月の第2日曜の2時からは標準時より1時間追加して PDT (Pacific Daylight Time)、つまりサマータイムが採用されることが定義されているようです。
2007年から今現在の「US」のルールは、11月の第1日曜の2時からは PST (Pacific Standard Time)になるようです。

### Africa/Casablanca

モロッコは 2018/10/28 までは標準時は UTC+0 でサマータイム時は UTC+1 にするのですが、
サマータイム中にラマダンの時期になったときは UTC+0 に戻り、ラマダンの時期が終わるとサマータイムの UTC+1 に戻るというのを採用していました。
2018年からは通年サマータイムになり基本 UTC+1 になり、ラマダンの時期だけ元々の標準時の UTC+0 になるようになっているとのことです。
なお、これらの時期の開始時期と終了時期は毎年バラバラのようです。

それを踏まえて、モロッコのカサブランカをみていきます。

カサブランカの定義は Africa/Casablanca で以下の場所となります。

https://github.com/eggert/tz/blob/2019c/africa#L1086-L1091

```
# Zone	NAME		STDOFF	RULES	FORMAT	[UNTIL]
Zone Africa/Casablanca	-0:30:20 -	LMT	1913 Oct 26
			 0:00	Morocco	+00/+01	1984 Mar 16
			 1:00	-	+01	1986
			 0:00	Morocco	+00/+01	2018 Oct 28  3:00
			 1:00	Morocco	+01/+00
```

コメントを除いて4行目は2018年10月28日までは、標準時は0時で、後述する Morocco というルールにしたがっていたようです。
最後の行のオフセットは 1:00 であり、こちらも Morocco というルールにしたがっています。

FORMAT の「+00/+01」や「+01/+00」を同解釈するかはわかりませんでした。
通常時は「/」の左側で場合によっては右側になるという意味なのでしょうか？

それでは、Morocco のルールをみてみましょう。

https://github.com/eggert/tz/blob/2019c/africa#L897-L1080

```
# RULE	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
Rule	Morocco	1939	only	-	Sep	12	 0:00	1:00	-
Rule	Morocco	1939	only	-	Nov	19	 0:00	0	-
Rule	Morocco	1940	only	-	Feb	25	 0:00	1:00	-
Rule	Morocco	1945	only	-	Nov	18	 0:00	0	-
Rule	Morocco	1950	only	-	Jun	11	 0:00	1:00	-
Rule	Morocco	1950	only	-	Oct	29	 0:00	0	-
Rule	Morocco	1967	only	-	Jun	 3	12:00	1:00	-
Rule	Morocco	1967	only	-	Oct	 1	 0:00	0	-
Rule	Morocco	1974	only	-	Jun	24	 0:00	1:00	-
Rule	Morocco	1974	only	-	Sep	 1	 0:00	0	-
Rule	Morocco	1976	1977	-	May	 1	 0:00	1:00	-
Rule	Morocco	1976	only	-	Aug	 1	 0:00	0	-
Rule	Morocco	1977	only	-	Sep	28	 0:00	0	-
Rule	Morocco	1978	only	-	Jun	 1	 0:00	1:00	-
Rule	Morocco	1978	only	-	Aug	 4	 0:00	0	-
Rule	Morocco	2008	only	-	Jun	 1	 0:00	1:00	-
Rule	Morocco	2008	only	-	Sep	 1	 0:00	0	-
Rule	Morocco	2009	only	-	Jun	 1	 0:00	1:00	-
Rule	Morocco	2009	only	-	Aug	21	 0:00	0	-
Rule	Morocco	2010	only	-	May	 2	 0:00	1:00	-
Rule	Morocco	2010	only	-	Aug	 8	 0:00	0	-
Rule	Morocco	2011	only	-	Apr	 3	 0:00	1:00	-
Rule	Morocco	2011	only	-	Jul	31	 0:00	0	-
Rule	Morocco	2012	2013	-	Apr	lastSun	 2:00	1:00	-
Rule	Morocco	2012	only	-	Jul	20	 3:00	0	-
Rule	Morocco	2012	only	-	Aug	20	 2:00	1:00	-
Rule	Morocco	2012	only	-	Sep	30	 3:00	0	-
Rule	Morocco	2013	only	-	Jul	 7	 3:00	0	-
Rule	Morocco	2013	only	-	Aug	10	 2:00	1:00	-
Rule	Morocco	2013	2018	-	Oct	lastSun	 3:00	0	-
Rule	Morocco	2014	2018	-	Mar	lastSun	 2:00	1:00	-
Rule	Morocco	2014	only	-	Jun	28	 3:00	0	-
Rule	Morocco	2014	only	-	Aug	 2	 2:00	1:00	-
Rule	Morocco	2015	only	-	Jun	14	 3:00	0	-
Rule	Morocco	2015	only	-	Jul	19	 2:00	1:00	-
Rule	Morocco	2016	only	-	Jun	 5	 3:00	0	-
Rule	Morocco	2016	only	-	Jul	10	 2:00	1:00	-
Rule	Morocco	2017	only	-	May	21	 3:00	0	-
Rule	Morocco	2017	only	-	Jul	 2	 2:00	1:00	-
Rule	Morocco	2018	only	-	May	13	 3:00	0	-
Rule	Morocco	2018	only	-	Jun	17	 2:00	1:00	-
Rule	Morocco	2019	only	-	May	 5	 3:00	-1:00	-
Rule	Morocco	2019	only	-	Jun	 9	 2:00	0	-
Rule	Morocco	2020	only	-	Apr	19	 3:00	-1:00	-
Rule	Morocco	2020	only	-	May	24	 2:00	0	-
Rule	Morocco	2021	only	-	Apr	11	 3:00	-1:00	-
Rule	Morocco	2021	only	-	May	16	 2:00	0	-
Rule	Morocco	2022	only	-	Mar	27	 3:00	-1:00	-
Rule	Morocco	2022	only	-	May	 8	 2:00	0	-
Rule	Morocco	2023	only	-	Mar	19	 3:00	-1:00	-
Rule	Morocco	2023	only	-	Apr	23	 2:00	0	-
Rule	Morocco	2024	only	-	Mar	10	 3:00	-1:00	-
Rule	Morocco	2024	only	-	Apr	14	 2:00	0	-
Rule	Morocco	2025	only	-	Feb	23	 3:00	-1:00	-
Rule	Morocco	2025	only	-	Apr	 6	 2:00	0	-
Rule	Morocco	2026	only	-	Feb	15	 3:00	-1:00	-
Rule	Morocco	2026	only	-	Mar	22	 2:00	0	-
Rule	Morocco	2027	only	-	Feb	 7	 3:00	-1:00	-
Rule	Morocco	2027	only	-	Mar	14	 2:00	0	-
Rule	Morocco	2028	only	-	Jan	23	 3:00	-1:00	-
Rule	Morocco	2028	only	-	Feb	27	 2:00	0	-
Rule	Morocco	2029	only	-	Jan	14	 3:00	-1:00	-
Rule	Morocco	2029	only	-	Feb	18	 2:00	0	-
Rule	Morocco	2029	only	-	Dec	30	 3:00	-1:00	-
Rule	Morocco	2030	only	-	Feb	10	 2:00	0	-
Rule	Morocco	2030	only	-	Dec	22	 3:00	-1:00	-
Rule	Morocco	2031	only	-	Jan	26	 2:00	0	-
Rule	Morocco	2031	only	-	Dec	14	 3:00	-1:00	-
Rule	Morocco	2032	only	-	Jan	18	 2:00	0	-
Rule	Morocco	2032	only	-	Nov	28	 3:00	-1:00	-
Rule	Morocco	2033	only	-	Jan	 9	 2:00	0	-
Rule	Morocco	2033	only	-	Nov	20	 3:00	-1:00	-
Rule	Morocco	2033	only	-	Dec	25	 2:00	0	-
Rule	Morocco	2034	only	-	Nov	 5	 3:00	-1:00	-
Rule	Morocco	2034	only	-	Dec	17	 2:00	0	-
Rule	Morocco	2035	only	-	Oct	28	 3:00	-1:00	-
Rule	Morocco	2035	only	-	Dec	 2	 2:00	0	-
Rule	Morocco	2036	only	-	Oct	19	 3:00	-1:00	-
Rule	Morocco	2036	only	-	Nov	23	 2:00	0	-
Rule	Morocco	2037	only	-	Oct	 4	 3:00	-1:00	-
Rule	Morocco	2037	only	-	Nov	15	 2:00	0	-
Rule	Morocco	2038	only	-	Sep	26	 3:00	-1:00	-
Rule	Morocco	2038	only	-	Oct	31	 2:00	0	-
Rule	Morocco	2039	only	-	Sep	18	 3:00	-1:00	-
Rule	Morocco	2039	only	-	Oct	23	 2:00	0	-
Rule	Morocco	2040	only	-	Sep	 2	 3:00	-1:00	-
Rule	Morocco	2040	only	-	Oct	14	 2:00	0	-
Rule	Morocco	2041	only	-	Aug	25	 3:00	-1:00	-
Rule	Morocco	2041	only	-	Sep	29	 2:00	0	-
Rule	Morocco	2042	only	-	Aug	10	 3:00	-1:00	-
Rule	Morocco	2042	only	-	Sep	21	 2:00	0	-
Rule	Morocco	2043	only	-	Aug	 2	 3:00	-1:00	-
Rule	Morocco	2043	only	-	Sep	 6	 2:00	0	-
Rule	Morocco	2044	only	-	Jul	24	 3:00	-1:00	-
Rule	Morocco	2044	only	-	Aug	28	 2:00	0	-
Rule	Morocco	2045	only	-	Jul	 9	 3:00	-1:00	-
Rule	Morocco	2045	only	-	Aug	20	 2:00	0	-
Rule	Morocco	2046	only	-	Jul	 1	 3:00	-1:00	-
Rule	Morocco	2046	only	-	Aug	 5	 2:00	0	-
Rule	Morocco	2047	only	-	Jun	23	 3:00	-1:00	-
Rule	Morocco	2047	only	-	Jul	28	 2:00	0	-
Rule	Morocco	2048	only	-	Jun	 7	 3:00	-1:00	-
Rule	Morocco	2048	only	-	Jul	19	 2:00	0	-
Rule	Morocco	2049	only	-	May	30	 3:00	-1:00	-
Rule	Morocco	2049	only	-	Jul	 4	 2:00	0	-
Rule	Morocco	2050	only	-	May	15	 3:00	-1:00	-
Rule	Morocco	2050	only	-	Jun	26	 2:00	0	-
Rule	Morocco	2051	only	-	May	 7	 3:00	-1:00	-
Rule	Morocco	2051	only	-	Jun	11	 2:00	0	-
Rule	Morocco	2052	only	-	Apr	28	 3:00	-1:00	-
Rule	Morocco	2052	only	-	Jun	 2	 2:00	0	-
Rule	Morocco	2053	only	-	Apr	13	 3:00	-1:00	-
Rule	Morocco	2053	only	-	May	25	 2:00	0	-
Rule	Morocco	2054	only	-	Apr	 5	 3:00	-1:00	-
Rule	Morocco	2054	only	-	May	10	 2:00	0	-
Rule	Morocco	2055	only	-	Mar	28	 3:00	-1:00	-
Rule	Morocco	2055	only	-	May	 2	 2:00	0	-
Rule	Morocco	2056	only	-	Mar	12	 3:00	-1:00	-
Rule	Morocco	2056	only	-	Apr	23	 2:00	0	-
Rule	Morocco	2057	only	-	Mar	 4	 3:00	-1:00	-
Rule	Morocco	2057	only	-	Apr	 8	 2:00	0	-
Rule	Morocco	2058	only	-	Feb	17	 3:00	-1:00	-
Rule	Morocco	2058	only	-	Mar	31	 2:00	0	-
Rule	Morocco	2059	only	-	Feb	 9	 3:00	-1:00	-
Rule	Morocco	2059	only	-	Mar	16	 2:00	0	-
Rule	Morocco	2060	only	-	Feb	 1	 3:00	-1:00	-
Rule	Morocco	2060	only	-	Mar	 7	 2:00	0	-
Rule	Morocco	2061	only	-	Jan	16	 3:00	-1:00	-
Rule	Morocco	2061	only	-	Feb	27	 2:00	0	-
Rule	Morocco	2062	only	-	Jan	 8	 3:00	-1:00	-
Rule	Morocco	2062	only	-	Feb	12	 2:00	0	-
Rule	Morocco	2062	only	-	Dec	31	 3:00	-1:00	-
Rule	Morocco	2063	only	-	Feb	 4	 2:00	0	-
Rule	Morocco	2063	only	-	Dec	16	 3:00	-1:00	-
Rule	Morocco	2064	only	-	Jan	20	 2:00	0	-
Rule	Morocco	2064	only	-	Dec	 7	 3:00	-1:00	-
Rule	Morocco	2065	only	-	Jan	11	 2:00	0	-
Rule	Morocco	2065	only	-	Nov	22	 3:00	-1:00	-
Rule	Morocco	2066	only	-	Jan	 3	 2:00	0	-
Rule	Morocco	2066	only	-	Nov	14	 3:00	-1:00	-
Rule	Morocco	2066	only	-	Dec	19	 2:00	0	-
Rule	Morocco	2067	only	-	Nov	 6	 3:00	-1:00	-
Rule	Morocco	2067	only	-	Dec	11	 2:00	0	-
Rule	Morocco	2068	only	-	Oct	21	 3:00	-1:00	-
Rule	Morocco	2068	only	-	Dec	 2	 2:00	0	-
Rule	Morocco	2069	only	-	Oct	13	 3:00	-1:00	-
Rule	Morocco	2069	only	-	Nov	17	 2:00	0	-
Rule	Morocco	2070	only	-	Oct	 5	 3:00	-1:00	-
Rule	Morocco	2070	only	-	Nov	 9	 2:00	0	-
Rule	Morocco	2071	only	-	Sep	20	 3:00	-1:00	-
Rule	Morocco	2071	only	-	Oct	25	 2:00	0	-
Rule	Morocco	2072	only	-	Sep	11	 3:00	-1:00	-
Rule	Morocco	2072	only	-	Oct	16	 2:00	0	-
Rule	Morocco	2073	only	-	Aug	27	 3:00	-1:00	-
Rule	Morocco	2073	only	-	Oct	 8	 2:00	0	-
Rule	Morocco	2074	only	-	Aug	19	 3:00	-1:00	-
Rule	Morocco	2074	only	-	Sep	23	 2:00	0	-
Rule	Morocco	2075	only	-	Aug	11	 3:00	-1:00	-
Rule	Morocco	2075	only	-	Sep	15	 2:00	0	-
Rule	Morocco	2076	only	-	Jul	26	 3:00	-1:00	-
Rule	Morocco	2076	only	-	Sep	 6	 2:00	0	-
Rule	Morocco	2077	only	-	Jul	18	 3:00	-1:00	-
Rule	Morocco	2077	only	-	Aug	22	 2:00	0	-
Rule	Morocco	2078	only	-	Jul	10	 3:00	-1:00	-
Rule	Morocco	2078	only	-	Aug	14	 2:00	0	-
Rule	Morocco	2079	only	-	Jun	25	 3:00	-1:00	-
Rule	Morocco	2079	only	-	Jul	30	 2:00	0	-
Rule	Morocco	2080	only	-	Jun	16	 3:00	-1:00	-
Rule	Morocco	2080	only	-	Jul	21	 2:00	0	-
Rule	Morocco	2081	only	-	Jun	 1	 3:00	-1:00	-
Rule	Morocco	2081	only	-	Jul	13	 2:00	0	-
Rule	Morocco	2082	only	-	May	24	 3:00	-1:00	-
Rule	Morocco	2082	only	-	Jun	28	 2:00	0	-
Rule	Morocco	2083	only	-	May	16	 3:00	-1:00	-
Rule	Morocco	2083	only	-	Jun	20	 2:00	0	-
Rule	Morocco	2084	only	-	Apr	30	 3:00	-1:00	-
Rule	Morocco	2084	only	-	Jun	11	 2:00	0	-
Rule	Morocco	2085	only	-	Apr	22	 3:00	-1:00	-
Rule	Morocco	2085	only	-	May	27	 2:00	0	-
Rule	Morocco	2086	only	-	Apr	14	 3:00	-1:00	-
Rule	Morocco	2086	only	-	May	19	 2:00	0	-
Rule	Morocco	2087	only	-	Mar	30	 3:00	-1:00	-
Rule	Morocco	2087	only	-	May	 4	 2:00	0	-
```

ルールに規則性がないようなので1年ごとに定義されているようですね。
2017年以降から今現在までの部分を読んでみましょう。

```
Rule	Morocco	2013	2018	-	Oct	lastSun	 3:00	0	-
Rule	Morocco	2014	2018	-	Mar	lastSun	 2:00	1:00	-
(略)
Rule	Morocco	2017	only	-	May	21	 3:00	0	-
Rule	Morocco	2017	only	-	Jul	 2	 2:00	1:00	-
Rule	Morocco	2018	only	-	May	13	 3:00	0	-
Rule	Morocco	2018	only	-	Jun	17	 2:00	1:00	-
Rule	Morocco	2019	only	-	May	 5	 3:00	-1:00	-
Rule	Morocco	2019	only	-	Jun	 9	 2:00	0	-
```

2013年から2018年まで「Morocco」のルールは、10月の最終日曜の3時からは標準時が定義されているようです。
2014年から2018年までは、3月の最終日曜の2時からは標準時より1時間加算されるようです。
2017年は、5月21日 3時からは標準時が定義されているようです。
2017年は、7月2日 2時からは標準時に1時間加算されるようです。
2018年は、5月13日 3時からは標準時が定義されているようです。
2018年は、6月17日 2時からは標準時に1時間加算されるようです。
2019年は、5月5日 3時からは標準時から1時間減算されるようです。
2019年は、6月9日 2時からは標準時が定義されるようです。

2016年以降に当てはまる前述の Zone の定義も再度貼ります。

```
# Zone	NAME		STDOFF	RULES	FORMAT	[UNTIL]
Zone Africa/Casablanca	 (略)
                         (略)
			 0:00	Morocco	+00/+01	2018 Oct 28  3:00
			 1:00	Morocco	+01/+00
```

これらの情報を考慮すると、2017年〜2019年は以下のような移り変わりなのかなと考えられます。

2018年10月28日の3時までは標準時は UTC+0 # Zone の定義
2016年10月最終日曜の3時から標準時になるので UTC+0 に変わる # 標準時開始
2017年3月最終日曜の2時から標準時+1になるので UTC+1 に変わる # サマータイム開始
2017年5月21日の3時から標準時になるので UTC+0 に変わる # ラマダン開始
2017年7月2日の2時から標準時+1になるので UTC+1 に変わる # ラマダン終了
2017年10月最終日曜の3時から標準時になるので UTC+0 に変わる # 標準時開始
2018年3月最終日曜の2時から標準時+1になるので UTC+1 に変わる # サマータイム開始
2018年5月13日の3時から標準時になるので UTC+0 に変わる # ラマダン開始
2018年6月17日の2時から標準時+1になるので UTC+1 に変わる # ラマダン終了
2018年10月28日の3時から標準時を UTC+1 に変更 # Zone の定義
2018年10月の最終日曜(10/28)の3時から標準時になるので UTC+1 で継続 # サマータイム継続
2019年5月5日の3時から標準時-1になるので UTC+0 に変わる # ラマダン開始
2019年6月9日の2時から標準時になるので UTC+1 に変わる # ラマダン終了

## まとめ

tz database の案内と実施手順は以上となります。

tz database のリリースノートは [NEWS](https://github.com/eggert/tz/blob/master/NEWS) ファイルに記載されています。
これを定期的に読んでいくことで、世界でタイムゾーンがどのように変更されているかを追うことができます。

これを機に tz database に興味をもった方がいれば、ぜひ NEWS ファイルやいろいろな地域のタイムゾーン情報を読んでいただけると幸いです。