2009-09-04 14 views
33

मुझे pytz के .localize() फ़ंक्शन के साथ कुछ अजीब समस्याएं हैं। कभी कभी यह स्थानीय datetime के लिए समायोजन कर नहीं होगा:pytz localize बनाम डेटाटाइम

.localize व्यवहार:

>>> tz 
<DstTzInfo 'Africa/Abidjan' LMT-1 day, 23:44:00 STD> 
>>> d 
datetime.datetime(2009, 9, 2, 14, 45, 42, 91421) 

>>> tz.localize(d) 
datetime.datetime(2009, 9, 2, 14, 45, 42, 91421, 
        tzinfo=<DstTzInfo 'Africa/Abidjan' GMT0:00:00 STD>) 
>>> tz.normalize(tz.localize(d)) 
datetime.datetime(2009, 9, 2, 14, 45, 42, 91421, 
        tzinfo=<DstTzInfo 'Africa/Abidjan' GMT0:00:00 STD>) 

आप देख सकते हैं, समय स्थानीयकरण के परिणाम के रूप में बदला नहीं गया/संचालन सामान्य बनाते हैं। हालांकि, अगर .replace प्रयोग किया जाता है:

>>> d.replace(tzinfo=tz) 
datetime.datetime(2009, 9, 2, 14, 45, 42, 91421, 
        tzinfo=<DstTzInfo 'Africa/Abidjan' LMT-1 day, 23:44:00 STD>) 
>>> tz.normalize(d.replace(tzinfo=tz)) 
datetime.datetime(2009, 9, 2, 15, 1, 42, 91421, 
        tzinfo=<DstTzInfo 'Africa/Abidjan' GMT0:00:00 STD>) 

कौन सा datetime में समायोजन करने के लिए लगता है।

प्रश्न है - जो सही है और क्यों गलत है?

+0

संबंधित: [पीटीटीज़ का उपयोग कर डेटाटाइम टाइमज़ोन रूपांतरण] (http://stackoverflow.com/q/27531718/4279) – jfs

उत्तर

27

localize सिर्फ यह मानता है कि आप जिस निष्क्रिय समय को पास करते हैं वह "सही" है (टाइमज़ोन के बारे में जानने के अलावा!) और इसलिए बस टाइमज़ोन सेट करता है, कोई अन्य समायोजन नहीं करता है।

आप कर सकते हैं (और यह सलाह दी जाती है ...) आंतरिक यूटीसी (बल्कि अनुभवहीन datetimes साथ तुलना में) में काम करते हैं और replace का उपयोग जब आप (normalize डीएसटी और की तरह संभाल लेंगे एक स्थानीय तरह से मैं datetimes की/हे प्रदर्शन करने की जरूरत है)।

+1

यूटीसी का उपयोग करने के सुझाव के लिए एलेक्स उद्धरण और स्थानीयकरण/स्थानीयकरण/ को I/O संचालन के दौरान delocalize। क्या मैं सुझाव दे सकता हूं कि सलाह नहीं दी जाती है लेकिन दृढ़ता से अनुशंसा की जाती है (बाध्य पढ़ें)! – DrFalk3n

+2

ओपी ने 'लोकलाइज' और 'प्रतिस्थापन' के बीच के अंतर के बारे में पूछा। 'प्रतिस्थापन' नहीं करता है, बस टाइमज़ोन सेट करता है, कोई अन्य समायोजन नहीं करता है? यदि हां, तो दो परिणामों के बीच मतभेद क्यों हैं? –

+5

@ माइकल वाटरफॉल: 'pytz.timezone()' कई tzinfo ऑब्जेक्ट्स (एक ही स्थान, विभिन्न यूटीसी ऑफ़सेट, टाइमज़ोन संक्षेप) के अनुरूप हो सकता है। 'tz.localize (डी)' दिए गए 'd' स्थानीय समय के लिए सही tzinfo खोजने का प्रयास करता है (कुछ स्थानीय समय अस्पष्ट है या मौजूद नहीं है)। 'प्रतिस्थापित करें() 'बस जो भी (यादृच्छिक) जानकारी सेट करता है pytz timezone दिए गए दिनांक (हाल के संस्करणों में एलएमटी) के संबंध में डिफ़ॉल्ट रूप से प्रदान करता है। 'tz.normalize()' समय को समायोजित कर सकता है यदि 'd' एक अस्तित्वहीन स्थानीय समय है, उदाहरण के लिए, वसंत (उत्तरी गोलार्द्ध) में डीएसटी संक्रमण के दौरान समय अन्यथा यह इस मामले में कुछ भी नहीं करता है। – jfs

4

यह DstTzInfo वर्ग समय क्षेत्र जहां समय में कुछ बिंदुओं पर यूटीसी परिवर्तन से ऑफसेट के लिए प्रयोग किया जाता है। उदाहरण के लिए (जैसा कि आप शायद जानते हैं), कई स्थानों ग्रीष्मकाल की शुरुआत में "डेलाइट बचत समय" में संक्रमण, और फिर ग्रीष्म के अंत में "मानक समय" पर वापस आते हैं। प्रत्येक DstTzInfo इंस्टेंस केवल इन टाइमज़ोन में से एक का प्रतिनिधित्व करता है, लेकिन "स्थानीयकरण" और "सामान्यीकृत" विधियां आपको सही उदाहरण प्राप्त करने में सहायता करती हैं।

आबिदजान के लिए, वहाँ भी है तो केवल एक संक्रमण (pytz के अनुसार) कर दिया गया है, और कहा कि 1912 में किया गया था:

>>> tz = pytz.timezone('Africa/Abidjan') 
>>> tz._utc_transition_times 
[datetime.datetime(1, 1, 1, 0, 0), datetime.datetime(1912, 1, 1, 0, 16, 8)] 

TZ वस्तु हम pytz से बाहर निकलने के पूर्व 1912 समय क्षेत्र का प्रतिनिधित्व करता है:

>>> tz 
<DstTzInfo 'Africa/Abidjan' LMT-1 day, 23:44:00 STD> 

अब आप अपने दो उदाहरणों को देख, कि जब आप tz.localize (घ) फोन आप नहीं इस पूर्व 1912 समय क्षेत्र आपके अनुभवहीन datetime वस्तु को जोड़ा गया मिलता है देखते हैं। यह मानता है कि आपके द्वारा दी जाने वाली डेटाटाइम ऑब्जेक्ट स्थानीय समय उस स्थानीय समय के लिए सही समय क्षेत्र में दर्शाती है, जो 1 9 12 के बाद का समय है।

हालांकि d.replace का उपयोग कर अपने दूसरे उदाहरण में (tzinfo = TZ), यह आपके datetime वस्तु लेता पूर्व 1912 समय क्षेत्र में समय का प्रतिनिधित्व करने। शायद यह आपके लिए क्या मतलब नहीं है। फिर जब आप dt.normalize को कॉल करते हैं तो यह उस टाइमज़ोन में परिवर्तित हो जाता है जो उस डेटाटाइम मान के लिए सही है, यानि 1 9 12 के बाद का समय।

6

मुझे लगता है मैं इस पर एक छोटे से देर हो रही है ... लेकिन यहाँ मैं क्या अच्छी तरह से काम करने के लिए मिला है।एलेक्स के रूप में यूटीसी में कार्य ने कहा:

tz = pytz.timezone('Africa/Abidjan') 
now = datetime.datetime.utcnow() 

तब स्थानीय बनाना:

tzoffset = tz.utcoffset(now) 
mynow = now+tzoffset 

और इस विधि को संभालने डीएसटी पूरी तरह से

+1

यह गलत है अगर '.utcoffset()' विधि स्थानीय टाइमज़ोन में डेटाटाइम की अपेक्षा करता है जो utc से अलग है। स्थानीय समय क्षेत्र में वर्तमान समय प्राप्त करने के लिए: 'now = datetime.now (tz)'। यूटीसी समय को स्थानीय टाइमज़ोन में कनवर्ट करने के लिए: 'dt = utc_dt.replace (tzinfo = pytz.utc) .astimezone (tz)' (आपको '.localize()', '.normalize()' की आवश्यकता नहीं है)। – jfs

+0

ऑफसेट गलत होने पर डीएसटी सीमा पार कर भी गलत हो सकता है – paolov

1

localize साथ datetime बारे में पता वस्तुओं बनाने के लिए उपयोग करने के लिए सही कार्य है करता है एक प्रारंभिक तय डेटाटाइम मूल्य। परिणामी डेटाटाइम जागरूक ऑब्जेक्ट में मूल डेटाटाइम वैल्यू होगा। मेरे विचार में एक बहुत ही सामान्य उपयोग पैटर्न, और एक जो शायद pytz बेहतर दस्तावेज़ कर सकते हैं।

replace(tzinfo = ...) दुर्भाग्य से नामित है। यह एक ऐसा कार्य है जो इसके व्यवहार में यादृच्छिक है। मैं समय-समय पर सेट करने के लिए इस फ़ंक्शन के उपयोग से बचने की सलाह दूंगा जबतक कि आप स्वयं को पीड़ित दर्द का आनंद न लें। मैं इस समारोह का उपयोग करने से पहले ही काफी पीड़ित हूं।

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^