1. ホーム
  2. パイソン

[解決済み】ナイーブとアウェアを比較できない datetime.now() <= challenge.datetime_end

2022-04-02 19:01:04

質問

比較演算子を使って、現在の日時とモデルで指定された日時を比較しようとしています。

if challenge.datetime_start <= datetime.now() <= challenge.datetime_end:

でスクリプトがエラーになる。

TypeError: can't compare offset-naive and offset-aware datetimes

モデルはこのような感じです。

class Fundraising_Challenge(models.Model):
    name = models.CharField(max_length=100)
    datetime_start = models.DateTimeField()
    datetime_end = models.DateTimeField()

また、djangoはロケールの日付と時刻を使用しています。

私が見つけられなかったのは、django が DateTimeField() に使用するフォーマットです。 それは素朴なものですか、それとも意識したものですか? そして、どうすれば datetime.now() がロケールの日時を認識できるようになるのでしょうか?

解決方法は?

デフォルトでは datetime オブジェクトは naive をPythonで使用する場合、両者をナイーブにするか、または認識させる必要があります。 datetime オブジェクトを作成します。これを実現するためには

import datetime
import pytz

utc=pytz.UTC

challenge.datetime_start = utc.localize(challenge.datetime_start) 
challenge.datetime_end = utc.localize(challenge.datetime_end) 
# now both the datetime objects are aware, and you can compare them

注:この場合 ValueError もし tzinfo がすでに設定されています。もし、それがよくわからない場合は、そのまま

start_time = challenge.datetime_start.replace(tzinfo=utc)
end_time = challenge.datetime_end.replace(tzinfo=utc)

ところで、UNIXタイムスタンプをdatetime.datetimeオブジェクトでフォーマットすると、タイムゾーン情報を含めて次のようになります。

d = datetime.datetime.utcfromtimestamp(int(unix_timestamp))
d_with_tz = datetime.datetime(
    year=d.year,
    month=d.month,
    day=d.day,
    hour=d.hour,
    minute=d.minute,
    second=d.second,
    tzinfo=pytz.UTC)