for e's laboratory
パソコン実習室
パソコンの時計 ハードウェア クロックとシステム クロック
≪ previous  

V.クロックの検証 Linux 編

 パソコンのクロックが管理して(持って)いる時刻情報は、システム クロックがUTC、ハードウェア クロックはUTCまたはローカル タイムとなっています(インストール時のオプションで変わります)。

 date、hwclock はこれらの情報を読み出して表示するコマンドで、読み出された時刻情報がどちらの設定(UTC, ローカル タイム)であっても、ローカル タイムに変換して表示します。
※ date コマンドは、オプションによって UTC を表示することもできます。

 取得した時刻情報をローカル タイムで表示するには、各コマンドが次の2点を識別できていることが肝心です。  コマンドがこれらを識別するための情報源はどこにあるのでしょう。設定を操作・変更して検証してみます。


V.1.使用するコマンド


 検証では時刻表示用に以下のコマンドを使用します。

date [option]
  • システム クロックの日付・時刻を表示(設定)します。
    ※ システム クロックのデータは 1970年01月01日からの経過秒数です。
      表示の際に、年・月・日・時・分・秒 の形式に変換します。
  • option なしの場合、ローカル タイムで表示します。
  • UTCからローカルタイムへの変換には /etc/localtime を参照して補正値(時差情報)を得ます。
  • option に --u を指定すると、UTCの現在時刻を表示します。
    ※ 仮にローカル タイムが12:30(JST)なら、UTCとの時差は -9時間なので 03:30 と表示されます。
  • date コマンドはシステム クロックの表示だけでなく、設定(変更)も可能です。
    取り扱いにはご注意ください。

hwclock --show [第2option]
  • ハードウエア クロックの情報をローカル タイムに変換して表示します。
  • UTCからローカルタイムへの変換には /etc/localtime を参照して補正値(時差情報)を得ます。
  • 第2option
    第2オプションによって、ハードウエア クロックのタイム ゾーンを指定できます。
    • --utc
      ハードウエア クロックをUTCであると仮定して処理します。
    • --localtime
      ハードウエア クロックをローカル タイムであると仮定して処理します。
    • 第2option 省略
      /etc/adjtime を参照してハードウエア クロックのタイム ゾーンを識別します。
  • パラメータの --show は、-r で代用可能です。
    ( hwclock -r [option] )
  • hwclock コマンドはハードウェア クロックの表示だけでなく、書き替えも可能です。
    取り扱いにはご注意ください。


V.2.オプション (--utc, --localtime) で変化する時刻


 ハードウェア クロック(RTC)をUTCあるいはローカル タイムで設定した時の、date コマンドの時刻表示、hwclock --show コマンドによるハードウェア クロックの時刻表示が、オプションによって変化する様子を見ます。

 実施時期は 2009年10月22日 10時16〜18分であり、表示情報は一部省略してあります。
補助情報としてクロックの設定情報を cat コマンドで参照します。

コマンドハードウェア クロックの設定
UTC の場合ローカル タイム の場合
設定情報
# cat /etc/sysconfig/clock ZONE="Asia/Tokyo"
UTC=true
ZONE="Asia/Tokyo"
UTC=false
# cat /etc/adjtime -10624.509562 1256172955 0.000000
1256172955
UTC
-10624.509562 1256172955 0.000000
1256172955
LOCAL
システム クロック情報 (*1)
# date (*2) 2009年 10月 22日 木曜日 10:16:51 JST 2009年 10月 22日 木曜日 10:16:51 JST
# date --u (*3) 2009年 10月 22日 木曜日 01:17:10 UTC 2009年 10月 22日 木曜日 01:17:10 UTC
ハードウェア クロック情報
# hwclock --show 2009年10月22日 10時18分14秒 (*4) 2009年10月22日 10時18分15秒 (*5)
# hwclock --show --utc 2009年10月22日 10時18分24秒 (*6) 2009年10月22日 19時18分25秒 (*7)
# hwclock --show --localtime 2009年10月22日 01時18分34秒 (*8) 2009年10月22日 10時18分35秒 (*9)

【 表示結果について 】
  • (*1)システム クロックはUTCで管理されています。
    ハードウェア クロックがどちら(UTC or ローカル)の設定であっても常にUTC固定です。
  • (*2)date
    /etc/localtime を参照してUTCとローカル タイムの時差を識別し、補正(+9時間)結果を表示します。
  • (*3)date --u
    システム クロックはUTCなので、取得した時刻情報を無補正で表示します。
  • hwclock --show
    • (*4) 10時18分14秒
      ハードウェア クロックがUTCの場合、/etc/localtime を参照してUTCとローカル タイムの時差を識別し、補正(+9時間)結果を表示します。
    • (*5) 10時18分15秒
      ハードウェア クロックはローカル タイムなので、補正なしで表示します。
  • (*6) 10時18分24秒
    ハードウェア クロックをUTCであると仮定したので、ローカル タイムへの補正(+9時間)が行われます。
    ハードウェアクロックは元々 UTC であり矛盾はないので、表示結果は正常です。
  • (*7) 19時18分25秒
    JSTのハードウェア クロックをUTCであると仮定してローカル タイムを計算(+9時間の補正)させたため、現在時刻より9時間先の未来時刻を表示する結果となっています。
  • (*8) 01時18分34秒
    UTCのハードウェア クロックをローカル タイムであると仮定したため、補正されません。
    現在時刻より9時間前のUTCの時刻を表示する結果となっています。
  • (*9) 01時18分35秒
    ハードウェア クロックをローカル タイムであると仮定したので、補正なしで表示されます。
    ハードウェアクロックは元々JSTであり矛盾はないので、表示結果は正常です。

V.3./etc/adjtime を書き換える

 hwclock コマンドはハードウェア クロックの情報を読み書きしますが、その時 /etc/adjtime を参照してハードウェア クロックがUTCなのかローカル タイムなのかを識別しているようです。
/etc/adjtime
 ハードウェア クロックの時刻を補正するためのデータが、hwclock --set または hwclock --systohc (ハードウェア クロックへの書き込み) が実行されるたびに /etc/adjtime ファイルに記録(更新)されます。
 データには1日当たりに生じるシステム クロックとのズレや、最後に書き込みが行われた時刻等があり、
hwclock --adjust (規則的なズレの補正)が実行される時に参照されます。
 本当に参照しているのか、/etc/adjtime を書き換えたらどうなるのか、検証します。

V.3.1.初期設定

 ハードウェア クロックの初期状態を次のように設定します。
  • タイム ゾーン属性 : UTC
  • 時刻 : 2010年05月23日 10時01分01秒
※ 日時には特に意味はありません。
システムのタイムゾーンは、東京(JST)です。

Linux を起動したら、時刻の初期状態をチェックします。
JSTとUTCの時差は +9:00 時間ですから、表示されるローカル タイムは、UTCより9時間進んだ時刻になっているはずです。
# date
2010年 5月 23日 日曜日 19:03:50 JST
初期設定値(UTC) +09:00 ですから初期値はOKです。

ついでに /etc/adjtime の中身も見ておきます。
# cat /etc/adjtime
-0.072010 1271855284 0.000000
1271855284
UTC
末尾にUTCの記述があります。


V.3.2./etc/adjtime 書き換え

まず、正常状態のハードウェア クロックの時刻を確認します。
# hwclock --show
2010年05月23日 19時04分20秒 -0.954785 秒
 表示時刻は初期状態を確認した date コマンドの時と同じで、正常な読み出しと変換が行われています。

/etc/adjtime の末尾にある UTC を LOCAL に書き換えます。
書き替え後は次のようになります。
# cat /etc/adjtime
-0.072010 1271855284 0.000000
1271855284
LOCAL

 hwclock コマンドが実行のたびに、/etc/adjtime 末尾の UTC/LOCAL を参照してハードウェア クロックのタイム ゾーン属性を識別しているのであれば、その表示時刻は前回とは異なったものになることが予想されます。
確認しましょう。
# hwclock --show
2010年05月23日 10時05分20秒 -0.754810 秒
 表示されたのはハードウェア クロックに設定したUTCの時刻になりました(検証中に4分ほど経過しています)。

 この結果から、hwclock コマンドは /etc/adjtime を参照してハードウェア クロックがローカル タイムで設定されていると誤認識したため、読み出した時刻情報をそのまま(時差補正なしで)表示したものと考えられます。
hwclock コマンドは実行のたびに、/etc/adjtime を参照していることが窺えます。

※ デスクトップの時計表示は、終始 5月23(日) 19:XX で、書き換えによる影響はありません。

【 後処理 】
※ LOCAL に書き換えた /etc/adjtime の末尾を、UTC に戻しておきます。


V.4./etc/localtime を変更する

 date コマンドや hwclock コマンドは時刻情報をローカル タイムに変換する時に
/etc/localtime を参照します(デスクトップの時計も /etc/localtime を参照しています)。
/etc/localtime
 タイム ゾーン関連の情報ファイルで、UTC との時差 (秒単位)、夏時間の 開始/終了 時期等が記録されています。
 元になるファイルは、/usr/share/zoneinfo 配下 <地域ブロック名>ディレクトリ内の 都市・地域名が付いたゾーン ファイル (アジア/東京 の場合 /Asia/Tokyo) で、Linux インストール時あるいはタイム ゾーン変更時に、選択したタイム ゾーンに該当するゾーン ファイルが /etc/localtime として別名コピーされます。
※ ディストリビューションによっては、コピーではなくシンボリック リンクになっています。
 それでは、/etc/localtime を他の地域(タイム ゾーン)のファイルに置き換えたら、あるいは /etc/localtime そのものを削除したら、コマンドや時計が表示する時刻にどんな変化が現れるでしょう。


V.4.1.初期設定

 ハードウェア クロックとタイム ゾーンの初期状態を次のように設定します。
  • ハードウェア クロック
    • タイム ゾーン属性 : UTC
    • 時刻 : 2010年05月23日 10時01分01秒
  • システムのタイム ゾーン : アジア/東京(JST)
※ 日時には特に意味はありません。

Linux を起動したら、時刻の初期状態をチェックしておきます。
各クロックを表示します。システム クロックはUTCも表示しておきます
# hwclock --show
2010年05月23日 19時03分55秒 -0.188488 秒
# date
2010年 5月 23日 日曜日 19:04:01 JST
# date --u
2010年 5月 23日 日曜日 10:04:06 UTC
ローカル タイムは UTC + 9 時間、UTC は初期設定値になっています。
※ ローカル タイム(JST)の UTC との時差は +09:00 です。

 ファイルのタイム スタンプへの影響を見るため TimeStamp を作成し、ls コマンドでタイムスタンプを確認します。
# touch TimeStamp
# ls -l TimeStamp
-rw-r--r-- 1 root root 0  5月 23 19:04 TimeStamp

デスクトップ時計も見ておきます。
 5月23(日) 19:04 

※ /etc/localtime はバイナリ ファイルなので、cat コマンド等では表示できません。

V.4.2./etc/localtime を置き換える

 初期状態の確認が終わったら、/etc/localtime を他のタイム ゾーンのファイルに置き換えてみましょう。  ここでは日本の標準時とは 2 時間の時差がある、バンコック(タイ)のゾーン ファイルを使います。
/usr/share/zoneinfo にある Asia/Bangkok ファイルを /etc/localtime に別名コピーします。
# cp /usr/share/zoneinfo/Asia/Bangkok /etc/localtime
cp: `/etc/localtime' を上書きしてもよろしいですか(yes/no)? y
※ バンコック標準時の略号は ICT で、UTC との時差は +07:00、JST との時差は -02:00 です。

 コマンドがローカル タイムへの変換処理に /etc/localtime を参照しているのであれば、ファイル置き換えの効果は直ちに現れます。
まず、ローカルタイムを確認しましょう。
# hwclock --show
2010年05月23日 17時06分21秒 -0.391225 秒
# date
2010年 5月 23日 日曜日 17:06:27 ICT
 どちらもICTの時刻(UTC + 07:00 : JST より2時間遅れ)で表示されました。これで各コマンドは /etc/localtime を参照してローカル タイムへの変換を行っていることが確認できます。

では、UTC はどうなるでしょう。
# date --u
2010年 5月 23日 日曜日 10:06:33 UTC
 タイム ゾーンを JST としていた初期状態を同じ結果です。  当たり前のことですが、タイム ゾーンを変更してもUTCは常に一定で、ローカル タイムの影響を受けません。

 Linux 起動後に作成したファイル(TimeStamp)のタイム スタンプもチェックしましょう。
ファイル作成時は 5月 23 19:04 でした。
# ls -l TimeStamp
-rw-r--r--  1 root root 0  5月 23 17:04 TimeStamp
 表示されたタイム スタンプには JST と ICT の時差 -02:00 の影響が見られます。
タイム スタンプは UTC で記録されているため、ファイル リスト表示の際に /etc/localtime を参照してローカル タイムに変換しているものと推測できます。
※ TimeStamp 作成日時は、ICT で見れば 5月 23 17:04 ということです。

 デスクトップの時計表示はどうなったでしょう。
/etc/localtime を置き換える直前のデスクトップの時計は  5月23(日) 19:06  でした。
置き替え後の時計表示は  5月23(日) 19:07  になっても JST のままで、ICT の時刻表示になったのは  5月23(日) 17:08  になった時でした。
 X-windows の時計表示モジュールも 1 分程度のタイムラグはありますが、ローカル タイムへの変換に /etc/localtime を参照しているようです。

ログのタイム スタンプ
 OSや各種サービスが記録するログにもタイム スタンプがあり、ローカル タイムで記録されています。
これらログのタイム スタンプも /etc/localtime を参照してローカル タイムに変換した結果であり、
/etc/localtime を他のタイム ゾーンのファイルに置き換えると、記録される日時が直ちに新タイム ゾーンのものに変わります。


V.4.3./etc/localtime を削除する

 時刻表示に関係するコマンド等が /etc/localtime を参照している事は、前項で確認しました。ここでは /etc/localtime を削除したらどうなるかを確認します。

現状を確認しておきましょう。
前項 /etc/localtime の置き換え で、バンコック(ICT)のタイム ゾーンに変更したままですが、このまま進めます。
# hwclock --show
2010年05月23日 17時09分21秒 -0.547156 秒
# date
2010年 5月 23日 日曜日 17:09:27 ICT
# date --u
2010年 5月 23日 日曜日 10:09:33 UTC
# ls -l TimeStamp
-rw-r--r--  1 root root 0  5月 23 17:04 TimeStamp
デスクトップの時計も確認します。
 5月23(日) 17:09 

/etc/localtime を削除します。
# rm -f /etc/localtime

 さて、UTCとローカル タイムの時差情報(補正値)を参照できない場合の、時刻表示はどうなるのでしょう。
早速確認します。
# hwclock --show
2010年05月23日 10時11分10秒 -0.199269 秒
# date
2010年 5月 23日 日曜日 10:11:12 UTC
# date --u
2010年 5月 23日 日曜日 10:11:15 UTC
# ls -l TimeStamp
-rw-r--r-- 1 root root 0 5月 23 10:04 TimeStamp
 すべての時刻がUTCで表示されています。
ローカル タイムを算出しようにも、参照すべき /etc/localtime が存在しないので当たり前の結果ではありますが、エラーにもならないようです。

 デスクトップ時計の表示は /etc/localtime 削除直後は  5月23(日) 17:11  でしたが、1分程度のタイムラグの後に  5月23(日) 10:13  となりUTCの時刻表示なりました。

【 後処理 】
※ 削除した /etc/localtime を元のタイム ゾーン(JST)に戻しておきます。
# cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime



V.5.ハードウェア クロックのタイム ゾーン変更


 ハードウェア クロックは Linux インストール後でも、タイム ゾーン設定(UTC or ローカルタイム)を変更することが可能です。
タイムゾーン設定の変更には、コマンドラインによる方法とGUIツールを使う方法があります。
以下にその手順を示します。

  • コマンドラインによる方法。
    1. vi エディタ等で /etc/sysconfig/clock を開く。
    2. UTCステートメントの設定値を変更する。
      • UTC からローカルタイム(JST)へ変更する場合。
        UTC=true ---> UTC=false
      • ローカルタイム(JST)から UTC へ変更する場合。
        UTC=false ---> UTC=true
    3. 変更を保存しエディタを終了。
    4. PC を再起動する。

  • GUIツールによる方法。
    1. timeconfig コマンドで「タイムゾーンの選択」を起動。
    2. [Tab] キーで、カーソルを「システムクロックでUTCを使用」欄に移動。
    3. 「システムクロックでUTCを使用」欄のチェック (*) を変更する。
      • UTC からローカルタイム(JST) へ変更する場合。
        スペース キーでチェックを外す。
      • ローカルタイム(JST) から UTC へ変更する場合。
        スペース キーでチェックを入れる。
    4. [Tab] キーで、カーソルを[OK] に移動し [Enter] で timeconfig を終了する。
    5. PCを再起動する。

V.6.windows との共存


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

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




≪ previous [[ パソコンの時計 ]]