Python時間モジュールの初心者向けガイド

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とも呼ばれる)は、次の構造でフォーマットされます。

  1. Day of the week:MonMonday

  2. Month of the year:FebFebruary

  3. 月の日: 25

  4. 24-hour clock表記を使用した時間、分、秒: 19:11:59

  5. 年: 2019

前の例は、米国中南部地域のコンピューターからキャプチャされた特定の瞬間のタイムスタンプを表示します。 しかし、オーストラリアのシドニーに住んでいて、同じ瞬間に同じコマンドを実行したとしましょう。

上記の出力の代わりに、次が表示されます。

>>>

>>> from time import time, ctime
>>> t = time()
>>> ctime(t)
'Tue Feb 26 12:11:59 2019'

タイムスタンプのday of weekday 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 timeatomic 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を使用できます。

タプルを使用すると、一部のデータを抽象化して読みやすくすることで、時間をもう少し簡単に管理できます。

タプルとして時間を表す場合、タプル内の各要素は時間の特定の要素に対応します。

  1. Year

  2. 1(1月)から12(12月)の範囲の整数としての月

  3. 月の日

  4. 0(午前12時)から23(午後11時)の範囲の整数としての時間

  5. 第二

  6. 0(月曜日)から6(日曜日)までの範囲の整数としての曜日

  7. 年の日

  8. 次の値を持つ整数としての夏時間。

    • 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)

この場合、ttime_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:別の言語を使用している場合、structobjectという用語は互いに対立している可能性があります。

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つあります。

  1. UTC

  2. 現地時間

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_isdst0に設定されていることに注意してください。 この属性は、タイムゾーンが夏時間を使用しているかどうかを表します。 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が特定の時間に適用可能かどうかに応じて、01の間で変化します。 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つの属性も含まれています。

  1. tm_zone

  2. 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_localUTC-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()を使用することが重要である理由を示しています。

  1. 引数のないgmtime()は、UTCを使用してstruct_timeを返します。 current_utcMarch 1, 2019 14:51:19 UTCを示します。 CST is UTC-06:00であるため、これは正確です。したがって、UTCは現地時間より6時間進んでいる必要があります。

  2. mktime()は、現地時間を予期して秒数を返そうとしますが、代わりにcurrent_utcを渡しました。 したがって、current_utcがUTC時間であると理解する代わりに、March 1, 2019 14:51:19 CSTを意味していると想定します。

  3. 次に、gmtime()を使用してそれらの秒をUTCに変換し直すため、不整合が発生します。 時間はMarch 1, 2019 20:51:19 UTCになりました。 この不一致の理由は、mktime()が現地時間を予期しているという事実です。 したがって、UTCに戻すと、現地時間にanotherが6時間追加されます。

タイムゾーンの操作は非常に難しいため、UTCと現地時間の違いと、それぞれに対応するPythonの時間関数を理解することで、成功に備えることが重要です。

Python Timeオブジェクトを文字列に変換する

タプルでの作業は楽しくてすべてですが、場合によっては文字列で作業するのが最善です。

タイムスタンプとしても知られる時間の文字列表現は、時間を読みやすくするのに役立ち、直感的なユーザーインターフェイスの構築に特に役立ちます。

time.struct_timeオブジェクトを文字列に変換するために使用する2つのPythontime関数があります。

  1. asctime()

  2. 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つの引数を取ります:

  1. formatは、文字列内の時間要素の順序と形式を指定します。

  2. 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時間に関する新たな知識を実際のアプリケーションに適用するときが来ました!

参考文献

Pythonでの日付と時刻の使用についてさらに学習したい場合は、次のモジュールをご覧ください。

  • datetime:Pythonの標準ライブラリにあるより堅牢な日付と時刻のモジュール

  • timeit:コードスニペットのパフォーマンスを測定するためのモジュール

  • astropy:天文学で使用されるより高精度の日時