पायथन स्ट्रैपटाइम () और टाइमज़ोन?


157

मेरे पास एक ब्लैकबेरी IPD बैकअप से एक CSV डंपफाइल है, जिसे IPDDump का उपयोग करके बनाया गया है। यहाँ दिनांक / समय के तार कुछ इस तरह दिखते हैं (जहाँ ESTएक ऑस्ट्रेलियाई समय-क्षेत्र है):

Tue Jun 22 07:46:22 EST 2010

मुझे पायथन में इस तारीख को पार्स करने में सक्षम होने की आवश्यकता है। सबसे पहले, मैंने strptime()डेटेट से फ़ंक्शन का उपयोग करने का प्रयास किया ।

>>> datetime.datetime.strptime('Tue Jun 22 12:10:20 2010 EST', '%a %b %d %H:%M:%S %Y %Z')

हालांकि, किसी कारण के लिए, जो datetimeवस्तु वापस आती है , उसके tzinfoसाथ कोई संबंध नहीं है।

मैंने इस पृष्ठ पर पढ़ा था कि जाहिरा तौर पर datetime.strptimeचुपचाप डिस्क्राइब करता है tzinfo, हालांकि, मैंने दस्तावेज़ीकरण की जाँच की, और मुझे इस बात का कुछ भी पता नहीं चल सका कि यहाँ क्या प्रलेखित है

मैं एक तीसरे पक्ष के पायथन पुस्तकालय, डेटुटिल का उपयोग करके तारीख को प्राप्त करने में सक्षम रहा हूं, हालांकि मैं अभी भी उत्सुक हूं कि मैं strptime()गलत तरीके से इन-बिल्ट का उपयोग कैसे कर रहा था ? क्या strptime()टाइमज़ोन के साथ अच्छी तरह से खेलने का कोई तरीका है ?


1
क्या आप अभी नहीं ... सभी तिथियों को GMT में बदल सकते हैं?
रोबस

2
@ रॉबस: हम्म, मैं ऐसा करने की उम्मीद कर रहा था - लेकिन मैं यह मान रहा था कि स्ट्रैटेम / डेटाइम किसी भी तरह से ऐसा कर सकता है? किसी भी तरह से, मुझे इस तथ्य को संग्रहीत / पार्स करने की आवश्यकता है कि डेटासेटाइम ईएसटी समय क्षेत्र में हैं, या जो भी टाइमज़ोन मेरे साथ होता है। स्क्रिप्ट को समय क्षेत्र की जानकारी (जैसे ईटीसी किसी भी अन्य समयक्षेत्र हो सकता है) के साथ सामान्य डेटासेट को पार्स करने में सक्षम होना चाहिए।
3

3
ईएसटी एक यूएस टाइमजोन संक्षिप्त नाम भी है। (इसी तरह BST एक यूके और ब्राज़ीलियन टाइमज़ोन एब्सब्रव दोनों है।) इस तरह के संक्षिप्ताक्षर केवल अस्पष्ट हैं। इसके बजाय UTC / GMT के सापेक्ष ऑफ़सेट का उपयोग करें। (यदि आपको संक्षिप्तीकरण का समर्थन करने की आवश्यकता है, तो आपको मैपिंग को लोकेल-डिपेंडेंट बनाने की जरूरत है और यह एक गन्दा चूहा-छेद है।)
डोनल फैलो

जवाबों:


58

datetimeमॉड्यूल प्रलेखन का कहना है:

दिनांक_string, प्रारूप के अनुसार पार्स किए गए के समान डेटाइम लौटाएं। इसके बराबर है datetime(*(time.strptime(date_string, format)[0:6]))

वह देखें [0:6]? जो आपको मिलता है (year, month, day, hour, minute, second)। और कुछ नहीं। टाइमजोन का कोई उल्लेख नहीं है।

दिलचस्प बात यह है कि, [विन XP SP2, पायथन 2.6, 2.7] अपना उदाहरण time.strptimeकाम नहीं कर रहा है, लेकिन यदि आप "% Z" और "EST" को हटाते हैं तो यह काम नहीं करता है। "EST" कार्यों के बजाय "UTC" या "GMT" का उपयोग करना। "पीएसटी" और "एमईजेड" काम नहीं करते हैं। पेचीदा।

यह ध्यान देने योग्य है कि इसे 3.2 संस्करण के रूप में अद्यतन किया गया है और उसी दस्तावेज में अब निम्नलिखित भी हैं:

जब% z निर्देश स्ट्रेटटाइम () विधि को प्रदान किया जाता है, तो एक जागरूक डेटाइम ऑब्जेक्ट का उत्पादन किया जाएगा। परिणाम का tzinfo एक टाइमज़ोन उदाहरण के लिए सेट किया जाएगा।

ध्यान दें कि यह% Z के साथ काम नहीं करता है, इसलिए मामला महत्वपूर्ण है। निम्नलिखित उदाहरण देखें:

In [1]: from datetime import datetime

In [2]: start_time = datetime.strptime('2018-04-18-17-04-30-AEST','%Y-%m-%d-%H-%M-%S-%Z')

In [3]: print("TZ NAME: {tz}".format(tz=start_time.tzname()))
TZ NAME: None

In [4]: start_time = datetime.strptime('2018-04-18-17-04-30-+1000','%Y-%m-%d-%H-%M-%S-%z')

In [5]: print("TZ NAME: {tz}".format(tz=start_time.tzname()))
TZ NAME: UTC+10:00


353

मैं अजगर-खजूर का उपयोग करने की सलाह देता हूं । इसका पार्सर अब तक मेरे द्वारा फेंके गए हर तारीख प्रारूप को पार्स करने में सक्षम रहा है।

>>> from dateutil import parser
>>> parser.parse("Tue Jun 22 07:46:22 EST 2010")
datetime.datetime(2010, 6, 22, 7, 46, 22, tzinfo=tzlocal())
>>> parser.parse("Fri, 11 Nov 2011 03:18:09 -0400")
datetime.datetime(2011, 11, 11, 3, 18, 9, tzinfo=tzoffset(None, -14400))
>>> parser.parse("Sun")
datetime.datetime(2011, 12, 18, 0, 0)
>>> parser.parse("10-11-08")
datetime.datetime(2008, 10, 11, 0, 0)

और इसी तरह। strptime()प्रारूप बकवास के साथ कोई व्यवहार नहीं ... बस उस पर एक तारीख फेंक दो और यह सही बात करता है।

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


यह देखते हुए कि बहुत से लोग अजगर-खजूर का उपयोग करते हैं, मैं उस परिवाद की एक सीमा बताना चाहता हूं। >>> parser.parse("Thu, 25 Sep 2003 10:49:41,123 -0300") Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/Users/wanghq/awscli/lib/python2.7/site-packages/dateutil/parser.py", line 748, in parse return DEFAULTPARSER.parse(timestr, **kwargs) File "/Users/wanghq/awscli/lib/python2.7/site-packages/dateutil/parser.py", line 310, in parse res, skipped_tokens = self._parse(timestr, **kwargs) TypeError: 'NoneType' object is not iterable
वेंघ

1
@ ग्वांगक को आपको अंतिम अल्पविराम को अवधि के साथ बदलने की आवश्यकता है। फ़िरparser.parse("Thu, 25 Sep 2003 10:49:41.123 -0300") returns: datetime.datetime(2003, 9, 25, 10, 49, 41, 123000, tzinfo=tzoffset(None, -10800))
फ़्लायफ़ॉक्सलेली

7
@flyingfoxlee, हाँ, मैं समझता हूँ कि। मैं सिर्फ लोगों को अजगर-खजूर की सीमा बताना चाहता हूं। यह जादू की बातें करता है, लेकिन कभी-कभी ऐसा करने में विफल रहता है। तो "बस इस पर एक तारीख फेंक दो और यह सही बात करता है।" 100% सच नहीं है।
वँग्ख

4
dateutil.parser.parse("10-27-2016 09:06 AM PDT")रिटर्न: datetime.datetime(2016, 10, 27, 9, 6)समय क्षेत्र का पता लगाने में विफल रहता है ...
HaPsantran

2
यह किसी के लक्ष्य पर निर्भर करता है। dateutil parserउपयोग करने के लिए सरल हो सकता है, लेकिन strptime()तेज है। इसके अलावा, इसके प्रारूप सीखने में काफी आसान हैं।
उत्साह

9

आपका समय स्ट्रिंग rfc 2822 में समय प्रारूप (ईमेल, http हेडर में तारीख प्रारूप) के समान है । आप इसे केवल stdlib का उपयोग करके पार्स कर सकते हैं:

>>> from email.utils import parsedate_tz
>>> parsedate_tz('Tue Jun 22 07:46:22 EST 2010')
(2010, 6, 22, 7, 46, 22, 0, 1, -1, -18000)

विभिन्न पायथन संस्करणों के लिए टाइमज़ोन-जागरूक डेटाटाइम ऑब्जेक्ट प्राप्त करने वाले समाधान देखें: ईमेल से टाइमज़ोन के साथ पार्सिंग तिथि

इस प्रारूप में, ESTशब्दार्थ के बराबर है-0500 । हालांकि, सामान्य रूप से, एक टाइमज़ोन संक्षिप्त नाम पर्याप्त नहीं है, एक टाइमज़ोन की विशिष्ट पहचान करने के लिए


0

इस सटीक समस्या में भाग गया।

मैंने क्या किया:

# starting with date string
sdt = "20190901"
std_format = '%Y%m%d'

# create naive datetime object
from datetime import datetime
dt = datetime.strptime(sdt, sdt_format)

# extract the relevant date time items
dt_formatters = ['%Y','%m','%d']
dt_vals = tuple(map(lambda formatter: int(datetime.strftime(dt,formatter)), dt_formatters))

# set timezone
import pendulum
tz = pendulum.timezone('utc')

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