Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
4
Help us understand the problem. What is going on with this article?
@sivukai

python/djangoで文字列からdatetimeに変換するときのtimezone設定

More than 1 year has passed since last update.

めちゃくちゃ初歩的なミスを犯すところだったので戒めにメモしておきます。。。

背景

Twitter APIを用いて構築しているTwitterクローラで、デフォルト設定である1週間単位でツイートデータを収集していたが、1週間丸ごと取りに行くとデータ量的にクロールにかかる時間が長くなってしまう為、クロールしてくる期間を変更したい。
しかし、Standard Search APIには取得開始日時から特定の日時までのデータに絞るパラメータが存在していない為、APIの返り値から日付情報を抽出して比較する必要がある。
(厳密には、since_idはあるけど仕様が謎で使いづらい・・・)

問題

以下のように、django.utils.timezoneを用いてJSTで対象期間を定義し、APIの返り値をJSTに変換して比較しようとしていた。

import datetime
from django.utils import timezone

target_datetime = timezone.localtime(timezone.now()) - datetime.timedelta(days=4)

created_at = "Thu Oct 03 15:28:43 +0000 2019" #APIから抽出した日付文字列
created_at_datetime = timezone.make_aware(datetime.datetime.strptime(created_at, '%a %b %d %H:%M:%S +0000 %Y'), timezone.get_default_timezone())

if created_at_datetime > target_datetime:
以下省略

しかし、このやり方だと以下のように「UTC」の日時が「JST」に変換されないまま、「JST」のタイムゾーン情報だけが付与された形になっていた。

>>> created_at = "Thu Oct 03 15:28:43 +0000 2019"
>>> created_at_datetime = timezone.make_aware(datetime.datetime.strptime(created_at, '%a %b %d %H:%M:%S +0000 %Y'), timezone.get_default_timezone())
datetime.datetime(2019, 10, 3, 15, 28, 43, tzinfo=<DstTzInfo 'Asia/Tokyo' JST+9:00:00 STD>)

解決方法

UTC文字列をJSTのdatetimeに変換するには以下の手順を踏む必要がある。

>>> created_at = "Thu Oct 03 15:28:43 +0000 2019"
>>> created_at_datetime_utc = datetime.datetime.strptime(created_at, '%a %b %d %H:%M:%S %z %Y')
>>> timezone.localtime(created_at_datetime_utc)
datetime.datetime(2019, 10, 4, 0, 28, 43, tzinfo=<DstTzInfo 'Asia/Tokyo' JST+9:00:00 STD>)

なお、datetime同士の比較を行うだけの目的であればわざわざ変換しなくてもよしなに計算してくれる模様。

>>> created_at_datetime
datetime.datetime(2019, 9, 29, 20, 32, 44, tzinfo=datetime.timezone.utc)
>>> target_datetime
datetime.datetime(2019, 9, 29, 20, 32, 44, tzinfo=<DstTzInfo 'Asia/Tokyo' JST+9:00:00 STD>)
>>> created_at_datetime > target_datetime
True

>>> created_at_datetime
datetime.datetime(2019, 9, 29, 12, 32, 44, tzinfo=datetime.timezone.utc)
>>> target_datetime
datetime.datetime(2019, 9, 29, 20, 32, 44, tzinfo=<DstTzInfo 'Asia/Tokyo' JST+9:00:00 STD>)
>>> created_at_datetime > target_datetime
True

>>> created_at_datetime
datetime.datetime(2019, 9, 29, 10, 32, 44, tzinfo=datetime.timezone.utc)
>>> target_datetime
datetime.datetime(2019, 9, 29, 20, 32, 44, tzinfo=<DstTzInfo 'Asia/Tokyo' JST+9:00:00 STD>)
>>> created_at_datetime > target_datetime
False
4
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
sivukai

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
4
Help us understand the problem. What is going on with this article?