はじめに
Linuxで日時設定を行う場合、dateコマンドで以下のように行うと思います。
# date --set "2015/11/25 9:14:58"
しかし、サーバ(あるいは端末)をの電源断・再投入や、再起動を行うと、日付が数時間ずれる、1日あるいはそれ以上ずれる等、予期しない結果が生じる場合があります。
原因
Linuxでは、日時情報として「Local time」「Universal time」「RTC time」の3種類が管理されています。これはtimedatectlコマンドで確認することが出来ます。
# timedatectl
Local time: 水 2015-11-25 09:23:38 JST
Universal time: 水 2015-11-25 00:23:38 UTC
RTC time: 木 2015-11-26 00:29:58
Timezone: Asia/Tokyo (JST, +0900)
NTP enabled: yes
NTP synchronized: no
RTC in local TZ: no
DST active: n/a
「Local time」は現地時刻、「Universal time」は世界標準時で、これらはシステムクロックと云われます。「RTC time」は、ハードウェアが持つ日時情報で、これはリアルタイムクロックと云われます。BIOS/UEFIで設定可能な日時情報と「RTC time」は同じものです。
うち、dateコマンドで反映されるのは「Local time」と「Universal time」の2つです。(正しくは、設定値が反映されるのは「Local time」で、「Universal time」は「Local time」の時差に合わせて結果が出力されるものです)
「RTC time」はdateコマンドで日時設定を行っても、その設定値が反映されません。また、NTPによる日時補正についても同様(「Local time」しか補正されない)となります。
対応
最もシンプルな方法は、BIOS/UEFIで日時を設定することです。しかし、既にLinuxが起動していて、再起動が難しい場合は、hwclockコマンドで「RTC time」を設定することができます。
dateコマンドで日時を設定した後に、hwclock --systohcを実行すると、「Local time」と「RTC time」が同期されます。
# date --set "2015/11/25 9:28:20"
# hwclock --systohc
上記実行後、timedatectlコマンドを実行すると、「Localtime」と「RTC time」が同期されていることがわかります。
# timedatectl
Local time: 水 2015-11-25 09:28:26 JST
Universal time: 水 2015-11-25 00:28:26 UTC
RTC time: 水 2015-11-25 00:28:26
Timezone: Asia/Tokyo (JST, +0900)
NTP enabled: yes
NTP synchronized: no
RTC in local TZ: no
DST active: n/a
なお、NTPによる日時補正は、前述の通り「Local time」しか反映されませんので、「RTC time」の日時ずれが生じた際は、上記コマンドを実行する必要があります。1週間〜1ヶ月に1回程度cronで上記コマンドを定期的に実行するのが良いでしょう。