2008-12-17 7 views
32

सबसे अच्छा मैं के साथ अभी इस कुरूपता है ऊपर आ सकते हैं:मुझे दिए गए टाइमज़ोन के लिए "मध्यरात्रि" का यूटीसी समय कैसे प्राप्त होगा?

>>> datetime.utcnow() \ 
... .replace(tzinfo=pytz.UTC) \ 
... .astimezone(pytz.timezone("Australia/Melbourne")) \ 
... .replace(hour=0,minute=0,second=0,microsecond=0) \ 
... .astimezone(pytz.UTC) \ 
... .replace(tzinfo=None) 
datetime.datetime(2008, 12, 16, 13, 0) 

Ie, अंग्रेजी में, वर्तमान समय (यूटीसी में) मिलता है, इसे किसी और समय क्षेत्र में बदलने का, आधी रात के लिए समय निर्धारित तब, यूटीसी में वापस कनवर्ट करें।

मैं बस अब() या स्थानीयसमय (का उपयोग नहीं) के रूप में है कि सर्वर के समय क्षेत्र, नहीं उपयोगकर्ता के समय क्षेत्र का प्रयोग करेंगे।

मैं महसूस कर रही मदद नहीं कर सकता कि मैं कुछ याद कर रहा हूँ, किसी भी विचार?

उत्तर

46

मुझे लगता है कि आप कुछ विधि बंद दाढ़ी कर सकते हैं कॉल करता है, तो आप इसे इस प्रकार कार्य करें:

>>> from datetime import datetime 
>>> datetime.now(pytz.timezone("Australia/Melbourne")) \ 
      .replace(hour=0, minute=0, second=0, microsecond=0) \ 
      .astimezone(pytz.utc) 

लेकिन ... आपकी कोड में सौंदर्यशास्त्र से बड़ी समस्या है: यह दिन पर गलत परिणाम दे देंगे डेलाइट सेविंग टाइम पर या स्विच से स्विच का।

इस का कारण यह है कि न तो datetime कंस्ट्रक्टर्स और न ही replace() डीएसटी खाते में बदल जाता है ले रहा है।

उदाहरण के लिए:

>>> now = datetime(2012, 4, 1, 5, 0, 0, 0, tzinfo=pytz.timezone("Australia/Melbourne")) 
>>> print now 
2012-04-01 05:00:00+10:00 
>>> print now.replace(hour=0) 
2012-04-01 00:00:00+10:00 # wrong! midnight was at 2012-04-01 00:00:00+11:00 
>>> print datetime(2012, 3, 1, 0, 0, 0, 0, tzinfo=tz) 
2012-03-01 00:00:00+10:00 # wrong again! 

हालांकि, tz.localize() राज्यों के लिए प्रलेखन:

यह विधि एक datetime निर्माता के लिए एक tzinfo तर्क गुजर से localtimes, बल्कि निर्माण करने के लिए इस्तेमाल किया जाना चाहिए।1582 से पहले, हालांकि

>>> import pytz 
>>> from datetime import datetime, date, time 

>>> tz = pytz.timezone("Australia/Melbourne") 
>>> the_date = date(2012, 4, 1) # use date.today() here 

>>> midnight_without_tzinfo = datetime.combine(the_date, time()) 
>>> print midnight_without_tzinfo 
2012-04-01 00:00:00 

>>> midnight_with_tzinfo = tz.localize(midnight_without_tzinfo) 
>>> print midnight_with_tzinfo 
2012-04-01 00:00:00+11:00 

>>> print midnight_with_tzinfo.astimezone(pytz.utc) 
2012-03-31 13:00:00+00:00 

दिनांकों कोई गारंटी:

इस प्रकार, आपकी समस्या इतनी तरह हल किया जाता है।

+2

मिलीसेकंड – joeforker

+0

को न भूलें डीएसटी को नजरअंदाज करता है। कहीं '। Localize()/सामान्यीकृत() 'आवश्यक हो सकता है। – jfs

+0

@ जेएफ। सेबेस्टियन: दिलचस्प! क्या आपको यकीन है? आपके पास कोई उदाहरण है? यह पूरी तरह से संभव है। – hop

0

TZ वातावरण चर की स्थापना को संशोधित करता है क्या समय क्षेत्र अजगर का दिनांक और समय कार्यों के साथ काम करते हैं।

>>> time.gmtime() 
(2008, 12, 17, 1, 16, 46, 2, 352, 0) 
>>> time.localtime() 
(2008, 12, 16, 20, 16, 47, 1, 351, 0) 
>>> os.environ['TZ']='Australia/Melbourne' 
>>> time.localtime() 
(2008, 12, 17, 12, 16, 53, 2, 352, 1) 
+0

इस पर नियंत्रण करने के लिए टीजेड वैरिएबल का उपयोग नहीं करना चाहते हैं, यह वास्तव में मुझे मध्यरात्रि को खोजने का तरीका नहीं बताता है, केवल वर्तमान समय। – Tom

0

प्रत्येक बार क्षेत्र में एक संख्या होती है, उदाहरण के लिए यूएस/सेंट्रल = -6। इसे यूटीसी के घंटों में ऑफसेट के रूप में परिभाषित किया जाता है। चूंकि 0000 मध्यरात्रि है, इसलिए आप मध्यरात्रि यूटीसी होने पर किसी भी समय क्षेत्र में समय खोजने के लिए बस इस ऑफ़सेट का उपयोग कर सकते हैं।

time.timezone

की भरपाई: कि पहुँचने के लिए, मेरा मानना ​​है कि आप

 time.timezone

उपयोग कर सकते हैं The Python Docs के अनुसार, time.timezone वास्तव में इस संख्या के नकारात्मक मूल्य देता है यूटीसी के पश्चिम में सेकेंड में स्थानीय (गैर-डीएसटी) टाइमज़ोन (पश्चिमी यूरोप में नकारात्मक, अमेरिका में सकारात्मक, ब्रिटेन में शून्य)।

तो आप बस उस नंबर घंटों में समय के लिए अगर यह सकारात्मक है का प्रयोग करेंगे (यानी, अगर यह शिकागो (जो एक +6 समय क्षेत्र महत्व है में आधी रात) है, तो यह 6000 = 06:00 यूटीसी है) ।

संख्या ऋणात्मक है, तो 24 से घटाना उदाहरण के लिए, बर्लिन -1, इसलिए 24 देना होगा - 1 => 2300 = 11:00।

+0

मुझे लगता है कि आप सही रास्ते पर हैं, लेकिन आप कैसे जानते हैं कि किस तारीख से शुरुआत करना है? यानी कुछ घंटों पहले, यह मेलबोर्न में 17 वां था, जबकि यह अभी भी यूटीसी में 16 वां था। – Tom

+0

सवाल स्थानीय मध्यरात्रि के बारे में है। स्थानीय मध्यरात्रि में - टाइम रिश्ते को समय-समय पर यूटीसी ऑफ़सेट द्वारा तय किया जाता है। –

+0

हाथ से टीजे मतभेदों को जोड़ने/घटाने के लिए स्विच के आसपास और डीएसटी – hop

22

@hop's answer इसे ठीक करने के से डेलाइट सेविंग टाइम (डीएसटी) जैसे, अप्रैल 1, 2012 संक्रमण के दिन पर गलत है tz.localize() इस्तेमाल किया जा सकता:

tz = pytz.timezone("Australia/Melbourne") 
today = datetime.now(tz).date() 
midnight = tz.localize(datetime.combine(today, time(0, 0)), is_dst=None) 
utc_dt = midnight.astimezone(pytz.utc)   

एक ही टिप्पणी के साथ:

#!/usr/bin/env python 
from datetime import datetime, time 
import pytz # pip instal pytz 

tz = pytz.timezone("Australia/Melbourne") # choose timezone 

# 1. get correct date for the midnight using given timezone. 
today = datetime.now(tz).date() 

# 2. get midnight in the correct timezone (taking into account DST) 
#NOTE: tzinfo=None and tz.localize() 
# assert that there is no dst transition at midnight (`is_dst=None`) 
midnight = tz.localize(datetime.combine(today, time(0, 0)), is_dst=None) 

# 3. convert to UTC (no need to call `utc.normalize()` due to UTC has no 
# DST transitions) 
fmt = '%Y-%m-%d %H:%M:%S %Z%z' 
print midnight.astimezone(pytz.utc).strftime(fmt) 
+0

मैं थोड़ा उलझन में हूँ। डीएसटी स्विच 3 एएम पर हुआ, इसलिए उस दिन आधी रात 14:00 यूटीसी पर होनी चाहिए, न कि 13:00 बजे। नहीं? – hop

+0

@hop: 2012 मार्च 31 13:00 यूटीसी मेलबोर्न टाइमज़ोन में कनवर्ट करें और अपने लिए देखें (यह अभी भी +11 टाइमज़ोन (डीएसटी) है, +10 (मानक) नहीं) – jfs

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

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