भोले और जागरूक डेटाटाइम की तुलना नहीं कर सकते हैं। () <= Challenge.datetime_end


154

मैं वर्तमान समय और समय की तुलना करने की कोशिश कर रहा हूँ दिनांक और समय के साथ तुलना संचालकों का उपयोग करके मॉडल में निर्दिष्ट किया गया है:

if challenge.datetime_start <= datetime.now() <= challenge.datetime_end:

स्क्रिप्ट त्रुटियों के साथ:

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

मॉडल इस तरह दिखते हैं:

class Fundraising_Challenge(models.Model):
    name = models.CharField(max_length=100)
    datetime_start = models.DateTimeField()
    datetime_end = models.DateTimeField()

मैं भी तारीख और समय का उपयोग कर django है।

जो मैं नहीं खोज पाया वह डेटाइमफिल्ड () के लिए django प्रारूप का उपयोग करता है। यह भोला है या जागरूक? और लोकल डेटाइम को पहचानने के लिए मुझे datetime.now () कैसे मिलेगी?




1
तारीख के साथ खेलने के लिए एक बहुत अच्छा काम है: पेंडुलम (मैं संबद्ध नहीं हूं)
थॉमस डेकाक्स

जवाबों:


137

डिफ़ॉल्ट रूप से, datetimeऑब्जेक्ट naiveपायथन में है, इसलिए आपको उन दोनों को अनुभवहीन या जागरूक datetimeवस्तु बनाने की आवश्यकता है । इसका उपयोग करके किया जा सकता है:

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

नोट: यह एक ValueErrorअगर tzinfoपहले से ही सेट है उठाया जाएगा । यदि आप इसके बारे में निश्चित नहीं हैं, तो बस उपयोग करें

start_time = challenge.datetime_start.replace(tzinfo=utc)
end_time = challenge.datetime_end.replace(tzinfo=utc)

BTW, आप निम्नलिखित के रूप में टाइमज़ोन जानकारी के साथ डेटाटाइम में एक UNIX टाइमस्टैम्प प्रारूपित कर सकते हैं

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)

यह कहता है: ValueError: नहीं भोली डेटाइम (tzinfo पहले से ही सेट है) जब यह गणना करने की कोशिश करता है: datetimeStart = utc.localize (Challenge.datetime_start)
sccrthlt

हाँ, यह मान बढ़ाता है।
दिमित्री मिखाइलोव

4
की जगह tzinfoकिसी भी रूपांतरण नहीं करता है, तुलना गलत बना रही है।
ऑरेंजडॉग

इसके लिए +1। और, utc = pytz.utcpylint त्रुटि को रोकने के लिए उपयोग करना No value for argument 'dt' in unbound method call (no-value-for-parameter)pytz लिंक
सैम

90

datetime.datetime.now टाइमजोन जागरूक नहीं है

Django इसके लिए एक सहायक के साथ आता है, जिसे आवश्यकता होती है pytz

from django.utils import timezone
now = timezone.now()

आपको तुलना nowकरने में सक्षम होना चाहिएchallenge.datetime_start


3
यदि USE_TZ=Trueफिर भी timezone.now()एक समय-ज्ञात-अवगत डेटाटाइम ऑब्जेक्ट लौटाया pytzजाता है, भले ही इंस्टॉल न किया गया हो (हालाँकि अन्य कारणों से इसे इंस्टॉल करने की अनुशंसा की जा सकती है)।
JFS

49

कोड समाधान की एक पंक्ति

if timezone_aware_var <= datetime.datetime.now(timezone_aware_var.tzinfo):
    pass #some code

समझाया गया संस्करण

# 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

सारांश

आपको अपने now()डेटाटाइम में टाइमज़ोन जानकारी को जोड़ना होगा ।
हालाँकि, आपको संदर्भ चर का एक ही टाइमज़ोन जोड़ना होगा ; यही कारण है कि मैंने पहली बार tzinfoविशेषता को पढ़ा ।


18

समय क्षेत्र अक्षम करें। उपयोगchallenge.datetime_start.replace(tzinfo=None);

आप replace(tzinfo=None)अन्य डेटाटाइम के लिए भी उपयोग कर सकते हैं ।

if challenge.datetime_start.replace(tzinfo=None) <= datetime.now().replace(tzinfo=None) <= challenge.datetime_end.replace(tzinfo=None):

2

तो जिस तरह से मैं इस समस्या को हल करूँगा वह यह सुनिश्चित करना है कि दो डेटासेटाइम सही समय क्षेत्र में हैं।

मैं देख सकता हूं कि आप उपयोग कर रहे हैं datetime.now() जो मौजूदा समय में सिस्टम को लौटा देगा, जिसमें कोई tininfo सेट नहीं है।

tzinfo एक डेटाइम से जुड़ी जानकारी है जो आपको बताती है कि यह किस समय में है। यदि आप भोले डेटाइम का उपयोग कर रहे हैं तो आपको अपने सिस्टम के माध्यम से सुसंगत रहने की आवश्यकता है। मैं अत्यधिक केवल उपयोग करने की सलाह दूंगाdatetime.utcnow()

यह देखते हुए कि कहीं न कहीं आप डेटाइम बना रहे हैं, जिनके साथ tzinfo जुड़े हैं, आपको जो करने की ज़रूरत है वह सुनिश्चित करें कि वे स्थानीयकृत हैं (tzinfo संबद्ध है) सही टाइमज़ोन से।

डेलोरियन पर एक नज़र डालें , यह इस तरह की चीज़ से बहुत आसान काम करता है।


8
आप भी इस मुद्दे को उत्कंठा से देखें।
एंडी हेडन

0

यह मेरे लिए काम कर रहा है। यहाँ मैं टेबल बनाया गया हूँ और डाइमटाइम पर 10 मिनट जोड़कर बनाया गया है। बाद में वर्तमान समय के आधार पर, एक्सपायरी ऑपरेशन किए जाते हैं।

from datetime import datetime, time, timedelta
import pytz

डेटाबेस डेटाइम पर 10 मिनट जोड़े

table_datetime = '2019-06-13 07: 49: 02.832969' (उदाहरण)

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

इसने मेरे लिए काम किया।


0

बस:

dt = datetimeObject.strftime(format) # format = your datetime format ex) '%Y %d %m'
dt = datetime.datetime.strptime(dt,format)

तो ऐसा करें:

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

और फिर उपयोग करें start_timeऔरend_time

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.