पायथन में आईएसओ समय (आईएसओ 8601)


339

मेरे पास एक फाइल है। पायथन में, मैं इसका निर्माण समय लेना चाहूंगा, और इसे पूर्वी समय क्षेत्र (ईटी) में बनाए गए तथ्य को संरक्षित करते हुए इसे आईएसओ समय (आईएसओ 8601) स्ट्रिंग में परिवर्तित करूंगा ।

मैं फ़ाइल का समय कैसे ले सकता हूं और इसे आईएसओ टाइम स्ट्रिंग में परिवर्तित कर सकता हूं जो पूर्वी समय क्षेत्र को इंगित करता है (और यदि आवश्यक हो तो दिन के उजाले की बचत के समय को ध्यान में रखता है)?



11
@ निक- उपयोगी लिंक, लेकिन डुप्लिकेट नहीं- वह दूसरे तरीके से परिवर्तित करने के बारे में पूछ रहा है।
यारिन

1
@ Joseph- मैं सिर्फ आरएफसी 3999- के संबंध में यह पूछे जाने पर इसकी लिए काम करना चाहिए - अजगर में उत्पन्न आरएफसी 3339 टाइमस्टैम्प
Yarin

जवाबों:


559

स्थानीय से आईएसओ 8601:

import datetime
datetime.datetime.now().isoformat()
>>> 2020-03-20T14:28:23.382748

UTC से ISO 8601:

import datetime
datetime.datetime.utcnow().isoformat()
>>> 2020-03-20T01:30:08.180856

माइक्रोसेकंड के बिना आईएसओ 8601 के लिए स्थानीय:

import datetime
datetime.datetime.now().replace(microsecond=0).isoformat()
>>> 2020-03-20T14:30:43

टाइमजोन जानकारी (पायथन 3) के साथ यूटीसी टू आईएसओ 8601:

import datetime
datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc).isoformat()
>>> 2020-03-20T01:31:12.467113+00:00

माइक्रोसेकंड (पायथन 3) के बिना स्थानीय टाइमजोन जानकारी के साथ यूटीसी टू आईएसओ 8601:

import datetime
datetime.datetime.now().astimezone().replace(microsecond=0).isoformat()
>>> 2020-03-20T14:31:43+13:00

TimeZone जानकारी के साथ आईएसओ 8601 के लिए स्थानीय (पायथन 3):

import datetime
datetime.datetime.now().astimezone().isoformat()
>>> 2020-03-20T14:32:16.458361+13:00

ध्यान दें कि astimezone()utc समय का उपयोग करते समय एक बग है । यह एक गलत परिणाम देता है:

datetime.datetime.utcnow().astimezone().isoformat() #Incorrect result

पायथन 2 के लिए, पाइत्ज़ देखें और उपयोग करें


17
.isoformat()एक विभाजक पैरामीटर ले सकते हैं, (यदि आप 'T' के अलावा कुछ चाहते हैं):.isoformat(' ')
ThorSummoner

5
@ThorSummoner जानकर अच्छा लगा! लेकिन ध्यान रखें कि विभाजक को बदलने से अब ISO-8601 का अनुपालन नहीं होगा ... जो थोड़ा सा समझ में आता है (इसके अलावा, तिथियों को प्रिंट करने के बेहतर तरीके हैं, लेकिन यहां यह सवाल नहीं था)। RFC
एस्टानी

4
ISO-8601 मानक के हिस्से के रूप में अंतरिक्ष की अनुमति है। It is permitted to omit the 'T' character by mutual agreement.
रेची

4
@ श्रेय हमेशा आपसी समझौते से एक मानक को बदलने की अनुमति है (जो कई मामलों में मानक को तोड़ देगा, लेकिन अगर यह आपसी समझौता है, तो कौन परवाह करता है?)। मेरा 2c: जैसा है, वैसा ही छोड़ दो।
एस्टानी

14
यह उत्तर गलत है, क्योंकि datetime.datetime.now ()। Isoformat () स्थानीय ISO 8601 स्ट्रिंग को स्थानीय के रूप में लेबल किए बिना लौटाता है। सही काम करने के लिए इसोफ़ॉर्मेट प्राप्त करने के लिए आपको स्थानीय टाइमज़ोन का प्रतिनिधित्व करने के लिए डेटाइमटाइम की आवश्यकता होती है।
सैम हार्टमैन

66

यहाँ मैं XSD डेटाटाइम प्रारूप में बदलने के लिए क्या उपयोग कर रहा हूँ:

from datetime import datetime
datetime.now().replace(microsecond=0).isoformat()
# You get your ISO string

XSD दिनांक समय प्रारूप ( xs:dateTime) की तलाश में मैं इस सवाल पर आया था । मुझे माइक्रोसेकंड को हटाने की जरूरत थी isoformat


4
क्या है "XSD" (इस प्रसंग में)?
पीटर मोर्टेंसन

1
मेरा मानना ​​है कि वह xs:dateXSD / XML स्टाइलशीट से मतलब है।
22

1
इसका अर्थ हैxs:dateTime
रात्रि

56

आईएसओ 8601 समय प्रतिनिधित्व

अंतर्राष्ट्रीय मानक आईएसओ 8601 तारीखों और समय के लिए एक स्ट्रिंग प्रतिनिधित्व का वर्णन करता है। इस प्रारूप के दो सरल उदाहरण हैं

2010-12-16 17:22:15
20101216T172215

(जो दोनों 16 दिसंबर 2010 के लिए खड़े हैं), लेकिन प्रारूप उप-सेकंड रिज़ॉल्यूशन समय और समय क्षेत्र निर्दिष्ट करने की भी अनुमति देता है। यह प्रारूप निश्चित रूप से पायथन-विशिष्ट नहीं है, लेकिन यह एक पोर्टेबल प्रारूप में दिनांक और समय संग्रहीत करने के लिए अच्छा है। इस प्रारूप के बारे में विवरण मार्कस कुह्न प्रविष्टि में पाया जा सकता है ।

मैं फ़ाइलों में समय स्टोर करने के लिए इस प्रारूप के उपयोग की सलाह देता हूं।

इस प्रतिनिधित्व में वर्तमान समय को प्राप्त करने का एक तरीका पायथन मानक पुस्तकालय में समय मॉड्यूल से स्ट्रैपटाइम का उपयोग करना है:

>>> from time import strftime
>>> strftime("%Y-%m-%d %H:%M:%S")
'2010-03-03 21:16:45'

आप डेटाइम वर्ग के स्ट्रैप्टम कंस्ट्रक्टर का उपयोग कर सकते हैं:

>>> from datetime import datetime
>>> datetime.strptime("2010-06-04 21:08:12", "%Y-%m-%d %H:%M:%S")
datetime.datetime(2010, 6, 4, 21, 8, 12)

सबसे मजबूत Egenix mxDateTime मॉड्यूल है:

>>> from mx.DateTime.ISO import ParseDateTimeUTC
>>> from datetime import datetime
>>> x = ParseDateTimeUTC("2010-06-04 21:08:12")
>>> datetime.fromtimestamp(x)
datetime.datetime(2010, 3, 6, 21, 8, 12)

संदर्भ


2
यह किस अर्थ में "अधिक मजबूत" है?
स्टीफन

दिनांक:2018-05-25
लक्सैक्स

यूटीसी में संयुक्त तिथि और समय:2018-05-25T12:16:14+00:00
लक्सैक्स

2
यूटीसी में संयुक्त तिथि और समय:2018-05-25T12:16:14Z
लक्सैक्स

यूटीसी में संयुक्त तिथि और समय:20180525T121614Z
लक्सैक्स

49

मैंने प्रलेखन में डेटाटाइम.आईसोफोर्मैट पाया । ऐसा लगता है कि आप क्या चाहते हैं:

datetime.isoformat([sep])

Return a string representing the date and time in ISO 8601 format, YYYY-MM-DDTHH:MM:SS.mmmmmm or, if microsecond is 0, YYYY-MM-DDTHH:MM:SS

If utcoffset() does not return None, a 6-character string is appended, giving the UTC offset in (signed) hours and minutes: YYYY-MM-DDTHH:MM:SS.mmmmmm+HH:MM or, if microsecond is 0 YYYY-MM-DDTHH:MM:SS+HH:MM

The optional argument sep (default 'T') is a one-character separator, placed between the date and time portions of the result. For example,
>>>

>>> from datetime import tzinfo, timedelta, datetime
>>> class TZ(tzinfo):
...     def utcoffset(self, dt): return timedelta(minutes=-399)
...
>>> datetime(2002, 12, 25, tzinfo=TZ()).isoformat(' ')
'2002-12-25 00:00:00-06:39'

30

आईएसओ 8601 के अलावा कोई विभाजक के साथ एक कॉम्पैक्ट प्रतिनिधित्व की अनुमति देता है T, इसलिए मैं इस एक-लाइनर का उपयोग करना चाहता हूं ताकि एक त्वरित टाइमस्टैम्प स्ट्रिंग प्राप्त हो सके:

>>> datetime.datetime.utcnow().strftime("%Y%m%dT%H%M%S.%fZ")
'20180905T140903.591680Z'

यदि आपको माइक्रोसेकंड की आवश्यकता नहीं है, तो बस .%fभाग को छोड़ दें :

>>> datetime.datetime.utcnow().strftime("%Y%m%dT%H%M%SZ")
'20180905T140903Z'

स्थानीय समय के लिए:

>>> datetime.datetime.now().strftime("%Y%m%dT%H%M%S")
'20180905T140903'

संपादित करें:

इस पर कुछ और पढ़ने के बाद, मैं आपको विराम चिह्न छोड़ने की सलाह देता हूं। RFC 3339 उस शैली की सिफारिश करता है क्योंकि यदि हर कोई विराम चिह्नों का उपयोग करता है, तो कई विरामों जैसी चीजों का जोखिम नहीं होता है जैसे कि कई विराम चिह्नों को उनके विराम चिह्न पर समूहों में क्रमबद्ध किया जा रहा है। तो एक अनुरूप स्ट्रिंग के लिए एक लाइनर होगा:

>>> datetime.datetime.now().strftime("%Y-%m-%dT%H:%M%SZ")
'2018-09-05T14:09:03Z'

3
क्या मिलीसेकंड के अंकों को 3 तक सीमित करने का कोई तरीका है? यानी मेरे अन्य जावास्क्रिप्ट एप्लिकेशन का उत्पादन करेगा 2019-02-23T04:02:04.051Zके साथnew Date().toISOString()
मिरांडा

19

आईएसओ 8601 समय प्रारूप एक समय क्षेत्र नाम की दुकान नहीं है, केवल इसी यूटीसी ऑफसेट संरक्षित है।

पायथन 3 में UTC ऑफसेट को संरक्षित करते हुए एक फ़ाइल cIME को ISO 8601 टाइम स्ट्रिंग में बदलने के लिए:

>>> import os
>>> from datetime import datetime, timezone
>>> ts = os.path.getctime(some_file)
>>> dt = datetime.fromtimestamp(ts, timezone.utc)
>>> dt.astimezone().isoformat()
'2015-11-27T00:29:06.839600-05:00'

कोड मानता है कि आपका स्थानीय समय क्षेत्र पूर्वी समय क्षेत्र (ET) है और यह कि आपका सिस्टम दिए गए POSIX टाइमस्टैम्प के लिए एक सही UTC ऑफसेट प्रदान करता है (ts ) के , अर्थात, Python के पास आपके सिस्टम या समय क्षेत्र में एक ऐतिहासिक timezone डेटाबेस तक पहुँच है। नियत तिथि पर समान नियम।

यदि आपको एक पोर्टेबल समाधान की आवश्यकता है; का उपयोग pytzमॉड्यूल है कि तक पहुँच प्रदान करता TZ डेटाबेस :

>>> import os
>>> from datetime import datetime
>>> import pytz  # pip install pytz
>>> ts = os.path.getctime(some_file)
>>> dt = datetime.fromtimestamp(ts, pytz.timezone('America/New_York'))
>>> dt.isoformat()
'2015-11-27T00:29:06.839600-05:00'

इस मामले में परिणाम समान है।

यदि आपको समय क्षेत्र नाम / संक्षिप्त नाम / ज़ोन आईडी की आवश्यकता है, तो इसे अलग से संग्रहीत करें।

>>> dt.astimezone().strftime('%Y-%m-%d %H:%M:%S%z (%Z)')
'2015-11-27 00:29:06-0500 (EST)'

नोट: नहीं, :यूटीसी ऑफसेट और ESTटाइमजोन संक्षेप में आईएसओ 8601 समय प्रारूप का हिस्सा नहीं है। यह अद्वितीय नहीं है।

एक ही पुस्तकालय के विभिन्न पुस्तकालय / विभिन्न संस्करण एक ही तिथि / समयक्षेत्र के लिए अलग-अलग समय क्षेत्र नियमों का उपयोग कर सकते हैं। यदि यह भविष्य की तारीख है तो नियम अभी तक अज्ञात हो सकते हैं। दूसरे शब्दों में, समान यूटीसी समय आपके द्वारा उपयोग किए जाने वाले नियमों के आधार पर एक अलग स्थानीय समय के अनुरूप हो सकता है - आईएसओ 8601 प्रारूप में एक समय की बचत यूटीसी समय और स्थानीय समय को संरक्षित करता है जो आपके प्लेटफॉर्म पर वर्तमान समय क्षेत्र के नियमों से मेल खाती है। । यदि आपके पास अलग-अलग नियम हैं, तो आपको स्थानीय समय को एक अलग प्लेटफॉर्म पर पुनर्गणना करने की आवश्यकता हो सकती है।


14

आपको os.statफ़ाइल निर्माण समय और स्वरूपण के लिए time.strftimeऔर संयोजन बनाने के लिए उपयोग करने की आवश्यकता होगी time.timezone:

>>> import time
>>> import os
>>> t = os.stat('C:/Path/To/File.txt').st_ctime
>>> t = time.localtime(t)
>>> formatted = time.strftime('%Y-%m-%d %H:%M:%S', t)
>>> tz = str.format('{0:+06.2f}', float(time.timezone) / 3600)
>>> final = formatted + tz
>>> 
>>> final
'2008-11-24 14:46:08-02.00'

क्या दिन के समय की बचत के लिए समय क्षेत्र का हिसाब है? ऐसा लगता है कि दिन की बचत समय की परवाह किए बिना tz समान होगा या नहीं।
जोसेफ टुरियन

2
वर्तमान में जो भी ऑफसेट लागू होगा वह होगा। यदि डीएसटी सक्रिय है, तो डीएसटी नहीं होने से इसकी एक अलग ऑफसेट होगी।
मैक्स श्वाबकेह

4

सही होने पर मुझे ठीक करें (मैं नहीं हूँ), लेकिन यूटीसी से ऑफसेट दिन के समय की बचत के साथ बदल जाता है। इसलिए आपको उपयोग करना चाहिए

tz = str.format('{0:+06.2f}', float(time.altzone) / 3600)

मेरा यह भी मानना ​​है कि संकेत अलग होना चाहिए:

tz = str.format('{0:+06.2f}', -float(time.altzone) / 3600)

मैं गलत हो सकता हूं, लेकिन मुझे ऐसा नहीं लगता।


2

मैं जेरेक के साथ सहमत हूं, और मैं आगे ध्यान देता हूं कि आईएसओ ऑफसेट विभाजक चरित्र एक बृहदान्त्र है, इसलिए मुझे लगता है कि अंतिम उत्तर चाहिए:

isodate.datetime_isoformat(datetime.datetime.now()) + str.format('{0:+06.2f}', -float(time.timezone) / 3600).replace('.', ':')

2

एस्टानी के उत्कृष्ट उत्तर के लिए एक छोटे से बदलाव को जोड़ना

टाइमज़ोन के साथ आईएसओ 8601 के लिए स्थानीय और कोई माइक्रोसेकंड जानकारी (पायथन 3):

import datetime, time

utc_offset_sec = time.altzone if time.localtime().tm_isdst else time.timezone
utc_offset = datetime.timedelta(seconds=-utc_offset_sec)
datetime.datetime.now().replace(microsecond=0, tzinfo=datetime.timezone(offset=utc_offset)).isoformat()

नमूना आउटपुट:

'2019-11-06T12:12:06-08:00'

परीक्षण किया गया कि इस आउटपुट को जावास्क्रिप्ट Dateऔर C # DateTime/ दोनों द्वारा पार्स किया जा सकता हैDateTimeOffset


1

मैंने यह फ़ंक्शन विकसित किया है:

def iso_8601_format(dt):
    """YYYY-MM-DDThh:mm:ssTZD (1997-07-16T19:20:30-03:00)"""

    if dt is None:
        return ""

    fmt_datetime = dt.strftime('%Y-%m-%dT%H:%M:%S')
    tz = dt.utcoffset()
    if tz is None:
        fmt_timezone = "+00:00"
    else:
        fmt_timezone = str.format('{0:+06.2f}', float(tz.total_seconds() / 3600))

    return fmt_datetime + fmt_timezone

-6
import datetime, time    
def convert_enddate_to_seconds(self, ts):
    """Takes ISO 8601 format(string) and converts into epoch time."""
     dt = datetime.datetime.strptime(ts[:-7],'%Y-%m-%dT%H:%M:%S.%f')+\
                datetime.timedelta(hours=int(ts[-5:-3]),
                minutes=int(ts[-2:]))*int(ts[-6:-5]+'1')
    seconds = time.mktime(dt.timetuple()) + dt.microsecond/1000000.0
    return seconds 

>>> import datetime, time
>>> ts = '2012-09-30T15:31:50.262-08:00'
>>> dt = datetime.datetime.strptime(ts[:-7],'%Y-%m-%dT%H:%M:%S.%f')+ datetime.timedelta(hours=int(ts[-5:-3]), minutes=int(ts[-2:]))*int(ts[-6:-5]+'1')
>>> seconds = time.mktime(dt.timetuple()) + dt.microsecond/1000000.0
>>> seconds
1348990310.26
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.