2
1

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.

datetimeオブジェクトのnaiveとaware

Posted at

はじめに

pythonにおいて時刻を扱うdatetiem.datetimedatetime.timeオブジェクトにはnaiveawareという概念があります。

これは、生成されたオブジェクトがタイムゾーンの情報を持っているかどうかを示す属性値であり、タイムゾーンの情報を持っていればaware, なければnaiveになります。

このawareとnaiveという部分で躓くことが個人的に多かったので、知識を整理する意味でまとめておこうと思います。

概要〜naiveとawareとは

naiveとawareの区別自体は上記の通りで、タイムゾーンの情報を含んでいるかどうかによる。

タイムゾーン情報を含んでいるインスタンスを出力した場合には、+-xx:yyのような形式で世界標準時との差異が表示される。

なお、naive型とaware型の組み合わせに対しては、等号・不等号での比較ができない(naive同士・aware同士なら比較可能)。

# 変数now_naiveがnaive型の場合
print(now_naive)
>> 2021-11-16 10:05:46.268496

# 変数now_awareがaware型の場合
print(now_aware)
>> 2021-11-16 10:05:46.268704+09:00

タイムゾーン情報の取得

aware型のインスタンスはtzinfoという属性値を持っており、この値を参照することでタイムゾーンを取得することができる。

print(now_aware.tzinfo)
>> JST
# JSTは日本標準時の意味

# naive型のtzinfoはNoneになる
print(now_naive)
>> None

作成されるインスタンスのタイムゾーンの有無

datetime.datetime.now()で生成されるインスタンスは基本的にnaive型になるが、now()の引数としてtimezoneインスタンス(後述)を指定することでタイムゾーン情報を持ったawareなインスタンスを作成することができる。

import datetime
naive = datetime.datetime.now()
print(naive)
>> 2021-11-16 10:27:22.231630
print(naive.tzinfo)
>> None

aware_utc = datetime.datetime.now(dateteme.timezone.utc)
# datetime.datetime.utcは世界標準時の情報を持ったitmezoneインスタンス
print(aware_utc)
>> 2021-11-16 01:27:56.635804+00:00
print(aware_utc.tzinfo)
>> UTC

naive型のインスタンスの時刻は世界標準時ではなく現地時刻に合わせたものになることに注意。

例えばこの記事は日本で書いているので、naive型の変数の時刻はtzinofo="JST"のものと同じになる(もちろんtimezone情報は持っていないが)。

タイムゾーンの指定方法

awareなインスタンスを作る方法の一つとして上記のようにdatetime.timezone.utcをnow()の引数にする方法があるが、これでは世界標準時に基づくインスタンスしか作成できない。

タイムゾーンを任意のものに変更するための方法として、世界標準時から変換する、datetime()の引数として指定する、now()の引数として指定する、の3種類がある。

世界標準時から変更する

astimezone()メソッドを用いることで、ローカルのタイムゾーンに変更することができる。

now_utc = datetime.datetime.now(datetime.timezone.utc)
print(utc_now)
>> 2021-11-16 01:27:56.635804+00:00

now_jst = now_utc.astimezone()
print(now_jst)
>> 2021-11-16 01:27:56.635804+09:00

世界標準時との差異は+00:00から+09:00に変更されているものの、時刻自体は2021-11-16 01:27:56.635804で変更されていないことに注意。

datetime()の引数として指定する

datetime()の引数として年月日や時刻などとともにタイムゾーンの情報を与えることで、awareなインスタンスが作成される。

import datetime
from zoneinfo import Zoneinfo
now_jst = datetime.datetime(2020, 1, 1, tzinfo=Zoneinfo("Asia/Tokyo"))
# タイムゾーン情報はキーワード引数の形式で設定
print(now_jst)
>> 2020-01-01 00:00:00+09:00
print(now_jst.tzinfo)
>> Asia/Tokyo

nowの引数として設定する

now()はdatetime.timezone.utc以外にも、datetime.timezoneオブジェクトを引数として受け取ることが可能。

utc以外の引数に関しては地名や記号を用いるのではなく、以下のようにdatetime.timedeltaオブジェクトを用いて世界標準時からの差異を指定する。

now_jst = datetime.datetime.now(datetime.timezone(datetime.timedelta(hours=9)))
print(now_jst)
>> 2020-01-01 00:00:00+09:00
print(now_jst.tzinfo)
>> UTC+09:00
2
1
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
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?