日付と時間
このページではPythonでの時間と日付の扱いについてまとめておく(ここはまだ書きかけ)。
コンピュータの時計
コンピュータの内部には独立した時計の機能がハードウェアとして組み込まれており、そこから日時を読み出したり、設定したりすることができるようになっている場合がほとんどである。こうしたコンピュータ内の時計は、一般的な時計と同様、水晶発振器など正確な時間間隔を刻む素子によって駆動されてはいるものの、単体では少しずつずれてしまう。
現在では、多くのコンピュータがネットワークに接続されているため、正確な時計を内蔵したサーバーに問い合わせることで、自らの時計を自動修正するようになっている場合が多い。 そのための標準的な手順がNTP(Network Time Protocol)である。 Windows 10では、Windowsの設定 → 時刻と言語 → 日付と時刻 を開き、「時刻を自動的に設定する」によって、NTPサーバーとの同期が行われる。 macOSの場合は、システム環境設定 → 日付と時刻 の「日付と時刻を自動的に設定」の項目がそれに相当する。 NTPサーバーは世界中に多数存在しており、OSの種類や地域毎に推奨されている設定に従う(通常は、適切なデフォルト値が設定されている)。
時刻の表現
時刻の自然な表現方法は、起点となる日時を設け、そこからの長さ(秒数)を数える方法である。 実際に多くのソフトウェア では、1970日1月1日午前0時を起点として、そこからの経過秒数によって時間を表現している(UNIX時間)。 ところが、実際の暦ではときおり閏秒が発生しているため、実際の経過秒数から日時を計算すると、暦とずれてしまう。 そこで、UNIX時間から日時を算出する場合には、その間のうるう秒を考慮して、暦と整合するよう計算するような仕組みが組み込まれているのが通常である。
従来型のハードウェアで多く用いられていた(符号付き)32ビット整数で秒数を表すと、2038年で、その表現できる最大値を超えてしまうため、旧型の情報通信機器の誤動作が懸念されている(2038年問題)
Pythonでの日付と時間の扱い
Pythonで日付と時間を扱う際には、標準的な機能である timeモジュールや datetimeモジュールが利用できる。
これらを使った、誕生日を入力すると、現在まで何日が経過したか、およびその時点のUnix時間を表示するコードの例を以下に示す:
# coding:utf-8 from datetime import datetime birthday = input("input your birthday (yyyy/dd/mm):") bd = datetime.strptime(birthday,'%Y/%m/%d') now = datetime.now() delta = now - bd print("You lived",delta.days,"days since you were born.") print("Current Unix time is",now.timestamp())
解説: Pythonは人類滅亡をカウントダウンできるか
Pythonのdatetimeモジュールで表現できる西暦の最大値は datetime.MAXYEAR
で得られる:
import datetime print(datetime.MAXYEAR)
実際にPython 3で実行すると 9999 と表示される。
また、Unix時間の秒数を符号付きの64ビット整数で表現したとすると、最大で
人類滅亡までのカウントダウンプログラムを作成するとして、Pythonの処理系や現在のコンピュータはそれに必要な時間を扱うことができるのだろうか。そのためには、人類滅亡までの時間を見積もる必要がある。
例えば、核戦争による人類の危機を象徴的に表現した世界終末時計は、警鐘を鳴らすことが主な目的なので、その針は進んだり戻ったりしており、我々の残り時間の予測には使えそうもない。
ここから先は、定説というわけでは無いので、話半分で読んでください。
そこで、色々な事物の余命を推定したGottによる議論を少し焼き直して考察してみよう。
種の絶滅が何らかのランダムなイベント(パンデミックや環境の急激な変動等)で生じるとすれば、イベント間の時間間隔は(第0近似としては)指数分布に従うと考えるのが自然である(不安定原子核の崩壊のようなもの、と、考える)。
人類に対してそういったイベントがどれくらいの頻度で生じるかは不明であるが、その平均間隔を
人類に近いネアンデルタール人は40万年程度の期間で絶滅したらしい。一方、チンパンジーは約500万年前に、系統樹の上で、枝分かれしたと言われ、現在まで生存している。とすれば、上記の
次に、人類誕生から、我々は
他方で、
(1), (2), (3)式を使うと、ベイズの定理から
(4)式より、人類が
言うまでもなく、ここでの推定は、
ここで、仮に、
つまり、上記の見積もりが正しければ、95%の確率でこれまでの9倍程度の期間内に、すなわち
SciPyの機能を使って、(6)式の根を数値的に求めるコードの例。
# coding: utf-8 import math import numpy as np from scipy import optimize,integrate def Li1(x): val,err = integrate.quad(lambda t:1/t*math.exp(-t*x),1,np.inf) return val def G(x): L=100 t=20 val,err = integrate.quad(lambda T:1/T*math.exp(-T/L), t,t*x) return val/Li1(t/L) - 0.95 roots = optimize.fsolve(G,1) print("Roots=",roots)
以上をまとめると、Python 3のdatetimeモジュールで表現できる年数(9999)は、未来の我々にとっては不十分と思われる。 一方、64ビットの整数で表現したUnix時間を使えば、人類滅亡までのカウントダウン(アップ?)は十分に可能と予想できる。
別の議論の例
人類の存続期間
ここで、
解説: 原子の寿命と無記憶性
時刻
半減期を
よく考えると、これは少なからず不思議な気がする。 というのは、原発などで生成されたばかりの「真新しい」放射性の原子と、崩壊しないまま長年残存していた原子核との間に全く違いはなく、 「長生き」した原子核のほうが崩壊しやすい、といった傾向は一切ない、と言っているからである。 言い換えれば、原子は自分の過去を全く覚えていない、ということになる(無記憶性)。
この様子をもう少し詳しく考えてみよう。
時間の原点をどこかに設け、原子の崩壊のようなイベント起こる時刻を
そして、
イベントが発生する確率密度が指数分布の場合、すなわち
すなわち、指数分布に従ってランダムに生じるイベントでは、条件付き確率は
逆に、無記憶性の条件
練習:バスの待ち時間
あるバス停では、バスが到着するまでの時間間隔が指数分布に従っていることが分かっている(平均間隔は10分とする)。 あなたがバス停に来た時点ですでに人が並んでいたので、列の先頭の人に尋ねると、「5分間そこで待っている」と教えてもらった。
あなたはそのバス停で平均あと何分待たなければならないか、考えてみなさい。