1
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Pythonのdatetimeとタイムゾーンについて

Last updated at Posted at 2020-03-31

タイムゾーンを意識してdatetimeを扱う際色々混乱してしまったので、自分用にまとめておきます。

Naive,Aware

Pythonの日時オブジェクトは以下の2種類に分類される。ざっくりとした差はタイムゾーン情報の有無

  • Naiveオブジェクト

    • タイムゾーン情報を持たない
  • Awareオブジェクト

    • タイムゾーン情報(tzinfo属性)を持つ
    • tzinfo属性にはtzinfoのサブクラスのインスタンスを設定出来る
      • dateitme.timezoneがtzinfoのサブクラスなので、このクラスのオブジェクトを設定することが出来る
      • 例えば、datetime.timezone(timedelta(hours=+9), 'JST')としてオブジェクトを生成するとこれはJSTのタイムゾーンを表すオブジェクト

したがって、何らかのプログラムでタイムゾーンを意識した処理を行いたい場合、Awareオブジェクトを使う必要がある。

オブジェクト

以下4つのメインオブジェクトがある。

  • date: 年月日
  • time: 時分秒
  • datetime: 日付と時刻
  • timedelta: 時間間隔

それぞれオブジェクトの生成の仕方によって、NaiveだったりAwareだったりする。
例えば、

>>> print('Python %s on %s' % (sys.version, sys.platform))
Python 3.7.4 (default, Oct 10 2019, 12:40:25) 
[Clang 10.0.1 (clang-1001.0.46.4)] on darwin

>>> import datetime
>>> aware_dt = datetime.datetime.now(tz=datetime.timezone.utc)
>>> aware_dt
datetime.datetime(2020, 4, 4, 5, 49, 51, 291393, tzinfo=datetime.timezone.utc)
>>> naive_dt = datetime.datetime.utcnow()
>>> naive_dt
datetime.datetime(2020, 4, 4, 5, 50, 8, 499521)
>>> aware_dt.tzinfo
datetime.timezone.utc
>>> print(naive_dt.tzinfo)
<class 'NoneType'>

のように、utc現在時刻をオブジェクトとして生成するときも、タイムゾーンを指定する方法とそうでない方法がある。

datetimeオブジェクトにまつわるメソッド

strptime

日付を表現した文字列をdatetime型にするメソッド。

>>> str_dt = '2020-3-01 10:11:12'
>>> strp_dt = datetime.datetime.strptime(str_dt, "%Y-%m-%d %H:%M:%S")
>>> strp_dt
datetime.datetime(2020, 3, 1, 10, 11, 12)
>>> print(type(strp_dt.tzinfo))
<class 'NoneType'>

生成したオブジェクトにタイムゾーン属性は含まれない。
ただし、変換前の文字列にタイムゾーンが含まれていて、フォーマットも適切に設定すると

>>> str_dt_utc = '2020-3-01 10:11:12+00:00'
>>> strp_dt_utc = datetime.datetime.strptime(str_dt_utc, "%Y-%m-%d %H:%M:%S%z")
>>> strp_dt_utc
datetime.datetime(2020, 3, 1, 10, 11, 12, tzinfo=datetime.timezone.utc)
>>> str_dt_jst = '2020-3-01 10:11:12+09:00'
>>> strp_dt_jst = datetime.datetime.strptime(str_dt_jst, "%Y-%m-%d %H:%M:%S%z")
>>> strp_dt_jst
datetime.datetime(2020, 3, 1, 10, 11, 12, tzinfo=datetime.timezone(datetime.timedelta(seconds=32400)))

のようにタイムゾーン属性も設定されてdatetimeオブジェクトが生成される模様。

astimezone

あるdatetimeオブジェクトを指定したタイムゾーン情報に合わせて変換するメソッド。

>>> strp_dt.astimezone(datetime.timezone.utc)
datetime.datetime(2020, 3, 1, 1, 11, 12, tzinfo=datetime.timezone.utc)

JSTとUTCの時差である-9時間が反映され、tzinfoが付加されたdatetimeのオブジェクトが返却された。(これはローカルのタイムゾーンとの比較によるもの?)

replace

あるdatetimeオブジェクトのタイムゾーンを指定したタイムゾーンに変換するメソッド。

>>> strp_dt.replace(tzinfo=datetime.timezone.utc)
datetime.datetime(2020, 3, 1, 10, 11, 12, tzinfo=datetime.timezone.utc)

astimezoneと比較すると、tzinfoだけが変換されていることに注意。

timezoneオブジェクトの生成については、素直にdatetime.timezone(timedelta(hours=+9), 'JST')のように生成する方法や、サードパーティ製のモジュール(pytz,dateutil)を使ったりと、色々な方式がある。

1
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?