Próbuję porównać aktualną datę i godzinę z datami i godzinami określonymi w modelach za pomocą operatorów porównania:
if challenge.datetime_start <= datetime.now() <= challenge.datetime_end:
Błąd skryptu:
TypeError: can't compare offset-naive and offset-aware datetimes
Modele wyglądają tak:
class Fundraising_Challenge(models.Model):
name = models.CharField(max_length=100)
datetime_start = models.DateTimeField()
datetime_end = models.DateTimeField()
Mam też django używające daty i czasu locale.
Czego nie udało mi się znaleźć, to format używany przez django w funkcji DateTimeField (). Czy to naiwne czy świadome? I w jaki sposób mogę uzyskać datetime.now () rozpoznawać locale datetime?
python
django
datetime
comparison
sccrthlt
źródło
źródło
Odpowiedzi:
Domyślnie
datetime
obiekt jestnaive
w Pythonie, więc musisz uczynić oba z nichdatetime
obiektami naiwnymi lub świadomymi . Można to zrobić za pomocą:Uwaga: spowodowałoby to podniesienie wartości
ValueError
iftzinfo
jest już ustawiona. Jeśli nie jesteś tego pewien, po prostu użyjBTW, możesz sformatować znacznik czasu UNIX w obiekcie datetime.datetime z informacjami o strefie czasowej w następujący sposób
źródło
tzinfo
nie powoduje żadnej konwersji, przez co porównanie jest nieprawidłowe.utc = pytz.utc
aby zapobiec błędowi pylintaNo value for argument 'dt' in unbound method call (no-value-for-parameter)
. pytz linkdatetime.datetime.now
nie zna strefy czasowej.Django zawiera pomocnika, który wymaga
pytz
Powinieneś być w stanie porównać
now
dochallenge.datetime_start
źródło
USE_TZ=True
następnietimezone.now()
zwraca obiekt daty i godziny uwzględniający strefę czasową, nawet jeślipytz
nie jest zainstalowany (chociaż może być zalecane zainstalowanie z innych powodów).Jedna linia rozwiązania kodu
Wersja wyjaśniona
Podsumowanie
Musisz dodać informacje o strefie czasowej do daty i
now()
godziny.Musisz jednak dodać tę samą strefę czasową zmiennej referencyjnej; dlatego najpierw przeczytałem
tzinfo
atrybut.źródło
Wyłącz strefę czasową. Posługiwać się
challenge.datetime_start.replace(tzinfo=None);
Możesz również użyć
replace(tzinfo=None)
dla innych dat i godzin .źródło
Więc sposobem na rozwiązanie tego problemu jest upewnienie się, że te dwa czasy są we właściwej strefie czasowej.
Widzę, że używasz
datetime.now()
która zwróci systemowi bieżący czas, bez ustawionego tzinfo.tzinfo to informacja dołączona do daty i godziny, aby poinformować go, w jakiej strefie czasowej się znajduje. Jeśli używasz naiwnej daty i godziny, musisz zachować spójność w całym systemie. Gorąco polecam tylko używanie
datetime.utcnow()
widząc, że gdzieś tworzysz datę i godzinę z powiązanymi tzinfo, musisz upewnić się, że są one zlokalizowane (mają przypisane tzinfo) do właściwej strefy czasowej.
Spójrz na Delorean , to znacznie ułatwia radzenie sobie z tego typu rzeczami.
źródło
U mnie to działa. Tutaj kieruję tabelę utworzoną datę i godzinę i dodaję 10 minut do daty i godziny. później, w zależności od aktualnego czasu, wykonywane są operacje wygaśnięcia.
Dodano 10 minut do daty i godziny bazy danych
table_datetime = '2019-06-13 07: 49: 02.832969' (przykład)
U mnie to zadziałało.
źródło
Właśnie:
Więc zrób to:
a następnie użyj
start_time
iend_time
źródło