Je suis en train de migrer une application de Django 1.2 à 1.4.
J'ai un objet de tâche quotidien qui contient une heure de la journée où cette tâche doit être terminée:
class DailyTask(models.Model):
time = models.TimeField()
last_completed = models.DateTimeField()
name = models.CharField(max_length=100)
description = models.CharField(max_length=1000)
weekends = models.BooleanField()
def __unicode__(self):
return '%s' % (self.name)
class Meta:
db_table = u'dailytask'
ordering = ['name']
Afin de vérifier si une tâche doit encore être complétée aujourd'hui, j'ai le code suivant:
def getDueDailyTasks():
dueDailyTasks=[]
now = datetime.datetime.now()
try:
dailyTasks = DailyTask.objects.all()
except dailyTask.DoesNotExist:
return None
for dailyTask in dailyTasks:
timeDue = datetime.datetime(now.year,now.month,now.day,dailyTask.time.hour,dailyTask.time.minute,dailyTask.time.second)
if timeDue<now and timeDue>dailyTask.last_completed:
if dailyTask.weekends==False and now.weekday()>4:
pass
else:
dueDailyTasks.append({'id':dailyTask.id,
'due':timeDue,
'name': dailyTask.name,
'description':dailyTask.description})
return dueDailyTasks
Cela a bien fonctionné sous 1.2, mais sous 1.4 j'ai l'erreur:
can't compare offset-naive and offset-aware datetimes
en raison de la ligne
if timeDue<now and timeDue>dailyTask.last_completed
et les deux clauses de comparaison jettent cette erreur.
J'ai essayé de rendre le fuseau horaire timeDue conscient en ajoutant pytz.UTC comme argument, mais cela pose toujours la même erreur.
J'ai lu certaines de ces docs sur les fuseaux horaires, mais je ne sais pas si je dois juste informer le fuseau horaire timeDue ou si je dois apporter un changement fondamental à ma base de données et à mes données existantes.
Vérifiez le document complet pour plus de détails.
Normalement, utilisez Django.utils.timezone.now
Pour créer une date/heure actuelle avec décalage
>>> from Django.utils import timezone
>>> timezone.now()
datetime.datetime(2012, 5, 18, 13, 0, 49, 803031, tzinfo=<UTC>)
Et Django.utils.timezone.make_aware
Pour créer une date/heure avec décalage
>>> timezone.make_aware(datetime.datetime.now(), timezone.get_default_timezone())
datetime.datetime(2012, 5, 18, 21, 5, 53, 266396, tzinfo=<DstTzInfo 'Asia/Shanghai' CST+8:00:00 STD>)
Vous pouvez ensuite comparer les deux dates/heures sensibles à l'offset sans problème.
En outre, vous pouvez convertir une date/heure décalée en une date/heure naïve en supprimant les informations de fuseau horaire, puis comparer le résultat avec la fonction normale datetime.datetime.now()
, sous utc.
>>> t = timezone.now() # offset-awared datetime
>>> t.astimezone(timezone.utc).replace(tzinfo=None)
datetime.datetime(2012, 5, 18, 13, 11, 30, 705324)
USE_TZ
Est True
'par défaut' (en fait c'est False
par défaut, mais le fichier settings.py
Généré par Django-admin.py startproject
L'a réglé sur True
), si votre base de données prend en charge les heures prenant en compte les fuseaux horaires, les valeurs des champs de modèle temporels seront celles-ci. vous pouvez le désactiver en définissant USE_TZ=False
(ou simplement en supprimant USE_TZ=True
) dans les paramètres.