Python で文字列を日時に変換する

概要

データはさまざまな形式で表すことができます。日付と時刻を表す便利な方法は次のとおりです。 ストリング. ただし、これらの日付と時刻を算術的に処理するには (時差の計算、時刻の追加または削除など)、それらを に変換する必要があります。 datetime オブジェクト。

最も一般的なソースの XNUMX つ 文字列形式の日時 不可知論的な文字列を返す REST API であり、それを他の形式に変換できます。

さらに、タイムゾーンは、datetime オブジェクトを操作する際の一般的な頭痛の種であるため、変換中にも考慮する必要があります。

このガイドでは、文字列の日付/時刻を datetime ビルトインを使用した Python のオブジェクト datetime モジュールだけでなく、次のようなサードパーティのモジュールも dateutil, arrow そしてマヤ、タイムゾーンを説明します。

日時を使用した文字列の変換

  日付時刻 モジュールは、次の XNUMX つの異なるオブジェクト タイプで構成されます。 date, time, datetimeを選択します。 date オブジェクトは日付を保持し、 time 時間を保持し、 datetime 日付と時刻の両方を保持します!

import datetime
print(f'Current date/time: {datetime.datetime.now()}')

このコードを実行すると、次の結果になります。

Current date/time: 2022-12-01 10:27:03.929149

カスタム形式が指定されていない場合、デフォルトの文字列形式が使用されます。つまり、「2022-12-01 10:27:03.929149」の形式は ISO 8601 形式でアーカイブしたプロジェクトを保存します. (YYYY-MM-DDTHH:MM:SS.mmmmmm). 入力文字列を作成する場合 datetime オブジェクトが同じ ISO 8601 形式であるか、事前に受信する形式がわかっている場合は、簡単に解析して datetime オブジェクト:

import datetime

date_time_str = '2022-12-01 10:27:03.929149'

date_time_obj = datetime.datetime.strptime(date_time_str, '%Y-%m-%d %H:%M:%S.%f')

print('Date:', date_time_obj.date())
print('Time:', date_time_obj.time())
print('Date-time:', date_time_obj)

それを実行すると、日付、時刻、および日時が出力されます。

Date: 2022-12-01
Time: 10:27:03.929149
Date-time: 2022-12-01 10:27:03.929149

ここでは、 strptime() このメソッドは、次の XNUMX つの引数を受け取ります。

  • 文字列形式の日付
  • 最初の引数の形式

このようにフォーマットを指定すると、解析がはるかに高速になります。 datetime フォーマットを独自に解釈しようとする必要はありません。これは、計算コストがはるかに高くなります。 戻り値の型は datetime.

この例では、 "2022-12-01 10:27:03.929149" 入力文字列であり、 "%Y-%m-%d %H:%M:%S.%f" 日付文字列の形式です。 返された datetime 値は次のように保存されます date_time_obj.

これは datetime オブジェクト、私たちは呼び出すことができます date() & time() その上に直接メソッド。 出力からわかるように、入力文字列の「日付」と「時刻」の部分が出力されます!

フォーマットトークン

少し時間をかけて理解する価値があります フォーマットトークン - "%Y-%m-%d %H:%M:%S.%f" 前から。

各トークンは、日、月、年、日、週など、日時のさまざまな部分を表します。 サポートされているトークンのリスト さまざまな書式設定を有効にするのに十分な広さです。 以前にも使用した、一般的に使用されるもののいくつかは次のとおりです。

  • %Y:年(4桁)
  • %m: 月
  • %d:日
  • %H:時(24時間)
  • %M: 分
  • %S: 秒
  • %f: マイクロ秒

注: 年を除くこれらのトークンはすべてゼロで埋められることが期待されます (つまり、8 月は XNUMX 番目の月であり、 08).

strptime() 形式トークンを使用して文字列を異なる日時形式に変換する

文字列の形式がわかっている場合は、簡単に解析して datetime 使用するオブジェクト strptime(). ある形式から別の形式に変換する重要な例を見てみましょう。

import datetime

date_time_str = 'Jul 17 2022 9:20AM'
date_time_obj = datetime.datetime.strptime(date_time_str, '%b %d %Y %I:%M%p')

print('Date:', date_time_obj.date())
print('Time:', date_time_obj.time())
print('Date-time:', date_time_obj)

入力文字列は、「17 年 2022 月 9 日 20:8601 午前」という XNUMX つの形式でした。 この形式を知っていたので、構成要素を ISO XNUMX 形式にマッピングし、 datetime オブジェクト:

Date: 2022-07-17
Time: 09:20:00
Date-time: 2022-07-17 09:20:00

一般的な文字列形式の日時とそれに対応する形式の短いリストを次に示します。 strptime():

"Jun 28 2018 at 7:40AM" -> "%b %d %Y at %I:%M%p"
"September 18, 2017, 22:19:55" -> "%B %d, %Y, %H:%M:%S"
"Sun,05/12/99,12:30PM" -> "%a,%d/%m/%y,%I:%M%p"
"Mon, 21 March, 2015" -> "%a, %d %B, %Y"
"2018-03-12T10:12:45Z" -> "%Y-%m-%dT%H:%M:%SZ"

受け取った入力に対して正しい形式トークンの文字列を使用している限り、任意の形式の日時文字列を解析できます。

タイムゾーンを使用して文字列を日時に変換する

タイムゾーンを扱う場合、日時の処理はより複雑になります。 これまでの上記の例はすべて、タイムゾーンにナイーブです。 これらは次のように知られています。 単純な日時オブジェクト.

しかし、 datetime オブジェクトには、タイムゾーン関連のデータを正確に格納するためのフィールドが含まれています – tzinfo:

import datetime as dt
dtime = dt.datetime.now()

print(dtime) 
print(dtime.tzinfo) 

  tzinfo フィールドは datetime.timezone タイムゾーン情報を示すオブジェクト。 これは None デフォルトでは、datetime オブジェクトが timezone-naive であることを示します。 タイムゾーンを処理するための非常に一般的な外部ライブラリは次のとおりです。 pytz。 設定できます ピッツ オブジェクトとして tzinfo フィールドも。

まだ持っていない場合は、次の方法でインストールします。

$ pip install pytz

PyTz を使用して、UTC などのタイムゾーン対応の日時のアンカーを作成できます。

import datetime as dt
import pytz

dtime = dt.datetime.now(pytz.utc)

print(dtime)
print(dtime.tzinfo)

出力:

2022-12-01 02:07:41.960920+00:00
UTC

タイムゾーンを数時間戻したので、午前 11 時ではなく午前 2 時になりました。 これ タイムゾーンを変更します 日時の。

+00:00 は、表示された時間とグローバル調整アンカーとしての UTC 時間との差です。 時刻を UTC に設定したので、オフセットは 00:00。 これは タイムゾーン対応オブジェクト.

同様に、タイムゾーン間で同じ日時の解釈を切り替えることができます。 「2022-06-29 17:08:00」などの文字列を日時に変換してから、 ローカライズ それを「America/New_York」タイムゾーンに:

import datetime as dt
import pytz

date_time_str = '2022-06-29 17:08:00'
date_time_obj = dt.datetime.strptime(date_time_str, '%Y-%m-%d %H:%M:%S')

timezone = pytz.timezone('America/New_York')
timezone_date_time_obj = timezone.localize(date_time_obj)

print(timezone_date_time_obj)
print(timezone_date_time_obj.tzinfo)

注: ローカライゼーション タイムゾーンを考慮しない datetime をタイムゾーン対応の datetime に変換し、タイムゾーンをローカルのものとして扱います。 したがって、 日時はそのまま、ただし、異なるタイムゾーンを指定すると、タイムゾーンから解放された同じ時点を表すことはなくなります。

私たちは同じことを得る 日時値、オフセット -04:00 UTC 時間との比較:

2022-06-29 17:08:00-04:00
America/New_York

東京 17:08 ありません ニューヨークの17:08と同じ時点。 東京の 17:08 はニューヨークの 3:08 です。

すべてのタイムゾーン コード/エイリアスを見つける方法は?

利用可能なすべてのタイムゾーンを見つけるには、 all_timezones 使用可能なすべてのタイムゾーンのリストであるフィールド:

print(f'There are {len(pytz.all_timezones)} timezones in PyTzn')
for time_zone in pytz.all_timezones:
   print(time_zone)

ベストプラクティス、業界で認められた標準、および含まれているチートシートを含む、Gitを学習するための実践的で実用的なガイドを確認してください。 グーグルGitコマンドを停止し、実際に 学ぶ それ!

There are 594 timezones in PyTz

Africa/Abidjan
Africa/Accra
Africa/Addis_Ababa
Africa/Algiers
Africa/Asmara
Africa/Asmera
...

Datetime のタイムゾーンを変更する

タイムゾーン対応のタイムゾーンを変換できます datetime あるタイムゾーンのレンズを通してタイムゾーンに依存しない日時をローカライズするのではなく、ある地域から別の地域にオブジェクトを移動します。

ローカリゼーションは異なる時点を表すため、これはローカライズとは異なりますが、オブジェクトのタイムゾーンを変換すると、異なるレンズを通して同じ時点が表されます。

import datetime as dt
import pytz

timezone_nw = pytz.timezone('America/New_York')
nw_datetime_obj = dt.datetime.now(timezone_nw)

timezone_london = pytz.timezone('Europe/London')
london_datetime_obj = nw_datetime_obj.astimezone(timezone_london)


print('America/New_York:', nw_datetime_obj)
print('Europe/London:', london_datetime_obj)

まず、現在の時刻を含む datetime オブジェクトを XNUMX つ作成し、それを「America/New_York」タイムゾーンとして設定しました。 次に、 astimezone() メソッド、これを変換しました datetime 「ヨーロッパ/ロンドン」タイムゾーンに。 両方 datetimes は、UTC オフセットをそれらの間の参照リンクとして使用して、異なる値を出力します。

America/New_York: 2022-11-30 21:24:30.123400-05:00
Europe/London: 2022-12-01 02:24:30.123400+00:00

翌日2:24 ロンドン is ニューヨークの前日21時24分と同時刻 ロンドンは5時間進んでいるので.

予想どおり、約 5 時間離れているため、日時が異なります。

サードパーティ ライブラリを使用して文字列を日時に変換する

Pythonの datetime モジュールは、すべての異なるタイプの文字列を datetime 物体。 しかし、主な問題は、これを行うには、適切なフォーマット コード文字列を作成する必要があることです。 strptime() 理解することができます。 この文字列の作成には時間がかかり、コードが読みにくくなります。

代わりに、他のサードパーティ ライブラリを使用して簡単にすることができます。

場合によっては、これらのサードパーティ ライブラリには、日時の操作と比較のサポートが組み込まれている場合や、タイムゾーンが組み込まれている場合もあるため、追加の PyTz パッケージを含める必要はありません。

次のセクションでは、これらのライブラリのいくつかを見てみましょう。

dateutil を使用して文字列を日時に変換する

  dateutilモジュール への拡張です datetime モジュール。 XNUMX つの利点は、文字列を解析するために解析コードを渡す必要がないことです。

Python の dateutil:

from dateutil.parser import parse
datetime = parse('2018-06-29 22:21:41')

print(datetime)

この parse 関数は文字列を自動的に解析します! フォーマット文字列を含める必要はありません。 を使用して、さまざまなタイプの文字列を解析してみましょう dateutil:

from dateutil.parser import parse

date_array = [
    '2018-06-29 08:15:27.243860',
    'Jun 28 2018 7:40AM',
    'Jun 28 2018 at 7:40AM',
    'September 18, 2017, 22:19:55',
    'Sun, 05/12/1999, 12:30PM',
    'Mon, 21 March, 2015',
    '2018-03-12T10:12:45Z',
    '2018-06-29 17:08:00.586525+00:00',
    '2018-06-29 17:08:00.586525+05:00',
    'Tuesday , 6th September, 2017 at 4:30pm'
]

for date in date_array:
    print('Parsing: ' + date)
    dt = parse(date)
    print(dt.date())
    print(dt.time())
    print(dt.tzinfo)
    print('n')

出力:

Parsing: 2018-06-29 08:15:27.243860
2018-06-29
08:15:27.243860
None

Parsing: Jun 28 2018 7:40AM
2018-06-28
07:40:00
None

Parsing: Jun 28 2018 at 7:40AM
2018-06-28
07:40:00
None

Parsing: September 18, 2017, 22:19:55
2017-09-18
22:19:55
None

Parsing: Sun, 05/12/1999, 12:30PM
1999-05-12
12:30:00
None

Parsing: Mon, 21 March, 2015
2015-03-21
00:00:00
None

Parsing: 2018-03-12T10:12:45Z
2018-03-12
10:12:45
tzutc()

Parsing: 2018-06-29 17:08:00.586525+00:00
2018-06-29
17:08:00.586525
tzutc()

Parsing: 2018-06-29 17:08:00.586525+05:00
2018-06-29
17:08:00.586525
tzoffset(None, 18000)

Parsing: Tuesday , 6th September, 2017 at 4:30pm
2017-09-06
16:30:00
None

を使用して、ほとんどすべてのタイプの文字列を簡単に解析できることがわかります。 dateutil モジュールを開きます。

これは便利ですが、形式を予測する必要があるとコードが非常に遅くなることを思い出してください。そのため、コードに高いパフォーマンスが必要な場合、これはアプリケーションにとって適切なアプローチではない可能性があります。

Maya で文字列を日時に変換する

Maya また、文字列の解析とタイムゾーンの変更が非常に簡単になります。 Python の Maya で文字列を簡単に変換するには:

import maya

dt = maya.parse('2018-04-29T17:45:25Z').datetime()
print(dt.date())
print(dt.time())
print(dt.tzinfo)

出力:

2018-04-29
17:45:25
UTC

時間を別のタイムゾーンに変換するには:

import maya

dt = maya.parse('2018-04-29T17:45:25Z').datetime(to_timezone='America/New_York', naive=False)
print(dt.date())
print(dt.time())
print(dt.tzinfo)

出力:

2018-04-29
13:45:25
America/New_York

使いやすくないですか? 試してみましょう maya 使用した文字列と同じセットで dateutil:

import maya

date_array = [
    '2018-06-29 08:15:27.243860',
    'Jun 28 2018 7:40AM',
    'Jun 28 2018 at 7:40AM',
    'September 18, 2017, 22:19:55',
    'Sun, 05/12/1999, 12:30PM',
    'Mon, 21 March, 2015',
    '2018-03-12T10:12:45Z',
    '2018-06-29 17:08:00.586525+00:00',
    '2018-06-29 17:08:00.586525+05:00',
    'Tuesday , 6th September, 2017 at 4:30pm'
]

for date in date_array:
    print('Parsing: ' + date)
    dt = maya.parse(date).datetime()
    print(dt)
    
    
    
    

出力:

Parsing: 2018-06-29 08:15:27.243860
2018-06-29 08:15:27.243860+00:00

Parsing: Jun 28 2018 7:40AM
2018-06-28 07:40:00+00:00

Parsing: Jun 28 2018 at 7:40AM
2018-06-28 07:40:00+00:00

Parsing: September 18, 2017, 22:19:55
2017-09-18 22:19:55+00:00

Parsing: Sun, 05/12/1999, 12:30PM
1999-05-12 12:30:00+00:00

Parsing: Mon, 21 March, 2015
2015-03-21 00:00:00+00:00

Parsing: 2018-03-12T10:12:45Z
2018-03-12 10:12:45+00:00

Parsing: 2018-06-29 17:08:00.586525+00:00
2018-06-29 17:08:00.586525+00:00

Parsing: 2018-06-29 17:08:00.586525+05:00
2018-06-29 12:08:00.586525+00:00

Parsing: Tuesday , 6th September, 2017 at 4:30pm
2017-09-06 16:30:00+00:00

ご覧のとおり、すべての日付形式が正常に解析されました!

タイムゾーン情報を提供しない場合、自動的に UTC に変換されます。 したがって、注意することが重要です しなければなりません 提供する to_timezone & naive 時刻が UTC でない場合のパラメーター。

矢印を使用して文字列を日時に変換する

矢印 Python で日時を処理するための別のライブラリです。 そして以前のように maya、日時形式も自動的に把握します。 解釈されると、Python を返します datetime からのオブジェクト arrow オブジェクト。

Python を使用して文字列を日時に簡単に変換するには arrow:

import arrow

dt = arrow.get('2018-04-29T17:45:25Z')
print(dt.date())
print(dt.time())
print(dt.tzinfo)

出力:

2018-04-29
17:45:25
tzutc()

そしてここにあなたが使うことができる方法があります arrow を使用してタイムゾーンを変換するには to() 方法:

import arrow

dt = arrow.get('2018-04-29T17:45:25Z').to('America/New_York')
print(dt)
print(dt.date())
print(dt.time())

出力:

2018-04-29T13:45:25-04:00
2018-04-29
13:45:25

ご覧のとおり、日時文字列は「America/New_York」地域に変換されます。

ここで、上で使用したのと同じ文字列のセットを再び使用しましょう。

import arrow

date_array = [
    '2018-06-29 08:15:27.243860',
    
    
    
    
    
    '2018-03-12T10:12:45Z',
    '2018-06-29 17:08:00.586525+00:00',
    '2018-06-29 17:08:00.586525+05:00',
    
]

for date in date_array:
    dt = arrow.get(date)
    print('Parsing: ' + date)
    print(dt)
    
    
    
    

このコードは、コメント アウトされた日時文字列では失敗します。これは、例の半分以上です。 他の文字列の出力は次のようになります。

Parsing: 2018-06-29 08:15:27.243860
2018-06-29T08:15:27.243860+00:00

Parsing: 2018-03-12T10:12:45Z
2018-03-12T10:12:45+00:00

Parsing: 2018-06-29 17:08:00.586525+00:00
2018-06-29T17:08:00.586525+00:00

Parsing: 2018-06-29 17:08:00.586525+05:00
2018-06-29T17:08:00.586525+05:00

コメントアウトされた日時文字列を正しく解析するには、対応する フォーマットトークン 解析方法に関する手がかりをライブラリに提供します。

まとめ

この記事では、文字列を解析して datetime Python のオブジェクト。 デフォルトのPythonを選択できます datetime ライブラリ、またはこの記事で言及されているサードパーティのライブラリのいずれかなどがあります。

デフォルトの主な問題 datetime パッケージの重要な点は、ほぼすべての日時文字列形式に対して、解析コードを手動で指定する必要があることです。 そのため、文字列形式が将来変更された場合は、コードも変更する必要があります。 ただし、ここで説明したような多くのサードパーティ ライブラリでは、自動的に処理されます。

私たちが直面しているもう XNUMX つの問題は、タイムゾーンの扱いです。 それらを処理する最善の方法は、常にデータベースに時刻を UTC 形式で保存し、必要に応じてユーザーのローカル タイムゾーンに変換することです。

これらのライブラリは、文字列の解析に適しているだけでなく、さまざまな種類の日時関連の操作に使用できます。 ドキュメントを参照して、機能を詳細に学習することをお勧めします。

タイムスタンプ:

より多くの スタックアバス