Python時間モジュールの初心者向けガイド
Pythontime
モジュールは、オブジェクト、数値、文字列など、コードで時間を表す多くの方法を提供します。 また、コード実行中の待機やコードの効率の測定など、時間を表す以外の機能も提供します。
この記事では、time
で最も一般的に使用される関数とオブジェクトについて説明します。
この記事の終わりまでに、次のことができるようになります。
-
エポック、タイムゾーン、夏時間など、日付と時刻の操作の中心となるUnderstandのコアコンセプト
-
フロート、タプル、および
struct_time
を使用したコード内のRepresent時間 -
異なる時間表現間のConvert
-
Suspendスレッド実行
-
perf_counter()
を使用したMeasureコードパフォーマンス
まず、浮動小数点数を使用して時間を表す方法を学習します。
Free Bonus:Click here to get our free Python Cheat Sheetは、データ型、辞書、リスト、Python関数の操作など、Python3の基本を示しています。
秒を使用してPython時間を処理する
アプリケーションでPython時間の概念を管理する方法の1つは、時代の始まりから、つまり特定の開始点から経過した秒数を表す浮動小数点数を使用することです。
それが何を意味するのか、なぜそれが有用なのか、そしてそれを使用してPython時間に基づいてロジックをアプリケーションに実装する方法を詳しく見ていきましょう。
エポック
前のセクションで、時代の始まりからの経過時間を表す浮動小数点数でPython時間を管理できることを学びました。
Merriam-Websterは、時代を次のように定義します。
-
一連の年が計算される一定の時点
-
与えられた日付を基準として計算された時系列表記のシステム
ここで把握する重要な概念は、Pythonの時間を扱う場合、開始点で識別される期間を考慮することです。 コンピューティングでは、この開始点をepochと呼びます。
エポックは、時間の経過を測定できる開始点です。
たとえば、エポックを1970 UTCの1月1日の深夜(WindowsおよびほとんどのUNIXシステムで定義されているエポック)と定義すると、1970年1月2日のUTCの深夜をエポックからの86400
秒として表すことができます。 。
これは、1分に60秒、1時間に60分、1日に24時間あるためです。 1970年1月2日UTCはエポックの1日後なので、基本的な数学を適用してその結果に到達できます。
>>>
>>> 60 * 60 * 24
86400
また、エポック以前の時間を表すことができることに注意することも重要です。 秒数は負の値になります。
たとえば、1969年12月31日のUTCの深夜(1970年1月1日のエポックを使用)を-86400
秒として表します。
1970年1月1日UTCは一般的なエポックですが、コンピューティングで使用される唯一のエポックではありません。 実際、異なるオペレーティングシステム、ファイルシステム、およびAPIは、異なるエポックを使用する場合があります。
前に見たように、UNIXシステムはエポックを1970年1月1日と定義しています。 一方、Win32 APIは、エポックをJanuary 1, 1601として定義します。
time.gmtime()
を使用して、システムのエポックを判別できます。
>>>
>>> import time
>>> time.gmtime(0)
time.struct_time(tm_year=1970, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=1, tm_isdst=0)
この記事のコース全体を通して、gmtime()
とstruct_time
について学習します。 今のところ、time
を使用して、この関数を使用してエポックを検出できることを知っておいてください。
エポックを使用して秒単位で時間を測定する方法について理解したところで、Pythonのtime
モジュールを見て、それがどの機能を提供しているかを確認しましょう。
浮動小数点数としてのPython時間(秒)
まず、time.time()
は、エポックから経過した秒数を返します。 戻り値は、秒の小数部を考慮した浮動小数点数です。
>>>
>>> from time import time
>>> time()
1551143536.9323719
エポックと見なされる基準点は非常に異なる可能性があるため、マシンで取得する数値は非常に異なる場合があります。
Further Reading: Python 3.7ではtime_ns()
が導入されました。これは、エポックからの同じ経過時間を表す整数値を返しますが、秒単位ではなくナノ秒単位です。
時間を秒単位で測定することは、いくつかの理由で役立ちます。
-
フロートを使用して、2つの時点の差を計算できます。
-
フロートは簡単にserializableになります。つまり、データ転送用に保存して、反対側でそのまま出力することができます。
ただし、現在の時刻を文字列で表示したい場合があります。 これを行うには、time()
から取得した秒数をtime.ctime()
に渡すことができます。
ローカル時間を表す文字列としてのPython時間(秒)
前に見たように、エポックからの経過秒数として表されるPython時間をstringに変換することをお勧めします。 これは、ctime()
を使用して行うことができます。
>>>
>>> from time import time, ctime
>>> t = time()
>>> ctime(t)
'Mon Feb 25 19:11:59 2019'
ここでは、現在の時刻を秒単位で変数t
に記録し、t
を引数としてctime()
に渡しました。これにより、同じ時刻の文字列表現が返されます。
Technical Detail:エポックからの秒数を表す引数は、ctime()
の定義によればオプションです。 引数を渡さない場合、ctime()
はデフォルトでtime()
の戻り値を使用します。 したがって、上記の例を単純化できます。
>>>
>>> from time import ctime
>>> ctime()
'Mon Feb 25 19:11:59 2019'
ctime()
によって返される時間の文字列表現(timestampとも呼ばれる)は、次の構造でフォーマットされます。
-
Day of the week:
Mon
(Monday
) -
Month of the year:
Feb
(February
) -
月の日:
25
-
24-hour clock表記を使用した時間、分、秒:
19:11:59
-
年:
2019
前の例は、米国中南部地域のコンピューターからキャプチャされた特定の瞬間のタイムスタンプを表示します。 しかし、オーストラリアのシドニーに住んでいて、同じ瞬間に同じコマンドを実行したとしましょう。
上記の出力の代わりに、次が表示されます。
>>>
>>> from time import time, ctime
>>> t = time()
>>> ctime(t)
'Tue Feb 26 12:11:59 2019'
タイムスタンプのday of week
、day of month
、およびhour
の部分は、最初の例とは異なることに注意してください。
ctime()
によって返されるタイムスタンプは地理的な場所によって異なるため、これらの出力は異なります。
Note:タイムゾーンの概念は物理的な場所に関連していますが、実際に移動しなくても、コンピューターの設定でこれを変更できます。
物理的な場所に依存する時間の表現はlocal timeと呼ばれ、time zonesと呼ばれる概念を利用します。
Note:現地時間はロケールに関連しているため、タイムスタンプは、文字列内の要素の順序や日と月の省略形の翻訳など、ロケール固有の詳細を説明することがよくあります。 ctime()
はこれらの詳細を無視します。
Pythonの時間表現をよりよく理解できるように、タイムゾーンの概念をもう少し詳しく見てみましょう。
タイムゾーンについて
タイムゾーンは、標準化された時間に準拠する世界の地域です。 タイムゾーンは、Coordinated Universal Time(UTC)からのオフセットと、場合によっては夏時間を含めることによって定義されます(これについては、この記事の後半で詳しく説明します)。
Fun Fact:英語を母国語とする場合、「協定世界時」の略語がより明白なCUTではなくUTCである理由を疑問に思うかもしれません。 ただし、フランス語を母国語とする場合は、「Temps UniverselCoordonné」と呼び、別の略語TUCを提案します。
最終的には、International Telecommunication Union and the International Astronomical Union compromised on UTCが正式な略語であるため、言語に関係なく、略語は同じになります。
UTCおよびタイムゾーン
UTCは、世界のすべての計時が同期(または調整)される時間標準です。 それ自体はタイムゾーンではなく、タイムゾーンとは何かを定義する超越的な標準です。
UTC時間は、地球の自転を参照するastronomical timeとatomic clocksを使用して正確に測定されます。
タイムゾーンは、UTCからのオフセットによって定義されます。 たとえば、南北アメリカでは、中央タイムゾーン(CT)はUTCから5〜6時間遅れているため、UTC-5:00またはUTC-6:00の表記を使用しています。
一方、オーストラリアのシドニーは、オーストラリア東部時間帯(AET)に属し、UTC(UTC + 10:00またはUTC + 11:00)よりも10時間または11時間進んでいます。
この違い(UTC-6:00からUTC + 10:00)は、前の例のctime()
からの2つの出力で観察された差異の理由です。
-
中部標準時(CT):
'Mon Feb 25 19:11:59 2019'
-
オーストラリア東部時間(AET):
'Tue Feb 26 12:11:59 2019'
これらの時間は正確に16時間離れており、上記のタイムゾーンオフセットと一致しています。
CTがUTCから5〜6時間遅れるか、AETが10〜11時間遅れることがあるのか疑問に思うかもしれません。 これは、これらのタイムゾーンの一部を含む世界中の一部の地域で夏時間が適用されるためです。
サマータイム
夏の月は一般的に冬の月よりも多くのdaylight hoursを経験します。 このため、一部の地域では、夏時間をより有効に活用するために、春と夏の間に夏時間(DST)を遵守しています。
DSTを遵守する場所では、春の初めに時計が1時間進みます(実質的に1時間失われます)。 その後、秋には、時計が標準時間にリセットされます。
文字SとDは、タイムゾーン表記の標準時間と夏時間を表します。
-
中部標準時(CST)
-
オーストラリア東部夏時間(AEDT)
時刻を現地時間のタイムスタンプとして表す場合、DSTが適用可能かどうかを考慮することが常に重要です。
ctime()
は、夏時間を考慮します。 したがって、前述の出力の差は、次のように正確になります。
-
中部標準時(CST):
'Mon Feb 25 19:11:59 2019'
-
オーストラリアの東部夏時間(AEDT):
'Tue Feb 26 12:11:59 2019'
データ構造を使用してPython時間を処理する
エポック、タイムゾーン、UTCなど、時間の多くの基本的な概念をしっかりと理解できたので、Pythontime
モジュールを使用して時間を表す他の方法を見てみましょう。
タプルとしてのPython時間
Pythonの時間を表すために数値を使用する代わりに、別のプリミティブデータ構造であるtupleを使用できます。
タプルを使用すると、一部のデータを抽象化して読みやすくすることで、時間をもう少し簡単に管理できます。
タプルとして時間を表す場合、タプル内の各要素は時間の特定の要素に対応します。
-
Year
-
1(1月)から12(12月)の範囲の整数としての月
-
月の日
-
0(午前12時)から23(午後11時)の範囲の整数としての時間
-
分
-
第二
-
0(月曜日)から6(日曜日)までの範囲の整数としての曜日
-
年の日
-
次の値を持つ整数としての夏時間。
-
1
は夏時間です。 -
0
は標準時です。 -
-1
は不明です。
-
既に学んだ方法を使用して、2つの異なる方法で同じPython時間を表すことができます。
>>>
>>> from time import time, ctime
>>> t = time()
>>> t
1551186415.360564
>>> ctime(t)
'Tue Feb 26 07:06:55 2019'
>>> time_tuple = (2019, 2, 26, 7, 6, 55, 1, 57, 0)
この場合、t
とtime_tuple
の両方が同じ時間を表しますが、タプルは時間コンポーネントを操作するためのより読みやすいインターフェイスを提供します。
Technical Detail:実際、秒単位のtime_tuple
で表されるPython時間を見ると(この記事の後半でその方法を説明します)、1551186415.0
に解決されることがわかります。 1551186415.360564
ではなくs。
これは、タプルに小数秒を表す方法がないためです。
タプルはPython時間を操作するためのより管理しやすいインターフェースを提供しますが、さらに優れたオブジェクトがあります:struct_time
。
オブジェクトとしてのPython時間
タプルコンストラクトの問題は、単一の秒ベースの数字よりも整理されているにもかかわらず、まだ数字の束のように見えることです。
struct_time
は、Pythonのcollections
モジュールのNamedTuple
を利用して、タプルの番号のシーケンスを有用な識別子に関連付けることにより、これに対する解決策を提供します。
>>>
>>> from time import struct_time
>>> time_tuple = (2019, 2, 26, 7, 6, 55, 1, 57, 0)
>>> time_obj = struct_time(time_tuple)
>>> time_obj
time.struct_time(tm_year=2019, tm_mon=2, tm_mday=26, tm_hour=7, tm_min=6, tm_sec=55, tm_wday=1, tm_yday=57, tm_isdst=0)
Technical Detail:別の言語を使用している場合、struct
とobject
という用語は互いに対立している可能性があります。
Pythonには、struct
というデータ型はありません。 代わりに、すべてがオブジェクトです。
ただし、名前struct_time
は、データ型が実際にはstruct
であるC-based time libraryに由来します。
実際、Pythonのtime
モジュール(implemented in C)は、ヘッダーファイルtimes.h
をインクルードすることにより、このstruct
を直接使用します。
これで、インデックスではなく属性の名前を使用して、time_obj
の特定の要素にアクセスできます。
>>>
>>> day_of_year = time_obj.tm_yday
>>> day_of_year
57
>>> day_of_month = time_obj.tm_mday
>>> day_of_month
26
struct_time
の可読性と使いやすさを超えて、Pythontime
モジュールの多くの関数の戻り値の型であるため、知っておくことも重要です。
秒単位のPython時間をオブジェクトに変換する
Python時間を操作する3つの主要な方法を確認したので、異なる時間データ型を変換する方法を学習します。
時刻データ型間の変換は、時刻がUTC時間か現地時間かによって異なります。
協定世界時(UTC)
エポックは、タイムゾーンではなくUTCを定義に使用します。 したがって、エポックからの経過秒数は、地理的な場所に応じて変わりません。
ただし、struct_time
については同じことが言えません。 Python時間のオブジェクト表現では、タイムゾーンが考慮される場合とされない場合があります。
秒を表すfloatをstruct_time
に変換する方法は2つあります。
-
UTC
-
現地時間
PythonタイムフロートをUTCベースのstruct_time
に変換するために、Pythontime
モジュールはgmtime()
と呼ばれる関数を提供します。
この記事で以前に使用したgmtime()
を確認しました。
>>>
>>> import time
>>> time.gmtime(0)
time.struct_time(tm_year=1970, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=1, tm_isdst=0)
この呼び出しを使用して、システムのエポックを発見しました。 これで、ここで実際に何が起こっているかを理解するためのより良い基盤ができました。
gmtime()
は、エポックからの経過秒数をUTCのstruct_time
に変換します。 この場合、秒数として0
を渡しました。これは、UTCでエポック自体を見つけようとしていることを意味します。
Note:属性tm_isdst
が0
に設定されていることに注意してください。 この属性は、タイムゾーンが夏時間を使用しているかどうかを表します。 UTCはDSTにサブスクライブしないため、gmtime()
を使用する場合、フラグは常に0
になります。
前に見たように、struct_time
は秒の小数部を表すことができないため、gmtime()
は引数の秒の小数部を無視します。
>>>
>>> import time
>>> time.gmtime(1.99)
time.struct_time(tm_year=1970, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=1, tm_wday=3, tm_yday=1, tm_isdst=0)
渡した秒数が2
に非常に近い場合でも、tm_sec=1
で示されているように、.99
の小数秒は単に無視されていることに注意してください。
gmtime()
のsecs
パラメータはオプションです。つまり、引数なしでgmtime()
を呼び出すことができます。 これにより、UTCの現在の時刻が提供されます。
>>>
>>> import time
>>> time.gmtime()
time.struct_time(tm_year=2019, tm_mon=2, tm_mday=28, tm_hour=12, tm_min=57, tm_sec=24, tm_wday=3, tm_yday=59, tm_isdst=0)
興味深いことに、time
内にこの関数の逆関数はありません。 代わりに、Pythonのcalendar
モジュールでtimegm()
という名前の関数を探す必要があります。
>>>
>>> import calendar
>>> import time
>>> time.gmtime()
time.struct_time(tm_year=2019, tm_mon=2, tm_mday=28, tm_hour=13, tm_min=23, tm_sec=12, tm_wday=3, tm_yday=59, tm_isdst=0)
>>> calendar.timegm(time.gmtime())
1551360204
timegm()
はタプル(またはタプルのサブクラスであるためstruct_time
)を取り、エポックからの対応する秒数を返します。
Historical Context:timegm()
がtime
にない理由に興味がある場合は、Python Issue 6280でディスカッションを表示できます。
つまり、time
は、一致する関数を含まないCのタイムライブラリ(time.h
で定義)に厳密に従うため、元々calendar
に追加されました。 上記の問題は、timegm()
をtime
に移動またはコピーするというアイデアを提案しました。
ただし、datetime
ライブラリの進歩、time.timegm()
のパッチ適用された実装の不整合、およびcalendar.timegm()
の処理方法の問題により、メンテナはパッチを拒否し、%の使用を推奨しました。 (t3)s代わりに。
UTCは標準であるため、プログラミングでは価値があります。 DST、タイムゾーン、またはロケール情報について心配する必要はありません。
そうは言っても、現地時間を使いたい場合はたくさんあります。 次に、秒単位から現地時間に変換する方法を確認して、それを実行できるようにします。
現地時間
アプリケーションでは、UTCではなく現地時間で作業する必要がある場合があります。 Pythonのtime
モジュールは、localtime()
と呼ばれるエポックから経過した秒数から現地時間を取得するための関数を提供します。
localtime()
の署名は、オプションのsecs
引数を取り、ローカルタイムゾーンを使用してstruct_time
を構築するために使用するという点で、gmtime()
に似ています。
>>>
>>> import time
>>> time.time()
1551448206.86196
>>> time.localtime(1551448206.86196)
time.struct_time(tm_year=2019, tm_mon=3, tm_mday=1, tm_hour=7, tm_min=50, tm_sec=6, tm_wday=4, tm_yday=60, tm_isdst=0)
tm_isdst=0
に注意してください。 DSTは現地時間に関係するため、tm_isdst
は、DSTが特定の時間に適用可能かどうかに応じて、0
と1
の間で変化します。 tm_isdst=0
以降、DSTは2019年3月1日には適用されません。
2019年の米国では、夏時間は3月10日に始まります。 したがって、DSTフラグが正しく変更されるかどうかをテストするには、secs
引数に9日分の秒を追加する必要があります。
これを計算するには、1日の秒数(86,400)に9日を掛けます。
>>>
>>> new_secs = 1551448206.86196 + (86400 * 9)
>>> time.localtime(new_secs)
time.struct_time(tm_year=2019, tm_mon=3, tm_mday=10, tm_hour=8, tm_min=50, tm_sec=6, tm_wday=6, tm_yday=69, tm_isdst=1)
これで、struct_time
が2019年3月10日をtm_isdst=1
で示していることがわかります。 また、夏時間のために、tm_hour
も前の例の7
ではなく8
にジャンプしていることに注意してください。
Python 3.3以降、struct_time
には、struct_time
のタイムゾーンを決定するのに役立つ2つの属性も含まれています。
-
tm_zone
-
tm_gmtoff
最初は、これらの属性はプラットフォームに依存していましたが、Python 3.6以降、すべてのプラットフォームで利用可能です。
まず、tm_zone
はローカルタイムゾーンを格納します。
>>>
>>> import time
>>> current_local = time.localtime()
>>> current_local.tm_zone
'CST'
ここで、localtime()
がstruct_time
を返し、タイムゾーンがCST
(中部標準時)に設定されていることがわかります。
前に見たように、UTCオフセットとDST(該当する場合)の2つの情報に基づいてタイムゾーンを通知することもできます。
>>>
>>> import time
>>> current_local = time.localtime()
>>> current_local.tm_gmtoff
-21600
>>> current_local.tm_isdst
0
この場合、current_local
はグリニッジ標準時を表すGMTより21600
秒遅れていることがわかります。 GMTは、UTCオフセットのないタイムゾーンです:UTC±00:00。
21600
秒を1時間あたりの秒数(3,600)で割ると、current_local
時間はGMT-06:00
(またはUTC-06:00
)になります。
GMTオフセットとDSTステータスを使用して、中部標準時ゾーンに対応する標準時のcurrent_local
がUTC-06:00
であると推定できます。
gmtime()
と同様に、localtime()
を呼び出すときにsecs
引数を無視でき、現在の現地時間をstruct_time
で返します。
>>>
>>> import time
>>> time.localtime()
time.struct_time(tm_year=2019, tm_mon=3, tm_mday=1, tm_hour=8, tm_min=34, tm_sec=28, tm_wday=4, tm_yday=60, tm_isdst=0)
gmtime()
とは異なり、localtime()
の逆関数はPythontime
モジュールに存在します。 それがどのように機能するかを見てみましょう。
ローカル時間オブジェクトを秒に変換する
calendar.timegm()
を使用してUTC時間オブジェクトを秒に変換する方法についてはすでに説明しました。 現地時間を秒に変換するには、mktime()
を使用します。
mktime()
では、通常の9タプルまたは現地時間を表すstruct_time
オブジェクトの形式をとるt
というパラメーターを渡す必要があります。
>>>
>>> import time
>>> time_tuple = (2019, 3, 10, 8, 50, 6, 6, 69, 1)
>>> time.mktime(time_tuple)
1552225806.0
>>> time_struct = time.struct_time(time_tuple)
>>> time.mktime(time_struct)
1552225806.0
t
は、UTCではなく現地時間を表すタプルである必要があることに注意してください。
>>>
>>> from time import gmtime, mktime
>>> # 1
>>> current_utc = time.gmtime()
>>> current_utc
time.struct_time(tm_year=2019, tm_mon=3, tm_mday=1, tm_hour=14, tm_min=51, tm_sec=19, tm_wday=4, tm_yday=60, tm_isdst=0)
>>> # 2
>>> current_utc_secs = mktime(current_utc)
>>> current_utc_secs
1551473479.0
>>> # 3
>>> time.gmtime(current_utc_secs)
time.struct_time(tm_year=2019, tm_mon=3, tm_mday=1, tm_hour=20, tm_min=51, tm_sec=19, tm_wday=4, tm_yday=60, tm_isdst=0)
Note:この例では、現地時間がMarch 1, 2019 08:51:19 CST
であると想定しています。
この例は、UTCではなく現地時間でmktime()
を使用することが重要である理由を示しています。
-
引数のない
gmtime()
は、UTCを使用してstruct_time
を返します。current_utc
はMarch 1, 2019 14:51:19 UTC
を示します。CST is UTC-06:00
であるため、これは正確です。したがって、UTCは現地時間より6時間進んでいる必要があります。 -
mktime()
は、現地時間を予期して秒数を返そうとしますが、代わりにcurrent_utc
を渡しました。 したがって、current_utc
がUTC時間であると理解する代わりに、March 1, 2019 14:51:19 CST
を意味していると想定します。 -
次に、
gmtime()
を使用してそれらの秒をUTCに変換し直すため、不整合が発生します。 時間はMarch 1, 2019 20:51:19 UTC
になりました。 この不一致の理由は、mktime()
が現地時間を予期しているという事実です。 したがって、UTCに戻すと、現地時間にanotherが6時間追加されます。
タイムゾーンの操作は非常に難しいため、UTCと現地時間の違いと、それぞれに対応するPythonの時間関数を理解することで、成功に備えることが重要です。
Python Timeオブジェクトを文字列に変換する
タプルでの作業は楽しくてすべてですが、場合によっては文字列で作業するのが最善です。
タイムスタンプとしても知られる時間の文字列表現は、時間を読みやすくするのに役立ち、直感的なユーザーインターフェイスの構築に特に役立ちます。
time.struct_time
オブジェクトを文字列に変換するために使用する2つのPythontime
関数があります。
-
asctime()
-
strftime()
まず、 `asctime()`について学習します。
asctime()
タイムタプルまたはstruct_time
をタイムスタンプに変換するには、asctime()
を使用します。
>>>
>>> import time
>>> time.asctime(time.gmtime())
'Fri Mar 1 18:42:08 2019'
>>> time.asctime(time.localtime())
'Fri Mar 1 12:42:15 2019'
gmtime()
とlocaltime()
はどちらも、UTCと現地時間でそれぞれstruct_time
インスタンスを返します。
asctime()
を使用して、いずれかのstruct_time
をタイムスタンプに変換できます。 asctime()
は、この記事の前半で学習したctime()
と同様に機能しますが、浮動小数点数を渡す代わりにタプルを渡す点が異なります。 タイムスタンプ形式でさえ、2つの関数間で同じです。
ctime()
と同様に、asctime()
のパラメーターはオプションです。 時間オブジェクトをasctime()
に渡さない場合、現在の現地時間を使用します。
>>>
>>> import time
>>> time.asctime()
'Fri Mar 1 12:56:07 2019'
ctime()
と同様に、ロケール情報も無視します。
asctime()
の最大の欠点の1つは、フォーマットの柔軟性がないことです。 strftime()
は、タイムスタンプをフォーマットできるようにすることで、この問題を解決します。
strftime()
ctime()
とasctime()
の文字列形式では、アプリケーションにとって不十分な状況に陥る可能性があります。 代わりに、ユーザーにとってより意味のある方法で文字列をフォーマットすることをお勧めします。
これの一例は、ロケール情報を考慮した文字列で時間を表示したい場合です。
文字列をフォーマットするには、struct_time
またはPythonの時間タプルを指定して、「文字列format時間」を表すstrftime()
を使用します。
strftime()
は2つの引数を取ります:
-
format
は、文字列内の時間要素の順序と形式を指定します。 -
t
は、オプションの時間タプルです。
文字列をフォーマットするには、directivesを使用します。 ディレクティブは、次のような特定の時間要素を指定する%
で始まる文字シーケンスです。
-
%d
:月の日 -
%m
:月 -
%Y
:年
たとえば、次のようにISO 8601標準を使用して、現地時間で日付を出力できます。
>>>
>>> import time
>>> time.strftime('%Y-%m-%d', time.localtime())
'2019-03-01'
Further Reading: Pythonの時刻を使用して日付を表すことは完全に有効で受け入れられますが、Pythonのdatetime
モジュールの使用も検討する必要があります。このモジュールは、日付と時刻を一緒に操作するためのショートカットとより堅牢なフレームワークを提供します。
たとえば、datetime
を使用して、ISO8601形式での日付の出力を簡略化できます。
>>>
>>> from datetime import date
>>> date(year=2019, month=3, day=1).isoformat()
'2019-03-01'
前に見たように、asctime()
よりもstrftime()
を使用することの大きな利点は、ロケール固有の情報を利用するタイムスタンプをレンダリングできることです。
たとえば、ロケールに依存する方法で日付と時刻を表現する場合は、asctime()
を使用できません。
>>>
>>> from time import asctime
>>> asctime()
'Sat Mar 2 15:21:14 2019'
>>> import locale
>>> locale.setlocale(locale.LC_TIME, 'zh_HK') # Chinese - Hong Kong
'zh_HK'
>>> asctime()
'Sat Mar 2 15:58:49 2019'
プログラムでロケールを変更した後でも、asctime()
は以前と同じ形式で日付と時刻を返すことに注意してください。
Technical Detail:LC_TIME
は、日付と時刻のフォーマットのロケールカテゴリです。 locale
引数'zh_HK'
は、システムによって異なる場合があります。
ただし、strftime()
を使用すると、ロケールを説明していることがわかります。
>>>
>>> from time import strftime, localtime
>>> strftime('%c', localtime())
'Sat Mar 2 15:23:20 2019'
>>> import locale
>>> locale.setlocale(locale.LC_TIME, 'zh_HK') # Chinese - Hong Kong
'zh_HK'
>>> strftime('%c', localtime())
'六 3/ 2 15:58:12 2019' 2019'
ここでは、strftime()
を使用したため、ロケール情報を正常に利用できました。
Note:%c
は、ロケールに適した日付と時刻のディレクティブです。
タイムタプルがパラメーターt
に渡されない場合、strftime()
はデフォルトでlocaltime()
の結果を使用します。 したがって、オプションの2番目の引数を削除することで、上記の例を単純化できます。
>>>
>>> from time import strftime
>>> strftime('The current local datetime is: %c')
'The current local datetime is: Fri Mar 1 23:18:32 2019'
ここでは、独自の引数を引数として渡す代わりに、デフォルトの時間を使用しています。 また、format
引数は、書式設定ディレクティブ以外のテキストで構成できることに注意してください。
Further Reading:strftime()
が利用できるこの完全なlist of directivesを確認してください。
Pythontime
モジュールには、タイムスタンプをstruct_time
オブジェクトに変換する逆の操作も含まれています。
Python時間文字列をオブジェクトに変換する
日付と時刻に関連する文字列を使用している場合、タイムスタンプを時刻オブジェクトに変換することは非常に価値があります。
時間文字列をstruct_time
に変換するには、「文字列parse時間」を表すstrptime()
を使用します。
>>>
>>> from time import strptime
>>> strptime('2019-03-01', '%Y-%m-%d')
time.struct_time(tm_year=2019, tm_mon=3, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=4, tm_yday=60, tm_isdst=-1)
strptime()
の最初の引数は、変換するタイムスタンプである必要があります。 2番目の引数は、タイムスタンプが含まれるformat
です。
format
パラメータはオプションであり、デフォルトは'%a %b %d %H:%M:%S %Y'
です。 したがって、その形式のタイムスタンプがある場合、引数として渡す必要はありません。
>>>
>>> strptime('Fri Mar 01 23:38:40 2019')
time.struct_time(tm_year=2019, tm_mon=3, tm_mday=1, tm_hour=23, tm_min=38, tm_sec=40, tm_wday=4, tm_yday=60, tm_isdst=-1)
struct_time
には9つの主要な日付と時刻のコンポーネントがあるため、strptime()
は、string
から解析できないコンポーネントの値に適切なデフォルトを提供する必要があります。
前の例では、tm_isdst=-1
です。 つまり、strptime()
は、タイムスタンプによって夏時間を表すかどうかを判断できません。
これで、さまざまな方法でtime
モジュールを使用してPythonの時刻と日付を操作する方法がわかりました。 ただし、time
の用途は、単に時間オブジェクトを作成する、Pythonの時間文字列を取得する、エポックから経過した秒数を使用する以外にもあります。
実行の一時停止
本当に便利なPython時間関数の1つは、sleep()
です。これは、指定された時間、スレッドの実行を一時停止します。
たとえば、次のようにプログラムの実行を10秒間中断できます。
>>>
>>> from time import sleep, strftime
>>> strftime('%c')
'Fri Mar 1 23:49:26 2019'
>>> sleep(10)
>>> strftime('%c')
'Fri Mar 1 23:49:36 2019'
プログラムは、最初にフォーマットされたdatetime
文字列を出力し、次に10秒間一時停止し、最後に2番目にフォーマットされたdatetime
文字列を出力します。
分数秒をsleep()
に渡すこともできます。
>>>
>>> from time import sleep
>>> sleep(0.5)
sleep()
は、何らかの理由でプログラムをテストまたは待機させるのに役立ちますが、正当な理由がない限り、本番コードを停止しないように注意する必要があります。
Python 3.5より前では、プロセスに送信されたシグナルがsleep()
を中断する可能性がありました。 ただし、3.5以降では、プロセスがシグナルを受信した場合でも、sleep()
は常に少なくとも指定された時間だけ実行を一時停止します。
sleep()
は、プログラムをテストしてより堅牢にするのに役立つPython時間関数の1つにすぎません。
性能測定
time
を使用して、プログラムのパフォーマンスを測定できます。
これを行う方法は、perf_counter()
を使用することです。これは、名前が示すように、短い時間の距離を測定するための高解像度のパフォーマンスカウンターを提供します。
perf_counter()
を使用するには、コードの実行を開始する前と、コードの実行が完了した後にカウンターを配置します。
>>>
>>> from time import perf_counter
>>> def longrunning_function():
... for i in range(1, 11):
... time.sleep(i / i ** 2)
...
>>> start = perf_counter()
>>> longrunning_function()
>>> end = perf_counter()
>>> execution_time = (end - start)
>>> execution_time
8.201258441999926
まず、start
は、関数を呼び出す前の瞬間をキャプチャします。 end
は、関数が戻った後の瞬間をキャプチャします。 関数の合計実行時間は(end - start)
秒かかりました。
Technical Detail: Python 3.7ではperf_counter_ns()
が導入されました。これはperf_counter()
と同じように機能しますが、秒ではなくナノ秒を使用します。
perf_counter()
(またはperf_counter_ns()
)は、1回の実行を使用してコードのパフォーマンスを測定する最も正確な方法です。 ただし、コードスニペットのパフォーマンスを正確に測定しようとしている場合は、Python timeit
モジュールを使用することをお勧めします。
timeit
は、コードを何度も実行してより正確なパフォーマンス分析を行うことを専門としており、時間測定やその他の一般的な落とし穴を単純化しすぎないようにするのに役立ちます。
結論
おめでとうございます。 これで、Pythonで日付と時刻を操作するための優れた基盤ができました。
現在、次のことができます。
-
エポックから経過した秒数を表す浮動小数点数を使用して、時間を処理します
-
タプルと
struct_time
オブジェクトを使用して時間を管理する -
秒、タプル、およびタイムスタンプ文字列間の変換
-
Pythonスレッドの実行を一時停止する
-
perf_counter()
を使用してパフォーマンスを測定する
さらに、次のような日付と時刻に関する基本的な概念を学びました。
-
エポック
-
UTC
-
時間帯
-
サマータイム
これで、Python時間に関する新たな知識を実際のアプリケーションに適用するときが来ました!