Ik probeer de huidige datum en tijd te vergelijken met datums en tijden die zijn gespecificeerd in modellen met behulp van vergelijkingsoperatoren:
if challenge.datetime_start <= datetime.now() <= challenge.datetime_end:
Het script maakt fouten met:
TypeError: can't compare offset-naive and offset-aware datetimes
De modellen zien er als volgt uit:
class Fundraising_Challenge(models.Model):
name = models.CharField(max_length=100)
datetime_start = models.DateTimeField()
datetime_end = models.DateTimeField()
Ik heb ook django die de lokale datum en tijden gebruikt.
Wat ik niet heb kunnen vinden is het formaat dat django gebruikt voor DateTimeField(). Is het naïef of bewust? En hoe zorg ik ervoor dat datetime.now() de locale datetime herkent?
Antwoord 1, autoriteit 100%
Standaard is het datetime
-object naive
in Python, dus je moet ze beide ofwel naïeve of bewust makende datetime
-objecten maken. Dit kan worden gedaan met:
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
Opmerking: Dit zou een ValueError
opleveren als tzinfo
al is ingesteld. Als je daar niet zeker van bent, gebruik dan gewoon
start_time = challenge.datetime_start.replace(tzinfo=utc)
end_time = challenge.datetime_end.replace(tzinfo=utc)
BTW, je zou een UNIX-tijdstempel in datetime.datetime-object kunnen opmaken met tijdzone-info als volgt
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)
Antwoord 2, autoriteit 59%
datetime.datetime.now
is niet op de hoogte van de tijdzone.
Django wordt hiervoor geleverd met een helper, waarvoor pytz
. nodig is
from django.utils import timezone
now = timezone.now()
Je zou now
moeten kunnen vergelijken met challenge.datetime_start
Antwoord 3, autoriteit 39%
Een regel code-oplossing
if timezone_aware_var <= datetime.datetime.now(timezone_aware_var.tzinfo):
pass #some code
Uitgelegde versie
# 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
Samenvatting
Je moet de tijdzone-informatie toevoegen aan je now()
datetime.
U moet echter de dezelfdetijdzone van de referentievariabele toevoegen; daarom las ik eerst het tzinfo
attribuut.
Antwoord 4, autoriteit 16%
Tijdzone uitschakelen.
Gebruik challenge.datetime_start.replace(tzinfo=None);
Je kunt replace(tzinfo=None)
ook gebruiken voor andere datetime.
if challenge.datetime_start.replace(tzinfo=None) <= datetime.now().replace(tzinfo=None) <= challenge.datetime_end.replace(tzinfo=None):
Antwoord 5
Dus de manier waarop ik dit probleem zou oplossen, is ervoor te zorgen dat de twee datums in de juiste tijdzone staan.
Ik kan zien dat je datetime.now()
gebruikt die de huidige tijd van het systeem teruggeeft, zonder dat tzinfo is ingesteld.
tzinfo is de informatie die aan een datetime is gekoppeld om het te laten weten in welke tijdzone het is. Als je naïeve datetime gebruikt, moet je consistent zijn in je hele systeem. Ik raad ten zeerste aan om alleen datetime.utcnow()
te gebruiken
Aangezien je ergens datetime aanmaakt waaraan tzinfo is gekoppeld, moet je ervoor zorgen dat deze zijn gelokaliseerd (met tzinfo gekoppeld) in de juiste tijdzone.
Kijk eens naar Delorean, het maakt het omgaan met dit soort zaken veel gemakkelijker.
Antwoord 6
Het werkt voor mij.
Hier krijg ik de tabel gemaakt datetime en voeg ik 10 minuten toe aan de datetime.
later, afhankelijk van de huidige tijd, worden de vervalbewerkingen uitgevoerd.
from datetime import datetime, time, timedelta
import pytz
10 minuten toegevoegd aan database datetime
table_datetime = ‘2019-06-13 07:49:02.832969’ (voorbeeld)
# 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 ")
Het werkte voor mij.
Antwoord 7
Je probeert de tijdzone voor date_time in te stellen die al een tijdzone heeft.
Gebruik de functies replace
en astimezone
.
local_tz = pytz.timezone('Asia/Kolkata')
current_time = datetime.now().replace(tzinfo=pytz.utc).astimezone(local_tz)
Antwoord 8
geen derde partij, alleen de native datetime-module.
from datetime import datetime, timedelta, timezone
time1 = datetime.strptime('2021-07-15T00:22:02+0000', '%Y-%m-%dT%H:%M:%S%z')
time2 = datetime(2021, 7, 15, tzinfo=timezone(offset=timedelta()))
if time1 < time2:
print(True)
Antwoord 9
Gewoon:
dt = datetimeObject.strftime(format) # format = your datetime format ex) '%Y %d %m'
dt = datetime.datetime.strptime(dt,format)
Dus doe dit:
start_time = challenge.datetime_start.strftime('%Y %d %m %H %M %S')
start_time = datetime.datetime.strptime(start_time,'%Y %d %m %H %M %S')
end_time = challenge.datetime_end.strftime('%Y %d %m %H %M %S')
end_time = datetime.datetime.strptime(end_time,'%Y %d %m %H %M %S')
en gebruik dan start_time
en end_time