django 1.4 - ऑफसेट-भोले और ऑफसेट-जागरूक डेटासेट की तुलना नहीं कर सकते


85

मैं django 1.2 To 1.4 से एक एप्लिकेशन को माइग्रेट करने की प्रक्रिया में हूं।

मेरे पास एक दैनिक कार्य ऑब्जेक्ट है जिसमें दिन का एक समय होता है जो कार्य पूरा होना चाहिए:

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']

यह जांचने के लिए कि क्या किसी कार्य को आज भी पूरा करना आवश्यक है, मेरे पास निम्नलिखित कोड हैं:

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

इसने 1.2 के तहत ठीक काम किया, लेकिन 1.4 के तहत मुझे त्रुटि मिली:

can't compare offset-naive and offset-aware datetimes

लाइन के कारण

if timeDue<now and timeDue>dailyTask.last_completed

और दोनों तुलना खंड इस त्रुटि को फेंक देते हैं।

मैंने एक तर्क के रूप में pytz.UTC को जोड़कर टाइम-टाइम टाइमज़ोन को जागरूक करने की कोशिश की है, लेकिन यह अभी भी एक ही त्रुटि उठाता है।

मैंने टाइमज़ोन पर कुछ डॉक्स पढ़े हैं, लेकिन इस बात को लेकर असमंजस में हूं कि क्या मुझे सिर्फ टाइम-टाइम के बारे में अवगत कराने की जरूरत है, या क्या मुझे अपने डीबी और मौजूदा डेटा में मूलभूत बदलाव करने की जरूरत है।

जवाबों:


168

विस्तार से जानकारी के लिए पूरी तरह से दस्तावेज़ देखें ।

आम तौर पर, django.utils.timezone.nowऑफसेट-अवगत वर्तमान डेटाटाइम बनाने के लिए उपयोग करें

>>> from django.utils import timezone
>>> timezone.now()
datetime.datetime(2012, 5, 18, 13, 0, 49, 803031, tzinfo=<UTC>)

और django.utils.timezone.make_awareएक ऑफसेट-अवगत डेटाटाइम बनाने के लिए

>>> 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>)

आप तब ऑफसेट-अवगत डेटाटाइम w / o परेशानी दोनों की तुलना कर सकते हैं।

इसके अलावा, आप समय-समय की जानकारी को अलग करके ऑफ़सेट- datetime.datetime.now()एनवेट डेटाटाइम को ऑफ़सेट-भोले डेटाइम में परिवर्तित कर सकते हैं, फिर इसकी तुलना w / सामान्य , 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है True'डिफ़ॉल्ट रूप से' (वास्तव में यह है Falseडिफ़ॉल्ट रूप से, लेकिन settings.pyफ़ाइल द्वारा उत्पन्न django-admin.py startprojectसेट इसे करने के लिए True), तो अगर आपके डीबी समर्थन करता है समय क्षेत्र अवगत बार, समय-संबंधी मॉडल फ़ील्ड के मानों का समय क्षेत्र अवगत होगा। आप इसे सेटिंग में सेटिंग USE_TZ=False(या बस हटा दें USE_TZ=True) द्वारा अक्षम कर सकते हैं ।


4
Django टाइमफिल्ड के लिए जागरूक समय स्टोर नहीं करता है, यह केवल DateTimeField के लिए करता है। इसका वास्तव में कष्टप्रद है, जैसे कि अजगर डेटाइम.टाइम ऑब्जेक्ट डेटाटाइम लाइफटाइम ऑब्जेक्ट की तरह TZINFO का समर्थन करता है। मुझे आश्चर्य है कि वे इसे अगले रिलीज में ठीक कर देंगे। Btw मैंने इसे पोस्टर्स 9.1 डेटाबेस सर्वर पर परीक्षण किया है।
तेजिंड्स

@tejinders: datetime.timeगलत है। 'Asia/Shanghai'अगर आप तारीख नहीं जानते (तो utc ऑफसेट एक ही समय के लिए अलग-अलग तारीखों पर भिन्न हो सकते हैं) को स्टोर करने का कोई मतलब नहीं है।
JFS

@okm: make_aware(datetime.now(), get_default_timezone())विफल रहता है यदि get_default_timezone()आपके स्थानीय समयक्षेत्र से भिन्न होता है (यह होना चाहिए लेकिन यह संपूर्ण भरोसेमंद नहीं है)। बस का उपयोग timezone.now()करने के बजाय (यह समय क्षेत्र अवगत अगर है USE_TZहै True)।
JFS
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.