Windows とGNU/Linux で時刻がずれる: コンピューターの2つの時間

Windows とGNU/Linux など、*nix 環境とを導入したら、それぞれの時計が9時間違う時刻を差した
ことがあったので、そのときの対処をちょっとした備忘録代わりに書き残しておきます。

この文章を最後まで読めば分かりますが、この対処法は恐らくUbuntu 16.04 LTS、Debian GNU/Linux 9 など、Systemd を採用した (GNU/)Linux ディストリビューション全般に適用できるかと思います。

症状

筆者が今利用しているPC には、元々Windows 10 という不自由なOS が導入されていた。そこで、Arch Linux をデュアルブートで導入した。

$ date # 現在の時刻を表示する

などと入力してみると、Windows 上と異なり時間が9時間進んでいた。

対処法

端末を開き、以下 $ に続くいくつかのコマンドを実行すればよい。timedatectl は Systemd に付随するコマンドだから、Systemd を採用した(GNU/)Linux ディストリビューション全般におそらく適用できる。

$ sudo timedatectl set-timezone Asia/Tokyo # タイムゾーンを設定
$ sudo timedatectl set-time "2018-04-17 21:21:30" # 日本時間で時刻を設定
$ timedatectl
# タイムゾーンが Asia/Tokyo であること、Local Time が意図した通りになっていることを確認
$ sudo timedatectl set-local-rtc 1
# ハードウエア時刻が日本時刻に設定される
$ sudo hwclock
$ timedatectl
# ハードウエア時刻 (hwclock) とソフトウエア時刻 (timedatectl)が
# 両方とも正しく設定されていることを確認できる

なお、時刻を設定する際には、NICT のサイトにある日本標準時をリアルタイムに更新するサービス JST Clock を利用するとよいかもしれない。

なぜこれで直るのか

こういう困ったときは、焦らず一歩一歩怪しい部分を確認していくのが良い、それは確かだが、筆者のようなLinux を基礎知識程度で使っている身には、どこから手をつければよいのか分からない。
そこで、有志により整備され日本語に多くが翻訳された、(GNU/)Linux についての多彩な情報が集積された、Arch Linux の公式Wiki に該当するものがないか確認するのもよい。

実際に探してみると、「時刻」 というページがあり、詳細に状況が述べられていることに気づいた。(本当によく整備されていて、ありがたい。) Arch Linux Wiki の記事、特に「2. 時刻系」の節を読めば、これらのコマンドの意図は把握できると思う。軽く説明を加えておく。

システム内にある時刻にはハードウエア時刻とソフトウエア時刻の2種類があり、ハードウエア時刻は概ねBIOS で、ソフトウエア時刻はOS で管理されている。(電源を切っている際も時計が進むのかなど、細かい話は省くが。)

それら2つの時間は、一方で同じように時刻を刻むが、ハードウエア時刻には「標準時間帯」の概念が導入されておらず、どの標準時間帯にその時刻が属しているのかを記録できない。
ソフトウエア時刻をハードウエア時刻から定める (実はOS によってはこれが起動時に行なわれたりする) 際には、ハードウエア時刻に標準時間帯を考慮して定める。このときに、仕様のずれがあり、Windows では日本標準時を、Linux では協定世界時がハードウエア時刻に設定されている、と想定している。

さて、元々Windows がある環境に今回Linux 環境を導入したことを考えると、Linux は日本標準時のハードウエア時刻を協定世界時だと思い込んで、ソフトウエア時刻を定めたので、9時間進んだ、というわけである。それなら、新しい時刻を設定した上で、ハードウエア時刻を日本標準時だと思わせるようにすれば問題なくなる。その発想により考えたのが、上に述べた対処法である。

ちなみに、時刻を再設定しなくとも、 hwclock --localtime --hctosys などとすることで、これらのずれを是正することもできるが、詳細は省く。

設定後、 timedatectl コマンドを実行すると、以下のように警告が表示される。

Warning: The system is configured to read the RTC time in the local time zone.
This mode cannot be fully supported. It will create various problems
with time zone changes and daylight saving time adjustments. The RTC
time is never updated, it relies on external facilities to maintain it.
If at all possible, use RTC in UTC by calling
‘timedatectl set-local-rtc 0’.

その文章に書かれている通りであるが、協定世界時でない時間をハードウエア時刻に設定してしまうと、夏時間がある標準時間帯では問題が生じるのは想像に難くない。そのためか、Arch Linux Wiki ではWindows 側のレジストリを編集し、Windows がUTC をハードウエア時刻として利用するように変更させる方法を推奨している。

今回筆者がLinux 側の設定を変更することにしたのは、日本標準時に夏時間の概念がないことと、Windows 側で問題が発生するとLinux 側と比べ対処が難しいのでは、という考えによるものである。

以上、手抜き (執筆所要時間40分) の乱文でした。

もし実際に試して問題などあれば、コメントなど残していただければと思います。