「システム時刻」の版間の差分

提供: ArchWiki
ナビゲーションに移動 検索に移動
(→‎時間標準: fix link)
(小改動)
 
(3人の利用者による、間の32版が非表示)
8行目: 8行目:
 
[[zh-hant:System time]]
 
[[zh-hant:System time]]
 
{{Related articles start}}
 
{{Related articles start}}
  +
{{Related|ネットワークタイムプロトコルデーモン}}
{{Related|Network Time Protocol daemon}}
 
 
{{Related|OpenNTPD}}
 
{{Related|OpenNTPD}}
 
{{Related|Chrony}}
 
{{Related|Chrony}}
22行目: 22行目:
 
* シャットダウン時にシステム クロックからハードウェア クロックを設定します。
 
* シャットダウン時にシステム クロックからハードウェア クロックを設定します。
   
== ハードウェアクロックとシステムクロック ==
+
== ハードウェアクロック ==
   
  +
'''ハードウェアクロック''' (又の名をリアルタイムクロック (Real Time Clock, RTC) もしくは CMOS クロック) は次の値を保存しています: 年・月・日・時・分・秒。2016 年以降の[[UEFI]] ファームウェアには、タイムゾーンとサマータイムを保存する機能を備えられています。
コンピューターは2つの時計を持っていることを考慮しなくてはなりません: "ハードウェアクロック" と "システム(ソフトウェア)クロック" です。
 
   
  +
=== ハードウェアクロックの読み込み ===
'''ハードウェアクロック''' (又の名をリアルタイムクロック (Real Time Clock, RTC) もしくは CMOS クロック) は次の値を保存しています: 年・月・日・時・分・秒。時刻系 (localtime か UTC) や夏時間が使われているかどうかの情報を保存することはできません。
 
  +
  +
# hwclock --show
  +
  +
=== システムクロックからハードウェアクロックを設定する ===
  +
  +
以下は、システムクロックからハードウェアクロックを設定するものです。さらに、{{ic|/etc/adjtime}} を更新するか、存在しない場合は作成します。このファイルに関するより詳しい情報は [[#タイムスキュー]] の項と同様に {{man|8|hwclock|The Adjtime File}} を参照してください。
  +
  +
# hwclock --systohc
  +
  +
== システムクロック ==
   
 
'''システムクロック''' (又の名をソフトウェアクロック) は次の情報を記録しています: 時刻、タイムゾーン、そして DST が適用されるかどうか。Linux カーネルは1970年1月1日の午前0時からの秒数でシステムクロックをはじき出します。システムクロックの初期値は {{ic|/etc/adjtime}} を使ってハードウェアクロックから算定されます。起動が完了した後は、システムクロックはハードウェアクロックとは独立して動作します。Linux カーネルはタイマー割り込みを数えることによりシステムクロックを記録します。
 
'''システムクロック''' (又の名をソフトウェアクロック) は次の情報を記録しています: 時刻、タイムゾーン、そして DST が適用されるかどうか。Linux カーネルは1970年1月1日の午前0時からの秒数でシステムクロックをはじき出します。システムクロックの初期値は {{ic|/etc/adjtime}} を使ってハードウェアクロックから算定されます。起動が完了した後は、システムクロックはハードウェアクロックとは独立して動作します。Linux カーネルはタイマー割り込みを数えることによりシステムクロックを記録します。
32行目: 42行目:
 
=== 時刻を表示する ===
 
=== 時刻を表示する ===
   
現在のシステム時刻を確認するには (UTC と地時どちらも表示されます):
+
現在のシステム時刻を確認するには (UTC と地時間のどちらも表示されます):
   
 
$ timedatectl status
 
$ timedatectl status
60行目: 70行目:
 
ハードウェアクロック (CMOS クロック, BIOS で表示される時間) で使われる時刻系はオペレーティングシステムによって定義されます。デフォルトでは、Windows は localtime を使いますが、Mac OS は UTC を使っていて、UNIX ライクなオペレーティングシステムでは決まっていません。一般的に、UTC を使う OS は起動時に CMOS (ハードウェアクロック) の時間を UTC 時間 (GMT, Greenwich time) だと認識して、あなたのタイムゾーンによってその時間を調整してシステム時刻を設定します。
 
ハードウェアクロック (CMOS クロック, BIOS で表示される時間) で使われる時刻系はオペレーティングシステムによって定義されます。デフォルトでは、Windows は localtime を使いますが、Mac OS は UTC を使っていて、UNIX ライクなオペレーティングシステムでは決まっていません。一般的に、UTC を使う OS は起動時に CMOS (ハードウェアクロック) の時間を UTC 時間 (GMT, Greenwich time) だと認識して、あなたのタイムゾーンによってその時間を調整してシステム時刻を設定します。
   
Linux を使う時はハードウェアクロックを UTC 時刻系に設定するのが有益です。Linux でハードウェアクロックを UTC で定義すれば夏時間が自動的使わます。地方時系を使う場合、システム刻は DST によってわらなくなり他のオペレーティングシステムが DST の切り替え引き受けことになります (そ NTP は動作しせん)
+
複数のオペレーティングシステムがマシンにインストールされている場合、それらすべて同じハードウェアクロックから現在の時刻取得します。システム間の競合を避けるために、UTC に設定することをお勧めします。それ以外の場合、ハードウェアクロックが「現地時間設定さている場合、たとえば [[Wikipedia:ja:夏間|DST]] 更後に複数のオペレーティングシステムがそれ調整す可能性があ、その結果、過剰な修正が行われます。異なるタイムゾーン間を移動、オペレーティング システムの 1 つを使用してシステム/ハドウア クロックをリセッするときにも、問題が発生する可能性があり
   
ハードウェアクロックの時刻系の設定はコマンドラインから可能す。Arch Linux をインストールした時にあなたがどちらを設定したのか確認るには:
+
ハードウェアクロックは、{{ic|timedatectl}} コマンドで照会および設定ができま
  +
以下を使用して、Arch システムの現在のハードウェアクロック時間標準を確認できます。
  +
  +
{{hc|$ timedatectl {{!}} grep local|
  +
RTC in local TZ: no
  +
}}
   
$ timedatectl status | grep local
 
   
 
ハードウェアクロックは {{ic|timedatectl}} コマンドで尋ねたり設定できます。ハードウェアクロックの時刻系を localtime に変更するには次を実行してください:
 
ハードウェアクロックは {{ic|timedatectl}} コマンドで尋ねたり設定できます。ハードウェアクロックの時刻系を localtime に変更するには次を実行してください:
70行目: 84行目:
 
# timedatectl set-local-rtc true
 
# timedatectl set-local-rtc true
   
逆に時刻系を UTC設定するには次を実行してください:
+
ハードウェアクロックの時刻系を localtime変更するには次を実行してください:
   
# timedatectl set-local-rtc false
+
# timedatectl set-local-rtc '''1'''
   
  +
逆にハードウェアクロックの時刻系を UTC に戻すには次を実行してください:
ハードウェアクロック (RTC) を localtime に設定すると、夏時間の扱いで問題が生じるので注意してください。コンピュータの電源が切られている時に夏時間が変わると、次の起動時に時計がおかしくなります (詳しくは [http://www.cl.cam.ac.uk/~mgk25/mswish/ut-rtc.html ここ] を見て下さい)。最近のカーネルでは起動時にシステム時刻を直接 RTC からセットしますが、その際カーネルは RTC を UTC としてみなします。RTC が localtime だった場合、起動時に毎回システム時刻は間違って設定され、その後修正されることになります。これは予期せぬバグを引き起こす温床になりかねません (時計の針が戻るのは良いことばかりではないのです)。
 
   
  +
# timedatectl set-local-rtc '''0'''
上のコマンドで {{ic|/etc/adjtime}} が自動的に設定されます; 他の設定は必要ありません。
 
  +
  +
これらは {{ic|/etc/adjtime}} を自動的に生成し、それに応じて RTC を更新します。これ以上の設定は必要ありません。
   
 
カーネルの起動中、RTC ドライバーがロードされた時点で、ハードウェアクロックからシステムクロックを設定することができます。設定するかどうかはハードウェアプラットフォーム、カーネルのバージョン・ビルドオプション次第です。設定される場合、ブートシーケンスで既に、ハードウェアクロックは UTC と認識され {{ic|/sys/class/rtc/rtcN/hctosys}} (N=0,1,2,..) の値は 1 に設定されます。その後、{{ic|/etc/adjtime}} の値を使って、再度 systemd によってハードウェアクロックからシステムクロックが設定されます。そのため、ハードウェアクロックで localtime を使っているとブートシーケンス中に予期しない動作が発生するかもしれません。例えば、システム時刻が後戻りするなど。従ってこの設定は良いアイデアとは言えません。
 
カーネルの起動中、RTC ドライバーがロードされた時点で、ハードウェアクロックからシステムクロックを設定することができます。設定するかどうかはハードウェアプラットフォーム、カーネルのバージョン・ビルドオプション次第です。設定される場合、ブートシーケンスで既に、ハードウェアクロックは UTC と認識され {{ic|/sys/class/rtc/rtcN/hctosys}} (N=0,1,2,..) の値は 1 に設定されます。その後、{{ic|/etc/adjtime}} の値を使って、再度 systemd によってハードウェアクロックからシステムクロックが設定されます。そのため、ハードウェアクロックで localtime を使っているとブートシーケンス中に予期しない動作が発生するかもしれません。例えば、システム時刻が後戻りするなど。従ってこの設定は良いアイデアとは言えません。
  +
  +
その後、{{ic|/etc/adjtime}} の値に応じて、systemd によってハードウェアクロックからシステムクロックが再度設定されます。したがって、ハードウェアクロックで localtime を使用すると、ブートシーケンス中に予期しない動作が発生する可能性があります。たとえば、システム時間が逆行することは、常に悪い考えです ([https://www.cl.cam.ac.uk/~mgk25/mswish/ut-rtc.html 他にもたくさんあります])。ハードウェアクロックが UTC に設定されていてローカルタイムゾーンについてカーネルに通知しないでください。その結果、Linux システムが使用する FAT ファイルシステムのタイムスタンプは UTC になります。
  +
 
{{Note|
 
{{Note|
* {{ic|timedatectl}} を使うには dbus が有効になっている必要があります。そのため、(インストール中など) chroot 下でこのコマンドが使えないかもしれません。そのような場合には、hwclock コマンドを使って下さい。
+
* {{ic|timedatectl}} を使うには [[D-Bus]] が有効になっている必要があります。そのため、(インストール中など) chroot 下でこのコマンドが使えないかもしれません。そのような場合には、hwclock コマンドを使って下さい。
 
* {{ic|/etc/adjtime}} が存在しない場合、[[systemd]] はハードウェアクロックが UTC に設定されていると認識しています。}}
 
* {{ic|/etc/adjtime}} が存在しない場合、[[systemd]] はハードウェアクロックが UTC に設定されていると認識しています。}}
   
116行目: 135行目:
   
 
Ubuntu とその派生ディストリはインストール時に Windows が認識されたときにハードウェアクロックを "localtime" と認識されるように設定します。Linux 初心者が Windows コンピュータで Ubuntu を試したときにレジストリを編集しなくてもよいように故意にこのような挙動となっています。
 
Ubuntu とその派生ディストリはインストール時に Windows が認識されたときにハードウェアクロックを "localtime" と認識されるように設定します。Linux 初心者が Windows コンピュータで Ubuntu を試したときにレジストリを編集しなくてもよいように故意にこのような挙動となっています。
 
== 時間標準 ==
 
 
2 つの時間標準があります: '''現地時間''' と [[Wikipedia:ja:協定世界時|協定世界時]] ('''UTC''')。現地時間標準は現在の「タイムゾーン」に依存しますが、UTC は「グローバル」標準時間であり、タイムゾーンの値とは無関係です。概念的には異なりますが、UTC は GMT (グリニッジ標準時) としても知られています。
 
 
ハードウェアクロック (CMOS クロック、BIOS 時間) で使用される時間標準は、オペレーティングシステムによって設定されます。デフォルトでは、Windows は現地時間を使用し、macOS は UTC を使用します。その他の UNIX および UNIX ライクなシステムはさまざまです。UTC 標準を使用する OS は、通常、ハードウェア クロックを UTC と見なし、それを調整して、タイムゾーンに従って起動時に OS 時刻を設定します。
 
 
複数のオペレーティングシステムがマシンにインストールされている場合、それらはすべて同じハードウェアクロックから現在の時刻を取得します。システム間の競合を避けるために、UTC に設定することをお勧めします。それ以外の場合、ハードウェアクロックが「現地時間」に設定されている場合、たとえば [[Wikipedia:ja:夏時間|DST]] の変更後に複数のオペレーティングシステムがそれを調整する可能性があり、その結果、過剰な修正が行われます。異なるタイムゾーン間を移動し、オペレーティング システムの 1 つを使用してシステム/ハードウェア クロックをリセットするときにも、問題が発生する可能性があります。
 
 
ハードウェアクロックは、{{ic|timedatectl}} コマンドで照会および設定ができます。
 
以下を使用して、Arch システムの現在のハードウェアクロック時間標準を確認できます。
 
 
{{hc|$ timedatectl {{!}} grep local|
 
RTC in local TZ: no
 
}}
 
 
ハードウェアクロックの時間標準を現地時間に変更するには、次を使用します。
 
 
# timedatectl set-local-rtc '''1'''
 
 
ハードウェアクロックを UTC に戻すには、次のように入力します。
 
 
# timedatectl set-local-rtc '''0'''
 
 
これらは {{ic|/etc/adjtime}} を自動的に生成し、それに応じて RTC を更新します。これ以上の設定は必要ありません。
 
 
カーネルの起動中、RTC ドライバーが読み込まれる時点で、システムクロックがハードウェアクロックから設定される場合があります。これが発生するかどうかは、ハードウェアプラットフォーム、カーネルのバージョン、およびカーネル ビルド オプションによって異なります。これが発生した場合、ブートシーケンスのこの時点で、ハードウェアクロックの時刻は UTC であると想定され、{{ic|/sys/class/rtc/rtc''N''/hctosys}} (N= 0,1,2,..) は 1 に設定されます。
 
 
その後、{{ic|/etc/adjtime}} の値に応じて、systemd によってハードウェアクロックからシステムクロックが再度設定されます。したがって、ハードウェアクロックで現地時間を使用すると、ブートシーケンス中に予期しない動作が発生する可能性があります。たとえば、システム時間が逆行することは、常に悪い考えです ([https://www.cl.cam.ac.uk/~mgk25/mswish/ut-rtc.html 他にもたくさんあります])。ハードウェアクロックが UTC に設定されていてローカルタイムゾーンについてカーネルに通知しないでください。その結果、Linux システムが使用する FAT ファイルシステムのタイムスタンプは UTC になります。
 
 
{{Note|
 
* {{ic|timedatectl}} の使用には、アクティブな [[D-Bus]] が必要です。そのため、[[chroot]] の下 (インストール中など) ではこのコマンドを使用できない場合があります。このような場合、hwclock コマンドに戻すか、chroot の代わりに [[systemd-nspawn]] を使用できます。
 
* {{ic|/etc/adjtime}} が存在しない場合、[[systemd]] はハードウェアクロックが UTC に設定されていると想定します。
 
}}
 
 
=== UTC in Microsoft Windows ===
 
 
To [[dual boot with Windows]], it is recommended to configure Windows to use UTC, rather than Linux to use localtime. (Windows by default uses localtime [https://devblogs.microsoft.com/oldnewthing/20040902-00/?p=37983].)
 
 
It can be done by a simple registry fix: Open {{ic|regedit}} and add a {{ic|DWORD}} value with hexadecimal value {{ic|1}} to the registry:
 
 
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation\RealTimeIsUniversal
 
 
You can do this from an Administrator Command Prompt running:
 
 
reg add "HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\TimeZoneInformation" /v RealTimeIsUniversal /d 1 /t REG_DWORD /f
 
 
Alternatively, create a {{ic|*.reg}} file (on the desktop) with the following content and double-click it to import it into registry:
 
 
Windows Registry Editor Version 5.00
 
 
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation]
 
"RealTimeIsUniversal"=dword:00000001
 
 
Should Windows ask to update the clock due to DST changes, let it. It will leave the clock in UTC as expected, only correcting the displayed time.
 
 
The [[#Hardware clock]] and [[#System clock]] time may need to be updated after setting this value.
 
 
If you are having issues with the offset of the time, try reinstalling {{Pkg|tzdata}} and then setting your time zone again:
 
 
# timedatectl set-timezone America/Los_Angeles
 
 
==== Historical notes ====
 
 
For ''really old'' Windows, the above method fails, due to Windows bugs. More precisely,
 
 
* For 64-bit versions of Windows 7 and older builds of Windows 10, there was a bug that made it necessary to have a {{ic|QWORD}} value with hexadecimal value of {{ic|1}} instead of a {{ic|DWORD}} value. This bug has been fixed in newer builds and now only {{ic|DWORD}} works.
 
* Before Vista SP2, there is a bug that resets the clock to ''localtime'' after resuming from the suspend/hibernation state.
 
* For XP and older, there is a bug related to the daylight saving time. See [https://mskb.pkisolutions.com/kb/2687252] for details.
 
* For ''even older'' versions of Windows, you might want to read https://www.cl.cam.ac.uk/~mgk25/mswish/ut-rtc.html - the functionality was not even documented nor officially supported then.
 
 
For these operating systems, it is recommended to use ''localtime''.
 
 
=== UTC in Ubuntu ===
 
 
Ubuntu and its derivatives have the hardware clock set to be interpreted as in "localtime" if Windows was detected on any disk during Ubuntu installation. This is apparently done deliberately to allow new Linux users to try out Ubuntu on their Windows computers without editing the registry.
 
 
For changing this behavior, see above.
 
   
 
== タイムゾーン ==
 
== タイムゾーン ==
233行目: 174行目:
   
 
また、{{aur|tzupdate}} ツールは IP アドレスの位置情報を元にタイムゾーンを自動設定します。
 
また、{{aur|tzupdate}} ツールは IP アドレスの位置情報を元にタイムゾーンを自動設定します。
  +
  +
==== NetworkManager がネットワークに接続するたびにタイムゾーンを更新する ====
  +
  +
[[NetworkManager# NetworkManager dispatcher を使用したネットワークサービス|NetworkManager dispatcher スクリプト]] を作成します:
  +
  +
{{hc|/etc/NetworkManager/dispatcher.d/09-timezone|
  +
#!/bin/sh
  +
case "$2" in
  +
up)
  +
timedatectl set-timezone "$(curl --fail <nowiki>https://ipapi.co/timezone</nowiki>)"
  +
;;
  +
esac
  +
}}
  +
  +
{{Tip|{{ic|up}} の代わりに {{ic|connectivity-change}} を使用すると、[[OpenConnect]] などのクライアントで VPN に接続するときにタイムゾーンの変更を防ぐことができます。}}
  +
  +
あるいは、ツール {{aur|tzupdate}} が IP アドレスのジオロケーションに基づいてタイムゾーンを自動的に設定します。この [https://medium.com/@ipdata_co/what-is-the-best-commercial-ip-geolocation-api-d8195cda7027 最も人気のある IP 地理位置情報 API の比較] は、プロダクションでどの API を使うか決める際に役に立つかもしれません。
   
 
== クロックスキュー ==
 
== クロックスキュー ==
252行目: 210行目:
 
[[Wikipedia:ja:Network Time Protocol|Network Time Protocol]] (NTP) はパケット交換でデータの遅延時間が不確定なネットワークを介してコンピュータシステムの時刻を同期するためのプロトコルです。NTP の実装は以下が存在します:
 
[[Wikipedia:ja:Network Time Protocol|Network Time Protocol]] (NTP) はパケット交換でデータの遅延時間が不確定なネットワークを介してコンピュータシステムの時刻を同期するためのプロトコルです。NTP の実装は以下が存在します:
   
  +
* {{App|[[Chrony]]|ローミングフレンドリーで、常時オンラインではないシステムのために特別に設計されたクライアントとサーバーです。ほとんどの場合、ntpd よりも速く、より参照に近い形で収束します。|https://chrony.tuxfamily.org/|{{Pkg|chrony}}}}
 
* {{App|[[Network Time Protocol daemon]]|プロトコルの[[Wikipedia:ja:リファレンス実装|リファレンス実装]]であり、特に時刻サーバーでの使用が推奨されます。NTPd は割り込みの周期や1秒辺りのティックの数を調整してシステムクロックのずれを減らすことも可能です。NTPd の実行中は11分ごとにハードウェアクロックの再同期も行われます。|http://www.ntp.org/|{{Pkg|ntp}}}}
 
* {{App|[[Network Time Protocol daemon]]|プロトコルの[[Wikipedia:ja:リファレンス実装|リファレンス実装]]であり、特に時刻サーバーでの使用が推奨されます。NTPd は割り込みの周期や1秒辺りのティックの数を調整してシステムクロックのずれを減らすことも可能です。NTPd の実行中は11分ごとにハードウェアクロックの再同期も行われます。|http://www.ntp.org/|{{Pkg|ntp}}}}
  +
* {{App|[[NTPsec]]|NTPd のフォークで、セキュリティに重点を置いています。多くの古いコードが捨てられる以外は、同じように動作します。|https://ntpsec.org/|{{AUR|ntpsec}}}}
  +
  +
適切な NTP ノード以下の機能を持つものは、SNTP("Sinplified" の意)とみなされます。基本的な SNTP クライアントは、長期的なドリフトを追跡することなく、単に 1 つのサーバーから時刻を取得し、すぐに設定することができます。SNTP は精度が低いですが、より少ないリソースで動作します。この精度は通常、デスクトップユーザーや組み込みワークロードには十分ですが、NTP サーバーには受け入れられません。以下は、SNTP を実装しています:
  +
  +
* {{App|[[ConnMan]]|A lightweight network manager with SNTP support.|[https://web.archive.org/web/20210224075615/https://01.org/connman https://01.org/connman (waybackmachine)]|{{Pkg|connman}}}}
  +
* {{App|ntpclient|シンプルなコマンドライン NTP クライアント。|http://doolittle.icarus.com/ntpclient/|{{Aur|ntpclient}}}}
  +
* {{App|[[OpenNTPD]]|クライアントとサーバーの両方を実装する OpenBSD プロジェクト。|http://www.openntpd.org/|{{Pkg|openntpd}}}}
 
* {{App|sntp|NTPd に付属している [[wikipedia:ja:Simple Network Time Protocol|SNTP]] クライアント。''ntpdate'' を置き換えることができ、サーバー以外の環境での使用が推奨されます。|http://www.ntp.org/|{{Pkg|ntp}}}}
 
* {{App|sntp|NTPd に付属している [[wikipedia:ja:Simple Network Time Protocol|SNTP]] クライアント。''ntpdate'' を置き換えることができ、サーバー以外の環境での使用が推奨されます。|http://www.ntp.org/|{{Pkg|ntp}}}}
 
* {{App|[[systemd-timesyncd]]|クライアント側だけを実装したシンプルな [[wikipedia:ja:Simple Network Time Protocol|SNTP]] デーモン。リモートサーバーに時刻を問い合わせることだけを行います。大抵の環境ではクライアントだけで十分です。|https://www.freedesktop.org/wiki/Software/systemd/|{{Pkg|systemd}}}}
 
* {{App|[[systemd-timesyncd]]|クライアント側だけを実装したシンプルな [[wikipedia:ja:Simple Network Time Protocol|SNTP]] デーモン。リモートサーバーに時刻を問い合わせることだけを行います。大抵の環境ではクライアントだけで十分です。|https://www.freedesktop.org/wiki/Software/systemd/|{{Pkg|systemd}}}}
* {{App|[[OpenNTPD]]|クライアントとサーバーの両方を実装する OpenBSD プロジェクト。|http://www.openntpd.org/|{{Pkg|openntpd}}}}
 
* {{App|[[Chrony]]|ノートパソコンなど常にオンラインとは限らない環境用に設計されたクライアント・サーバー。|https://chrony.tuxfamily.org/|{{Pkg|chrony}}}}
 
* {{App|ntpclient|シンプルなコマンドライン NTP クライアント。|http://doolittle.icarus.com/ntpclient/|{{Aur|ntpclient}}}}
 
 
== ヒントとテクニック ==
 
 
=== fake-hwclock ===
 
 
[https://github.com/xanmanning/alarm-fake-hwclock alarm-fake-hwclock] は RTC をバックアップするバッテリーが搭載されていないシステム用のスクリプトで、シャットダウン時に現在時刻を保存して、起動時に保存した時刻を復元する systemd サービスが付属しています。これによって時刻が飛んでしまうエラーを防ぐことができます。
 
 
{{AUR|fake-hwclock-git}} を[[インストール]]して {{ic|fake-hwclock.service}} を[[Systemd#ユニットを使う|起動・有効化]]してください。
 
   
=== ユーザー別あるいは一時的に時刻を設定 ===
+
== ユーザー別あるいは一時的に時刻を設定 ==
   
 
ときとしてシステムの時刻は変えずに一時的に設定を変えたいということがあるでしょう。例えば、時間を使用するアプリケーションを開発していて実際に動きをテストしたい場合やタイムゾーンが異なる場所からサーバーにログインしている場合などです。
 
ときとしてシステムの時刻は変えずに一時的に設定を変えたいということがあるでしょう。例えば、時間を使用するアプリケーションを開発していて実際に動きをテストしたい場合やタイムゾーンが異なる場所からサーバーにログインしている場合などです。
   
アプリケーションにシステム時刻以外の時刻を使わせたいときは ({{Pkg|libfaketime}} に含まれている) ''faketime'' あるいは {{Pkg|datefudge}}{{Broken package link|{{aur-mirror|datefudge}}}} ユーティリティが使えます。
+
アプリケーションにシステム時刻以外の時刻を使わせたいときは ({{Pkg|libfaketime}} に含まれている) {{man|1|faketime}} ユーティリティが使えます。
   
 
アプリケーションにシステム設定のタイムゾーン以外のタイムゾーンを使わせたいときは、以下のように {{ic|TZ}} [[環境変数]]を設定してください:
 
アプリケーションにシステム設定のタイムゾーン以外のタイムゾーンを使わせたいときは、以下のように {{ic|TZ}} [[環境変数]]を設定してください:
283行目: 238行目:
   
 
タイムゾーンを別々に設定するケースとして同一システム上にユーザーが複数存在する場合も考えられます。シェルの設定ファイルで {{ic|TZ}} 変数を設定することでユーザーごとにタイムゾーンを設定できます。[[環境変数#変数の定義]]や[[自動起動#シェル]]を参照してください。
 
タイムゾーンを別々に設定するケースとして同一システム上にユーザーが複数存在する場合も考えられます。シェルの設定ファイルで {{ic|TZ}} 変数を設定することでユーザーごとにタイムゾーンを設定できます。[[環境変数#変数の定義]]や[[自動起動#シェル]]を参照してください。
  +
  +
== ヒントとテクニック ==
  +
  +
=== fake-hwclock ===
  +
  +
[https://github.com/xanmanning/alarm-fake-hwclock alarm-fake-hwclock] は RTC をバックアップするバッテリーが搭載されていないシステム用のスクリプトで、シャットダウン時に現在時刻を保存して、起動時に保存した時刻を復元する systemd サービスが付属しています。これによって時刻が飛んでしまうエラーを防ぐことができます。
  +
  +
{{AUR|fake-hwclock-git}} を[[インストール]]して {{ic|fake-hwclock.service}} を[[Systemd#ユニットを使う|起動・有効化]]してください。
   
 
== トラブルシューティング ==
 
== トラブルシューティング ==
303行目: 266行目:
 
* {{Pkg|tzdata}} で使われている [http://www.twinsun.com/tz/tz-link.htm タイムゾーンと夏時間のソース]
 
* {{Pkg|tzdata}} で使われている [http://www.twinsun.com/tz/tz-link.htm タイムゾーンと夏時間のソース]
 
* [https://www.ucolick.org/~sla/leapsecs/timescales.html Time Scales]
 
* [https://www.ucolick.org/~sla/leapsecs/timescales.html Time Scales]
  +
* [[Gentoo: System time]]
 
* [[Wikipedia:ja:時間]]
 
* [[Wikipedia:ja:時間]]
  +
* [https://www.datetimeonline.com/time/gmt-utc-time The Difference Between GMT and UTC]

2024年9月1日 (日) 19:08時点における最新版

関連記事

オペレーティング システムでは、時間 (クロック) は 3 つの部分によって決定されます: 時間の値、現地時間か UTC かそれ以外か、タイム ゾーン、および該当する場合は夏時間 (DST) です。この記事では、それらが何であるか、およびそれらの読み取り/設定方法について説明します。システムには、ハードウェア クロックとシステム クロックの 2 つのクロックが存在します。これについても、この記事で詳しく説明します。

ほとんどのオペレーティング システムの標準的な動作は次のとおりです。

  • 起動時にハードウェア クロックからシステム クロックを設定します。
  • システムクロックの正確な時刻を維持します。#時刻同期 を参照してください。
  • シャットダウン時にシステム クロックからハードウェア クロックを設定します。

ハードウェアクロック

ハードウェアクロック (又の名をリアルタイムクロック (Real Time Clock, RTC) もしくは CMOS クロック) は次の値を保存しています: 年・月・日・時・分・秒。2016 年以降のUEFI ファームウェアには、タイムゾーンとサマータイムを保存する機能を備えられています。

ハードウェアクロックの読み込み

# hwclock --show

システムクロックからハードウェアクロックを設定する

以下は、システムクロックからハードウェアクロックを設定するものです。さらに、/etc/adjtime を更新するか、存在しない場合は作成します。このファイルに関するより詳しい情報は #タイムスキュー の項と同様に hwclock(8) § The Adjtime File を参照してください。

# hwclock --systohc

システムクロック

システムクロック (又の名をソフトウェアクロック) は次の情報を記録しています: 時刻、タイムゾーン、そして DST が適用されるかどうか。Linux カーネルは1970年1月1日の午前0時からの秒数でシステムクロックをはじき出します。システムクロックの初期値は /etc/adjtime を使ってハードウェアクロックから算定されます。起動が完了した後は、システムクロックはハードウェアクロックとは独立して動作します。Linux カーネルはタイマー割り込みを数えることによりシステムクロックを記録します。

時刻を表示する

現在のシステム時刻を確認するには (UTC と現地時間のどちらも表示されます):

$ timedatectl status

root で同じコマンドを実行すればハードウェアクロックの時間も表示します。

時刻を設定する

直接システムクロックを設定するには:

# timedatectl set-time "yyyy-MM-dd hh:mm:ss"

例:

# timedatectl set-time "2014-05-26 11:13:54"

2014年5月26日、11時13分54秒に設定されます。

RTC

ほとんどのオペレーティングシステムは:

  • 起動時にハードウェアクロックからシステムクロックを設定します
  • NTP デーモンを使ってシステムクロックの時間を正確に保ちます
  • シャットダウン時にシステムクロックからハードウェアクロックを設定します

時刻系

2つの時刻系が存在します: 地方時 (localtime) と 協定世界時 (Coordinated Universal Time, UTC) です。地方時系は現在のタイムゾーンによって決まりますが、UTC は世界時であり、タイムゾーンの値は関係ありません。概念的には異なっていますが、UTC は GMT (グリニッジ標準時, Greenwich Mean Time) とも言われます。

ハードウェアクロック (CMOS クロック, BIOS で表示される時間) で使われる時刻系はオペレーティングシステムによって定義されます。デフォルトでは、Windows は localtime を使いますが、Mac OS は UTC を使っていて、UNIX ライクなオペレーティングシステムでは決まっていません。一般的に、UTC を使う OS は起動時に CMOS (ハードウェアクロック) の時間を UTC 時間 (GMT, Greenwich time) だと認識して、あなたのタイムゾーンによってその時間を調整してシステム時刻を設定します。

複数のオペレーティングシステムがマシンにインストールされている場合、それらはすべて同じハードウェアクロックから現在の時刻を取得します。システム間の競合を避けるために、UTC に設定することをお勧めします。それ以外の場合、ハードウェアクロックが「現地時間」に設定されている場合、たとえば DST の変更後に複数のオペレーティングシステムがそれを調整する可能性があり、その結果、過剰な修正が行われます。異なるタイムゾーン間を移動し、オペレーティング システムの 1 つを使用してシステム/ハードウェア クロックをリセットするときにも、問題が発生する可能性があります。

ハードウェアクロックは、timedatectl コマンドで照会および設定ができます。 以下を使用して、Arch システムの現在のハードウェアクロック時間標準を確認できます。

$ timedatectl | grep local
RTC in local TZ: no


ハードウェアクロックは timedatectl コマンドで尋ねたり設定できます。ハードウェアクロックの時刻系を localtime に変更するには次を実行してください:

# timedatectl set-local-rtc true

ハードウェアクロックの時刻系を localtime に変更するには、次を実行してください:

# timedatectl set-local-rtc 1

逆にハードウェアクロックの時刻系を UTC に戻すには次を実行してください:

# timedatectl set-local-rtc 0

これらは /etc/adjtime を自動的に生成し、それに応じて RTC を更新します。これ以上の設定は必要ありません。

カーネルの起動中、RTC ドライバーがロードされた時点で、ハードウェアクロックからシステムクロックを設定することができます。設定するかどうかはハードウェアプラットフォーム、カーネルのバージョン・ビルドオプション次第です。設定される場合、ブートシーケンスで既に、ハードウェアクロックは UTC と認識され /sys/class/rtc/rtcN/hctosys (N=0,1,2,..) の値は 1 に設定されます。その後、/etc/adjtime の値を使って、再度 systemd によってハードウェアクロックからシステムクロックが設定されます。そのため、ハードウェアクロックで localtime を使っているとブートシーケンス中に予期しない動作が発生するかもしれません。例えば、システム時刻が後戻りするなど。従ってこの設定は良いアイデアとは言えません。

その後、/etc/adjtime の値に応じて、systemd によってハードウェアクロックからシステムクロックが再度設定されます。したがって、ハードウェアクロックで localtime を使用すると、ブートシーケンス中に予期しない動作が発生する可能性があります。たとえば、システム時間が逆行することは、常に悪い考えです (他にもたくさんあります)。ハードウェアクロックが UTC に設定されていてローカルタイムゾーンについてカーネルに通知しないでください。その結果、Linux システムが使用する FAT ファイルシステムのタイムスタンプは UTC になります。

ノート:
  • timedatectl を使うには D-Bus が有効になっている必要があります。そのため、(インストール中など) chroot 下でこのコマンドが使えないかもしれません。そのような場合には、hwclock コマンドを使って下さい。
  • /etc/adjtime が存在しない場合、systemd はハードウェアクロックが UTC に設定されていると認識しています。

Windows で UTC を使う

RTC を localtime に設定する理由に Windows とのデュアルブートをするためということがあります (Windows は localtime を使っています)。しかしながら、Windows ではレジストリを編集することで RTC で UTC を使っていても対応できるようにすることができます。従って、Linux に localtime を使わせるよりも Windows に UTC を使わせるようにすることが推奨されます。Windows に UTC を使わせる場合、Windows のインターネット時刻機能をオフにするようにしてください。オフにすると Windows はハードウェアクロックにメスを入れなくなるので、代わりに NTP デーモンを使って RTC を同期させる必要があります。

regedit を使って、レジストリに十六進数で 1DWORD 値を追加してください:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation\RealTimeIsUniversal

管理者権限で開いたコマンドプロンプトで以下のコマンドを実行することでも設定できます:

reg add "HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\TimeZoneInformation" /v RealTimeIsUniversal /d 1 /t REG_DWORD /f

もしくは、以下の内容で *.reg ファイルを (デスクトップに) 作成しそれをダブルクリックしてレジストリにインポートしてください:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation]
     "RealTimeIsUniversal"=dword:00000001
ノート: 64ビット版の Windows を使っている場合で、上記の設定を行っても効果がないときは DWORD の代わりに QWORD を使うことで問題が解決することがあります。

DST が変わったことで Windows が時計を更新すると行ってきた場合は、それに従って下さい。Windows は時計を UTC のままにしておき、表示する時間だけ修正します。

値を設定した後にハードウェアクロックとシステムクロックの時刻を更新する必要があるかもしれません。

時計がずれる問題が発生している場合、tzdata を再インストールしてタイムゾーンをもう一度設定してみてください:

# pacman -S tzdata
# timedatectl set-timezone Asia/Tokyo

Ubuntu で UTC を使う

Ubuntu とその派生ディストリはインストール時に Windows が認識されたときにハードウェアクロックを "localtime" と認識されるように設定します。Linux 初心者が Windows コンピュータで Ubuntu を試したときにレジストリを編集しなくてもよいように故意にこのような挙動となっています。

タイムゾーン

現在のゾーンを確認するには:

$ timedatectl status

利用可能なゾーンを一覧するには:

$ timedatectl list-timezones

タイムゾーンを変更するには:

# timedatectl set-timezone <Zone>/<SubZone>

例:

# timedatectl set-timezone Asia/Tokyo

このコマンドによって /usr/share/zoneinfo/ 下の zoneinfo ファイルを指し示したシンボリックリンク /etc/localtime が作られます。リンクを手動で作成する場合 (chroot の中で timedatectl が使用できない場合など)、archlinux(7) に書かれているように、ハードリンクではなくシンボリックリンクを使ってください:

# ln -sf /usr/share/zoneinfo/Zone/SubZone /etc/localtime

詳細は timedatectl(1), localtime(5), archlinux(7) を見てください。

ノート: systemd 以前の設定ファイル /etc/timezone がシステムにまだ存在している場合、もう使われていないので削除しても問題ありません。
ヒント: tzselect を使ってインタラクティブにタイムゾーンを選択することもできます。

地理情報を元に設定

IP アドレスの位置情報を元に自動的にタイムゾーンを設定したい場合、$ curl https://ipapi.co/timezone などで geolocation API を使ってタイムゾーンを取得して timedatectl set-timezone に出力を渡すことで自動設定できます。以下のサービスが無料あるいは一部無料で geo-IP API を提供しています:

また、tzupdateAUR ツールは IP アドレスの位置情報を元にタイムゾーンを自動設定します。

NetworkManager がネットワークに接続するたびにタイムゾーンを更新する

NetworkManager dispatcher スクリプト を作成します:

/etc/NetworkManager/dispatcher.d/09-timezone
#!/bin/sh
case "$2" in
    up)
        timedatectl set-timezone "$(curl --fail https://ipapi.co/timezone)"
    ;;
esac
ヒント: up の代わりに connectivity-change を使用すると、OpenConnect などのクライアントで VPN に接続するときにタイムゾーンの変更を防ぐことができます。

あるいは、ツール tzupdateAUR が IP アドレスのジオロケーションに基づいてタイムゾーンを自動的に設定します。この 最も人気のある IP 地理位置情報 API の比較 は、プロダクションでどの API を使うか決める際に役に立つかもしれません。

クロックスキュー

全ての時計は本当の時間 (一番正確なのは国際原子時) とは違う値を示しています、どの時計も完全ではありません。クォーツを使っている電子時計は(不完全な)時間を刻んでいますが、規則的なズレを生じさせています。この本質的な'ズレ'は'クロックスキュー'や'クロックドリフト'として知られています。

ハードウェアクロックが hwclock で設定された時、新しいドリフト値(一日に何秒ズレるか)が算定されます。このドリフト値は新しく設定された値と以前に設定されていたハードウェアクロックの値の差から計算され、以前のドリフト値とハードウェアクロックが最後に設定された時間を考慮しています。新しいドリフト値と時計が設定された時刻は /etc/adjtime ファイルに書き込まれ以前の値を上書きします。これにより hwclock --adjust を実行することでハードウェアクロックのずれを調整できるようになっています。また、hwclock デーモンが有効になっている場合シャットダウン時にも実行されます (よって systemd を使っているシステムでは実行されません)。

ノート: 以前に設定した時から24時間以内に再度 hwlock が設定された場合、hwclock は経過時間が短すぎて正確にドリフトを計算できないとしてドリフトは再計算されません。

ハードウェアクロックが時間の消失と取得を何度も繰り返している場合、不正なドリフトが保存されている可能性があります (ただし hwclock デーモンが実行中の場合に限ります)。これはハードウェアクロックの時間を間違って設定したり時刻系を Windows や Mac OS と合わせていないときに起こります。/etc/adjtime を削除してドリフト値を削除してから、正しいハードウェアとシステムクロックの時間を設定して、時刻系が直ったか確認してください。

ノート: systemd を使用しているのに /etc/adjtime に保存されているドリフト値を使いたい (つまり NTP を使えない・使いたくない) 場合、定期的に hwclock --adjust を実行するか、それを代わりにする cron ジョブを作って下さい。

ソフトウェアクロックはかなり正確ですが、他の時計と同じく完全に正しいわけではありませんし同じようにズレが起こります。稀に、カーネルが割り込みを飛ばしたときにシステム時刻が正確さを失うことがあります。ソフトウェアクロックの正確性を改善するツールが複数存在します。#時刻同期を見てください。

時刻同期

Network Time Protocol (NTP) はパケット交換でデータの遅延時間が不確定なネットワークを介してコンピュータシステムの時刻を同期するためのプロトコルです。NTP の実装は以下が存在します:

  • Chrony — ローミングフレンドリーで、常時オンラインではないシステムのために特別に設計されたクライアントとサーバーです。ほとんどの場合、ntpd よりも速く、より参照に近い形で収束します。
https://chrony.tuxfamily.org/ || chrony
  • Network Time Protocol daemon — プロトコルのリファレンス実装であり、特に時刻サーバーでの使用が推奨されます。NTPd は割り込みの周期や1秒辺りのティックの数を調整してシステムクロックのずれを減らすことも可能です。NTPd の実行中は11分ごとにハードウェアクロックの再同期も行われます。
http://www.ntp.org/ || ntp
  • NTPsec — NTPd のフォークで、セキュリティに重点を置いています。多くの古いコードが捨てられる以外は、同じように動作します。
https://ntpsec.org/ || ntpsecAUR

適切な NTP ノード以下の機能を持つものは、SNTP("Sinplified" の意)とみなされます。基本的な SNTP クライアントは、長期的なドリフトを追跡することなく、単に 1 つのサーバーから時刻を取得し、すぐに設定することができます。SNTP は精度が低いですが、より少ないリソースで動作します。この精度は通常、デスクトップユーザーや組み込みワークロードには十分ですが、NTP サーバーには受け入れられません。以下は、SNTP を実装しています:

  • ConnMan — A lightweight network manager with SNTP support.
https://01.org/connman (waybackmachine) || connman
  • ntpclient — シンプルなコマンドライン NTP クライアント。
http://doolittle.icarus.com/ntpclient/ || ntpclientAUR
  • OpenNTPD — クライアントとサーバーの両方を実装する OpenBSD プロジェクト。
http://www.openntpd.org/ || openntpd
  • sntp — NTPd に付属している SNTP クライアント。ntpdate を置き換えることができ、サーバー以外の環境での使用が推奨されます。
http://www.ntp.org/ || ntp
  • systemd-timesyncd — クライアント側だけを実装したシンプルな SNTP デーモン。リモートサーバーに時刻を問い合わせることだけを行います。大抵の環境ではクライアントだけで十分です。
https://www.freedesktop.org/wiki/Software/systemd/ || systemd

ユーザー別あるいは一時的に時刻を設定

ときとしてシステムの時刻は変えずに一時的に設定を変えたいということがあるでしょう。例えば、時間を使用するアプリケーションを開発していて実際に動きをテストしたい場合やタイムゾーンが異なる場所からサーバーにログインしている場合などです。

アプリケーションにシステム時刻以外の時刻を使わせたいときは (libfaketime に含まれている) faketime(1) ユーティリティが使えます。

アプリケーションにシステム設定のタイムゾーン以外のタイムゾーンを使わせたいときは、以下のように TZ 環境変数を設定してください:

$ date && export TZ="/usr/share/zoneinfo/Pacific/Fiji" && date
Tue Nov  1 14:34:51 CET 2016
Wed Nov  2 01:34:51 FJT 2016

環境変数によってシステムの時刻が変わるわけではないため、プログラムの開発時に UTC からの時差を変えたり DST をテストすることが可能です。

タイムゾーンを別々に設定するケースとして同一システム上にユーザーが複数存在する場合も考えられます。シェルの設定ファイルで TZ 変数を設定することでユーザーごとにタイムゾーンを設定できます。環境変数#変数の定義自動起動#シェルを参照してください。

ヒントとテクニック

fake-hwclock

alarm-fake-hwclock は RTC をバックアップするバッテリーが搭載されていないシステム用のスクリプトで、シャットダウン時に現在時刻を保存して、起動時に保存した時刻を復元する systemd サービスが付属しています。これによって時刻が飛んでしまうエラーを防ぐことができます。

fake-hwclock-gitAURインストールして fake-hwclock.service起動・有効化してください。

トラブルシューティング

時計が示している値が UTC でも localtime でもない

さまざまな理由が考えられます。例えば、ハードウェアクロックが localtime で動いているのに、timedatectl が UTC に設定されていると、タイムゾーンのオフセットが UTC に二重に適用されることで、localtime でも UTC でもない間違った値になってしまいます。

時計を正しい時刻に直して、ハードウェアクロックに正しい UTC を書き込むには、以下の手順に従って下さい:

  • NTP を設定してください (サービスとして有効にする必要はありません)。
  • タイムゾーンを適切に設定してください。
  • ntpd -qg を実行して手動で時計をネットワークと同期してください、ローカル UTC とネットワーク UTC の時差は無視します。
  • hwclock --systohc を実行して現在のソフトウェア UTC 時刻をハードウェアクロックに書き込んで下さい。

資料