Kan naïef en bewust datetime.now() <= challenge.datetime_end

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 naivein 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 ValueErroropleveren als tzinfoal 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.nowis 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 nowmoeten 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 tzinfoattribuut.


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 replaceen 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_timeen end_time

Other episodes