ログ記録、データベースへのレコード保存、ファイルへのアクセスは、プログラマがよく行う作業です。いずれの場合も、データの意味と整合性を保つために、日付と時刻が重要な役割を果たします。プログラマはしばしば日付と時刻に関わる必要があります。
この記事では、Pythonの組み込みモジュールであるdatetimeを使って、現在の日付と時刻を取得する方法を学びます。このモジュールでは、関連するすべてのデータを1つのオブジェクトで取得したり、日付と時刻を別々に抽出したりすることができます。
また、異なるタイムゾーンのために日付と時刻を調整する方法についても学びます。最後に、datetime
オブジェクトを一般的なUnixやEpochのタイムスタンプに変換する方法について見ていきます。
datetimeで現在の日時を取得する
datetime` モジュールは、日付と時刻に関する情報を取得するためのさまざまなクラスを持っています。
-
datetime.date
: *datetime.date
: 日、月、年、または日付を格納する -
datetime.time
: 時刻を時、分、秒単位で格納する。*datetime.time
: 時、分、秒、マイクロ秒の単位で時間を格納する。この情報は、どの日付からも独立しています。 -
datetime.datetime
: 時刻を時、分、秒、マイクロ秒の単位で格納する。日付と時刻
の両方の属性を保持する。
ここでは、 datetime.datetime
オブジェクトを用いて、現在の日付と時刻を取得することにしよう。このオブジェクトから date
と time
オブジェクトを抽出するのは簡単である。まず、 datetime
モジュールをインポートしましょう。
from datetime import datetime
最初は奇妙に見えますが、 datetime
モジュールから datetime
クラスを取得しているのであって、これらは別物です。
現在の日付と時刻を持つオブジェクトを取得するには、 now()
関数を使用します。
current_datetime = datetime.now()
print(current_datetime)
このファイルを実行すると、次のような出力が得られます。
2019-12-13 12:18:18.290623
この now()
関数はオブジェクトが作成された時の日付と時刻をすべて含むオブジェクトを提供します。これを表示するとき、Pythonは自動的にオブジェクトを文字列に整形し、人間が簡単に読めるようにします。時刻を表示するさまざまな方法については、Pythonで日付をフォーマットする方法 を参照してください。
このように、日付と時刻の個々の属性を取得することができます。
print(current_datetime.year) # 2019
print(current_datetime.month) # 12
print(current_datetime.day) # 13
print(current_datetime.hour) # 12
print(current_datetime.minute) # 18
print(current_datetime.second) # 18
print(current_datetime.microsecond) # 290623
now()` メソッドは一瞬を切り取るには最適なメソッドです。しかし、日付か時刻のどちらか一方にしか関心がなく、両方には関心がない場合には冗長です。どうすれば日付の情報だけを得ることができるでしょうか?
現在の日付の取得
Python で現在の日付を取得する方法は 2 つあります。Python コンソールでは、 date()
メソッドを使って datetime
オブジェクトから日付を取得することができます。
>>> from datetime import datetime
>>> current_date = datetime.now().date()
>>> print(current_date)
2019-12-13
しかし、日付を取得するためだけに datetime
オブジェクトを初期化するのは無駄なように思えます。代替案としては、 date
クラスの today()
メソッドを使用することです。
>>> from datetime import date
>>> current_date = date.today()
>>> print(current_date)
2019-12-13
datetime.dateクラスはカレンダーの日付を表します。その
year,
month,
day属性は
datetime` オブジェクトと同じようにアクセスすることができます。
例えば、この print
文はそれぞれの属性を取得し、さらに weekday()
メソッドを使用して曜日を取得します。
>>> print("It's the %dth day of the week, %dth day of the %dth month of the %dth year" %
... (current_date.weekday()+1, current_date.day, current_date.month, current_date.year))
It's the 5th day of the week, 13th day of the 12th month of the 2019th year
Note: weekday()
メソッドは、曜日を表す 0 から 6 までの整数を返します。0 は月曜日に相当します。したがって、この例では weekday()
メソッドは 4 を返しますが、5番目の曜日 (金曜日) を表示するために 1 を追加しています。
これで現在の日付を取得できるようになったので、次は現在の時刻を取得する方法を見てみましょう。
現在時刻の取得
ここでは、time()
メソッドを用いて datetime
オブジェクトから現在の時刻を取得します。
>>> from datetime import datetime
>>> current_time = datetime.now().time()
>>> print(current_time)
12:18:18.290623
日付の取得とは異なり、現在の時刻を直接取得するためのショートカットはありません。datetime.time` クラスは、時間の概念を時間、分、秒、マイクロ秒 (1日未満の時間) で表現します。
datetimeオブジェクトと同様に、その属性に直接アクセスすることができます。以下は、文中の
current_time` を表示する例である。
>>> print("It's %d o'clock. To be exact, it's %d:%d and %d seconds with %d microseconds" %
... (current_time.hour, current_time.hour, current_time.minute, current_time.second, current_time.microsecond))
It's 12 o'clock. To be exact, it's 12:18 and 18 seconds with 290623 microseconds
デフォルトでは、 now()
関数はあなたのローカルタイムゾーンの時刻を返します。もし、ユーザーの設定によって異なるタイムゾーンに変換する必要がある場合はどうすればよいでしょうか。ここでは、ローカライズされた time
オブジェクトを取得するために、どのようにタイムゾーンの情報を提供すればよいかを見てみましょう。
異なるタイムゾーンで現在の日付と時刻を取得する
Now()メソッドは引数としてタイムゾーンを受け取るので、生成される
datetime` オブジェクトは適切に調整されます。まず、pytzライブラリを使ってタイムゾーンのデータを取得する必要があります。
pipを使って
pytz` ライブラリをインストールします(まだインストールされていない場合)。
$ pip3 install pytz
では、pytz
を使って、ベルリンにいる場合の現在の日付と時刻を取得してみましょう。
>>> import pytz
>>> from datetime import datetime
>>> tz = pytz.timezone('Europe/Berlin')
>>> berlin_current_datetime = datetime.now(tz)
>>> print(berlin_current_datetime)
2019-12-14 00:20:50.840350+01:00
berlin_current_datetimeは先ほど見たすべてのプロパティと関数を持つ
datetime` オブジェクトになりますが、これはベルリンに住んでいる人にとってのものと完全に一致するようになりました。
もし、UTCで時刻を取得したい場合は、以前のように pytz
モジュールを使用することができます。
>>> import pytz
>>> from datetime import datetime
>>> utc_current_datetime = datetime.now(pytz.timezone("UTC"))
>>> print(utc_current_datetime)
2019-12-13 23:20:50.840350+00:00
また、UTCの時刻を取得する場合は、 pytz
モジュールを使用する必要はありません。datetimeモジュールには
timezone` プロパティがあり、次のように使用することができます。
>>> from datetime import datetime, timezone
>>> utc_current_datetime = datetime.now(timezone.utc)
>>> print(utc_current_datetime)
2019-12-13 23:20:50.840350+00:00
さて、日付と時刻をさまざまなタイムゾーンに合わせて変換できるようになったところで、コンピュータで最も広く使われている形式の1つであるUnixタイムスタンプに変換する方法を見ていきましょう。
タイムスタンプを日付と時刻に変換する
コンピュータシステムは、Unixエポック、つまり1970年1月1日00:00:00 UTCからの経過秒数に基づいて時間を測定します。アプリケーション、データベース、プロトコルでは、時間を表示するためにタイムスタンプを使用することが一般的です。
Pythonでは、time
ライブラリを使って現在のタイムスタンプを取得することができます。
>>> import time
>>> print(time.time())
1576280665.0915806
time.time()関数はUnixのタイムスタンプをfloatで返します。また、
fromtimestamp()関数を使うと、タイムスタンプを
datetime` オブジェクトに変換することができます。
>>> from datetime import datetime
>>> print(datetime.fromtimestamp(1576280665))
2019-12-13 19:44:25
デフォルトでは、 fromtimestamp()
はあなたのタイムゾーンの datetime
オブジェクトを返します。別のローカライズを行いたい場合は、第二引数でタイムゾーンを指定することができます。
例えば、タイムスタンプを UTC で datetime
オブジェクトに変換するには、次のようにします。
>>> from datetime import datetime, timezone
>>> print(datetime.fromtimestamp(1576280665, timezone.utc))
2019-12-13 19:44:25+00:00
逆に、 timestamp()
メソッドを使用して、 datetime
オブジェクトを有効なタイムスタンプに変換することができます。
>>> from datetime import datetime, timezone
>>> print(datetime.now(timezone.utc).timestamp())
1577117555.940705
結論
Python の組み込みライブラリ datetime
では、 now()
関数で現在の日付と時刻を取得することができます。返された datetime
オブジェクトを使って、日付の部分だけ、または時刻の部分だけを取り出すことができます。また、 today()
関数を用いて、現在の日付を取得することもできます。
デフォルトでは、Pythonはローカルのタイムゾーンの datetime
オブジェクトを生成します。pytz` ライブラリを利用すれば、日付と時刻を異なるタイムゾーンに変換することができます。
最後に、 fromtimestamp()
関数を使用して、Unix タイムスタンプを取得して datetime
オブジェクトを生成しました。datetimeオブジェクトがあれば、その
timestamp()` メソッドでタイムスタンプを取得することができます。