比較演算子を使用して、現在の日付と時刻をモデルで指定された日付と時刻と比較しようとしています。
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もあります。
私が見つけることができなかったのは、DateTimeField()にDjangoが使用するフォーマットです。それは素朴なのですか、それとも意識しているのですか?そして、ロケールdatetimeを認識するためにdatetime.now()を取得するにはどうすればよいですか?
デフォルトでは、datetime
オブジェクトはPythonのnaive
であるため、これらの両方をナイーブまたはアウェアな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)
ところで、次のようにタイムゾーン情報を持つdatetime.datetimeオブジェクトのUNIXタイムスタンプをフォーマットすることができます
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)
datetime.datetime.now
はタイムゾーンを認識しません。
Djangoにはこのためのヘルパーが付属しています。これにはpytz
が必要です
from Django.utils import timezone
now = timezone.now()
now
とchallenge.datetime_start
を比較できるはずです
コードソリューションの1行
if timezone_aware_var <= datetime.datetime.now(timezone_aware_var.tzinfo):
pass #some code
説明バージョン:
# Timezone info of your timezone aware variable
timezone = your_timezone_aware_variable.tzinfo
# Current datetime for the timezone of your variable
now_in_timezone = datetime.datetime.now(timezone)
# Now you can do a fair comparison, both datetime variables have the same time zone
if your_timezone_aware_variable <= now_in_timezone:
pass #some code
概要:
タイムゾーン情報をnow()
datetimeに追加する必要があります。
ただし、参照変数の同じタイムゾーンを追加する必要があります。それが最初にtzinfo
属性を読んだ理由です。
タイムゾーンを無効にします。 challenge.datetime_start.replace(tzinfo=None);
を使用します
他のdatetimeにreplace(tzinfo=None)
を使用することもできます。
if challenge.datetime_start.replace(tzinfo=None) <= datetime.now().replace(tzinfo=None) <= challenge.datetime_end.replace(tzinfo=None):
したがって、この問題を解決する方法は、2つの日時が正しいタイムゾーンにあることを確認することです。
Tzinfoが設定されていないシステムの現在時刻を返すdatetime.now()
を使用していることがわかります。
tzinfoは、日時がどのタイムゾーンにあるかを知らせるために日時に付加される情報です。単純な日時を使用している場合は、システム全体で一貫性を保つ必要があります。 datetime.utcnow()
のみを使用することを強くお勧めします
tzinfoが関連付けられたdatetimeを作成している場所を確認するには、それらが正しいタイムゾーンにローカライズされている(tzinfoが関連付けられている)ことを確認する必要があります。
Delorean を見てください。これにより、この種の処理がはるかに簡単になります。
それは私から働いています。ここでは、datetimeで作成されたテーブルを取得し、datetimeに10分を追加しています。後で現在の時刻に応じて、有効期限操作が行われます。
from datetime import datetime, time, timedelta
import pytz
データベースの日時に10分追加
table_datetime = '2019-06-13 07:49:02.832969'(例)
# Added 10 minutes on database datetime
# table_datetime = '2019-06-13 07:49:02.832969' (example)
table_expire_datetime = table_datetime + timedelta(minutes=10 )
# Current datetime
current_datetime = datetime.now()
# replace the timezone in both time
expired_on = table_expire_datetime.replace(tzinfo=utc)
checked_on = current_datetime.replace(tzinfo=utc)
if expired_on < checked_on:
print("Time Crossed)
else:
print("Time not crossed ")
それは私のために働いた。