Akira's Tech Notes

Java/JVM | GNU/Linux | Emacs/Lisp | 知的好奇心駆動

header-icon
ネイティブでない日本語で思い付くことや気になることをダラダラ書く、体裁とかは気にしない。読みづらいと感じた時に随時更新する。

[まとめ]Linuxシステム時刻について

Linuxシステム時刻に関わる知識やリソースのまとめです。

1 ハードウェアクロック/システムクロックの違い

クロック種別 説明
ハードウェアクロック * マザーボード上のICによって提供される時計です。
  * 通常は電池でバックアップして駆動されるので、電源をお落としても時計が進みます。
  * RTC(Real Time Clock)、BIOS、CMOSクロックとも呼ばれる。
システムクロック * Linux カーネルの内部に存在している時計で、 タイマ割り込みによって駆動されている
  * Linux システムは起動時に一度だけハードウェア・クロックを参照し、 システム・クロックを設定する。
  * 精度の高いクロック、1GHz以上のCPUの場合1クロックは1ナノ秒のなります。
  * 時刻は1970/01/01T00:00:00からの経過時間を秒単位/ナノ秒単位で保持される。

ハードウェアクロック持っていないボードも存在する。RaspberryPiボードはその一つです、 RTCが必要な場合、別途RTCモジュールを導入しなければいけません。2

RaspberryPiで hwclock コマンドでハードウェアクロックを参照すると /dev/rtc デバイ スがない旨のメッセージが表示された。

$ sudo hwclock --debug
hwclock from util-linux 2.26.2
hwclock: cannot open /dev/rtc: No such file or directory
No usable clock interface found.
hwclock: Cannot access the Hardware Clock via any known method.

RaspberryPiはNTPサーバから時刻同期のし掛けが必要です。そしないとシステムクロックが POSIXにおける紀元時刻(Epoch; 1970-01-01 00:00:00 +0000 (UTC))に設定されてしまう。

2 時刻の表示仕様

systemdに導入された timdatectl コマンドでシステム時刻の各種表示形式を確認する。

$ timedatectl
      Local time: 土 2015-06-27 23:55:12 JST
  Universal time: 土 2015-06-27 14:55:12 UTC
        RTC time: 土 2015-06-27 14:55:12
       Time zone: Asia/Tokyo (JST, +0900)
     NTP enabled: yes
NTP synchronized: yes
 RTC in local TZ: no
      DST active: n/a

各時刻項目について

  正式名称 説明
Universal time 協定世界時 (UTC) UTC は GMT (グリニッジ標準時, Greenwich Mean Time) とも言われます
    協定世界時は、国際度量衡局 (BIPM) が維持する時刻系であり、
    協定された標準周波数と報時信号発射の基礎になっている。
Local time 標準時 ある国または広い地域が共通で使う地方時、
    世界各地の標準時は協定世界時 (UTC) を基準として決めている。
    例えば、日本標準時 (JST) は協定世界時より9時間進んでおり、
    「+0900 (JST)」のように表示する。
DST 夏時間 daylight saving time
    1年のうち夏を中心とした期間に、太陽の出ている時間帯を有効に利用する目
    的で、標準時を1時間進める制度、またはその進められた時刻のこと。
    緯度が高く夏の日照時間が長い欧米諸国などで多く導入されている。10
    Linuxシステムにタイムゾーンを指定すれば自動的にDST時間を表示してくれる。
RTC time リアルタイムクロック 前述のハードウェアクロックです。

3 時刻表示/調整関連コマンド

コマンド名 概要
date システムクロックの表示/変更
hwclock ハードウェアクロックの表示/変更
ntpdate NTPサーバから時刻を同期化するクライアントツール
timedatectl 上記機能全て統括的に行えるツール
adjtimex Displays or sets the kernel time variable

時刻の表示/調整/同期化などは timedatectl で全て出来る。

3.1 NTP時刻同期化を自動化する

★set-ntpオプションで有効/無効を切り替える
$ sudo timedatectl set-ntp true

★状態確認
$ sudo timedatectl status
      Local time: 日 2015-06-28 00:19:26 JST
  Universal time: 土 2015-06-27 15:19:26 UTC
        RTC time: 土 2015-06-27 15:19:26
       Time zone: Asia/Tokyo (JST, +0900)
     NTP enabled: yes                      ★NTP時刻同期化有効の状態
NTP synchronized: yes                      ★NTP時刻同期化済み
 RTC in local TZ: no
      DST active: n/a

上記コマンドより systemd-timesyncd.service が有効化される。 /usr/lib/systemd/systemd-timesyncd デーモンプロセスがNTPクライアントとして動作し定 期的にNTPサーバから時刻を同期化する。

$ systemctl status systemd-timesyncd.service
● systemd-timesyncd.service - Network Time Synchronization
   Loaded: loaded (/usr/lib/systemd/system/systemd-timesyncd.service; enabled; vendor preset: enabled)
   Active: active (running) since 土 2015-06-27 19:29:29 JST; 4h 57min ago
     Docs: man:systemd-timesyncd.service(8)
 Main PID: 8787 (systemd-timesyn)
   Status: "Using Time Server 213.239.154.12:123 (0.arch.pool.ntp.org)."
   CGroup: /system.slice/systemd-timesyncd.service
           └─8787 /usr/lib/systemd/systemd-timesyncd

 6月 27 19:29:29 mimi systemd[1]: Starting Network Time Synchronization...
 6月 27 19:29:29 mimi systemd[1]: Started Network Time Synchronization.
 6月 27 20:45:20 mimi systemd-timesyncd[8787]: Timed out waiting for reply from 202.234.64.222:123 (0.arch.pool.ntp.org).
 6月 27 20:45:30 mimi systemd-timesyncd[8787]: Timed out waiting for reply from 157.7.153.56:123 (0.arch.pool.ntp.org).
 6月 27 20:45:40 mimi systemd-timesyncd[8787]: Timed out waiting for reply from 108.61.223.189:123 (0.arch.pool.ntp.org).
 6月 27 20:45:51 mimi systemd-timesyncd[8787]: Timed out waiting for reply from 133.100.11.8:123 (0.arch.pool.ntp.org).

NTPサーバは /etc/systemd/timesyncd.conf にて指定出来る。

3.2 タイムゾーンの変更

Asia/Tokyoタイムゾーンの指定

★利用可能なゾーンの表示
$ timedatectl list-timezones
Africa/Abidjan
Africa/Accra
Africa/Addis_Ababa
Africa/Algiers
Africa/Asmara
Africa/Bamako
Africa/Bangui
Africa/Banjul
Africa/Bissau
Africa/Blantyre
(中略)

★タイムゾーンの指定、/etc/localtimeのリンク先が変わる
$ timedatectl set-timezone Asia/Tokyo

★タイムゾーンの確認
$ timedatectl status
      Local time: 日 2015-06-28 17:57:04 JST
  Universal time: 日 2015-06-28 08:57:04 UTC
        RTC time: 日 2015-06-28 08:57:04
       Time zone: Asia/Tokyo (JST, +0900)
     NTP enabled: yes
NTP synchronized: yes
 RTC in local TZ: no
      DST active: n/a

America/Los_Angelesタイムゾーンの指定、「*」部分は夏時間です。

  |$ timedatectl  set-timezone America/Los_Angeles
  |[akira@mimi ~]$ timedatectl status
  |      Local time: 日 2015-06-28 01:54:09 PDT
  |  Universal time: 日 2015-06-28 08:54:09 UTC
  |        RTC time: 日 2015-06-28 08:54:09
  |       Time zone: America/Los_Angeles (PDT, -0700)
  |     NTP enabled: yes
  |NTP synchronized: yes
  | RTC in local TZ: no
*|      DST active: yes
*| Last DST change: DST began at
*|                  日 2015-03-08 01:59:59 PST
*|                  日 2015-03-08 03:00:00 PDT
*| Next DST change: DST ends (the clock jumps one hour backwards) at
*|                  日 2015-11-01 01:59:59 PDT
*|                  日 2015-11-01 01:00:00 PST

3.3 ハードウェアクロックとの同期化

ハードウェアクロックの時刻をUTCとして扱うように /etc/adjtime ファイルを更新する。 また、システムクロック時刻をハードウェアクロックに書き戻す。

$ timedatectl set-local-rtc false

/etc/adjtime ファイルの3行目がUTCでマークされた。

$ cat /etc/adjtime
0.000000 0 0.000000
0
UTC                                ★ハードウェアクロックがUTC時刻として扱う

RTC が localtime だった場合予期せぬバグを引き起こす可能性があるため、最近のカーネルは /etc/adjtime ファイルに設定値がない場合 RTC を UTC としてみなします。 hwclock コ マンドに–debugオプションを付けるとハードウェアクロックがどうのように扱われるかを確認 することが出来ます。

ハードウェアクロックの値をUTC時刻として扱い、表示時に /etc/localtime に持っている タイムゾーン情報を元にローカル時刻で表示する。

$ hwclock --show --debug
hwclock from util-linux 2.26.2
クロックの /dev インターフェイス を使用中。
ハードウェアの時刻が UTC に設定されているものと仮定します。
クロックティックを待っています...
...クロックティックを取得しました
ハードウェアの時計から読み込んだ時刻: 2015/06/27 15:44:18
ハードウェアの時刻値 : 2015/06/27 15:44:18 = 1969 年から 1435419858 秒経過
Time since last adjustment is 1435419858 seconds
Calculated Hardware Clock drift is 0.000000 seconds
2015年06月28日 00時44分17秒  .665140 秒

以下 /etc/adjtime= の設定値を明示された場合 hwclock の出力です。「*」部分が差分で す。

 |$ hwclock -r --debug
 |hwclock from util-linux 2.26.2
 |クロックの /dev インターフェイス を使用中。
*|直前のズレの修正は、 1969 年から 0 秒経過した時点で行なわれました
*|直前の調整は 1969 年から 0 秒経過した時点で行なわれました
*|ハードウェアの時刻は UTC です
 |ハードウェアの時刻が UTC に設定されているものと仮定します。
 |クロックティックを待っています...
 |...クロックティックを取得しました
 |ハードウェアの時計から読み込んだ時刻: 2015/06/27 16:05:20
 |ハードウェアの時刻値 : 2015/06/27 16:05:20 = 1969 年から 1435421120 秒経過
 |Time since last adjustment is 1435421120 seconds
 |Calculated Hardware Clock drift is 0.000000 seconds
 |2015年06月28日 01時05分19秒  .432450 秒

4 時刻関連ファイル

ファイル 役割
/etc/localtime ローカル時刻(標準時)に適用するタイムゾーン情報
/etc/adjtime ハードウェアクロック情報を保持するファイル、詳細について
  man hwclockのThe Adjust Functionセクションにて確認出来る
/dev/rtc ハードウェアクロックデバイスファイル
/dev/rtc0 同上
/dev/misc/rtc 同上

5 デュアルブートの注意点

以下 からの抜粋

windows はハードウェア クロックのタイムゾーンを、暗黙裡にローカル タイムであると認識
します。 Linux のようにタイムゾーンを選択(UTC or ローカルタイム)できる機能はありませ
ん。

そのため windows を含むマルチ ブート環境では、ハードウェア クロックのタイムゾーンを
UTCとすることは不可能(ローカルタイム固定)で、他のOSが windows の作法に合わせる必要が
あります。

日本の場合、システムをWindowsモードで起動したとして、次回Linux起動した後のシステム時 刻がローカル時刻より9時間早まる。

回避方法: Windows で UTC を使う

7 システムコール

関数名 機能概要
gettimeofday システム時刻を取得する
settimeofday システム時刻を設定する
time 秒単位の時間を得る
strftime 日付および時刻の文字列への変換
adjtimex カーネルの時計を調整する
clock プログラムの使用したプロセッサ時間の近似値を返す
asctime 日付と時刻を要素別の時刻や ASCII に変換する
ctime  
gmtime  
localtime  
mktime  
asctime_r  
ctime_r  
gmtime_r  
localtime_r  

Comments