ISO 8601 DateTime String을 Python DateTime 객체로 어떻게 변환합니까? [복제하다
-
13-09-2019 - |
문제
이 질문은 이미 여기에 답이 있습니다.
"2009-05-28T16 : 15 : 00"과 같은 형식으로 DateTime 문자열을 받고 있습니다 (ISO 8601입니다). 하나의 해킹 옵션은 사용을 사용하여 문자열을 구문 분석하는 것 같습니다. time.strptime
튜플의 처음 6 가지 요소를 DateTime 생성자로 전달합니다.
datetime.datetime(*time.strptime("2007-03-04T21:08:12", "%Y-%m-%dT%H:%M:%S")[:6])
나는 이것을하는 "더 깨끗한"방법을 찾을 수 없었습니다. 하나있어?
해결책
나는 사용하는 것을 선호한다 날짜 시간대 처리 및 일반적으로 견고한 날짜 구문 분석 라이브러리. ISO 8601 문자열과 같이 : 2010-05-08T23 : 41 : 54.000Z와 같은 문자열을 얻으려면 특히 시간대가 포함되어 있는지 여부를 알지 못한 경우 StrPtime과 함께 재미있는 시간을 파싱 할 것입니다. PYISO8601에는 사용 중에 제가 실행 한 몇 가지 문제 (추적기 확인)가 있으며 몇 년 안에 업데이트되지 않았습니다. 대조적으로 DateUtil은 활발 해 왔으며 저를 위해 일했습니다.
import dateutil.parser
yourdate = dateutil.parser.parse(datestring)
다른 팁
Python 3.7 이후 외부 라이브러리가 없기 때문에 :
datetime.datetime.strptime('2019-01-04T16:41:24+0200', "%Y-%m-%dT%H:%M:%S%z")
Python 2는 지원하지 않습니다 %z
지정자 형식이므로 가능한 경우 Zulu Time Age에서 명시 적으로 사용하는 것이 가장 좋습니다.
datetime.datetime.strptime("2007-03-04T21:08:12Z", "%Y-%m-%dT%H:%M:%SZ")
ISO 8601은 기본적으로 많은 옵션 콜론과 대시의 변형을 허용하기 때문에 CCYY-MM-DDThh:mm:ss[Z|(+|-)hh:mm]
. strptime을 사용하려면 먼저 이러한 변형을 제거해야합니다.
목표는 UTC DateTime 객체를 생성하는 것입니다.
z 접미사와 같은 UTC에서 작동하는 기본 케이스를 원한다면 2016-06-29T19:36:29.3453Z
:
datetime.datetime.strptime(timestamp.translate(None, ':-'), "%Y%m%dT%H%M%S.%fZ")
시간대 오프셋을 처리하려면 2016-06-29T19:36:29.3453-0400
또는 2008-09-03T20:56:35.450686+05:00
다음을 사용하십시오. 이들은 모든 변형을 가변 구분자가없는 것으로 변환합니다. 20080903T205635.450686+0500
더 일관되거나 구문 분석하기가 더 쉬워집니다.
import re
# This regex removes all colons and all
# dashes EXCEPT for the dash indicating + or - utc offset for the timezone
conformed_timestamp = re.sub(r"[:]|([-](?!((\d{2}[:]\d{2})|(\d{4}))$))", '', timestamp)
datetime.datetime.strptime(conformed_timestamp, "%Y%m%dT%H%M%S.%f%z" )
시스템이 지원하지 않는 경우 %z
strptime 지시문 (당신은 같은 것을 볼 수 있습니다 ValueError: 'z' is a bad directive in format '%Y%m%dT%H%M%S.%f%z'
) 그런 다음 시간을 수동으로 상쇄해야합니다. Z
(UTC). 메모 %z
시스템/Python 빌드 유형 (즉, Python 빌드 유형에 따라 C 라이브러리 지원에 의존하므로 Python 버전 <3에서 시스템에서 작동하지 않을 수 있습니다. Jython, 시톤, 등.).
import re
import datetime
# This regex removes all colons and all
# dashes EXCEPT for the dash indicating + or - utc offset for the timezone
conformed_timestamp = re.sub(r"[:]|([-](?!((\d{2}[:]\d{2})|(\d{4}))$))", '', timestamp)
# Split on the offset to remove it. Use a capture group to keep the delimiter
split_timestamp = re.split(r"[+|-]",conformed_timestamp)
main_timestamp = split_timestamp[0]
if len(split_timestamp) == 3:
sign = split_timestamp[1]
offset = split_timestamp[2]
else:
sign = None
offset = None
# Generate the datetime object without the offset at UTC time
output_datetime = datetime.datetime.strptime(main_timestamp +"Z", "%Y%m%dT%H%M%S.%fZ" )
if offset:
# Create timedelta based on offset
offset_delta = datetime.timedelta(hours=int(sign+offset[:-2]), minutes=int(sign+offset[-2:]))
# Offset datetime with timedelta
output_datetime = output_datetime + offset_delta
TZ-AWARE DATETIME를 TZ-AWARE와 비교할 때 문제가 발생할 수 있으므로 시간대 정보를 주시해야합니다.
왜 그렇게하는 데 어떤 용도가 아닌지 알지 않는 한 항상 TZ-AWARE (UTC로만)를 인식하는 것이 가장 좋습니다.
#-----------------------------------------------
import datetime
import pytz
import dateutil.parser
#-----------------------------------------------
utc = pytz.utc
BERLIN = pytz.timezone('Europe/Berlin')
#-----------------------------------------------
def to_iso8601(when=None, tz=BERLIN):
if not when:
when = datetime.datetime.now(tz)
if not when.tzinfo:
when = tz.localize(when)
_when = when.strftime("%Y-%m-%dT%H:%M:%S.%f%z")
return _when[:-8] + _when[-5:] # Remove microseconds
#-----------------------------------------------
def from_iso8601(when=None, tz=BERLIN):
_when = dateutil.parser.parse(when)
if not _when.tzinfo:
_when = tz.localize(_when)
return _when
#-----------------------------------------------
나는 아직 시도하지 않았지만 pyiso8601 이것을 지원하겠다고 약속합니다.
이소 데이트 가장 완전한 지원을받는 것 같습니다.
두 가지 방법 :
Epoch to ISO 시간 :
isoTime = time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime(epochTime))
ISO 시대 시간 :
epochTime = time.mktime(time.strptime(isoTime, '%Y-%m-%dT%H:%M:%SZ'))
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
여기에는 밀리 초 및 시간대도 포함됩니다.
시간이 '2012-09-30t15 : 31 : 50.262-08 : 00'인 경우, 이는 시대 시간으로 변환됩니다.
>>> 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
다음은 이러한 종류의 전환을 수행하는 매우 간단한 방법입니다. 구문 분석 또는 추가 라이브러리가 필요하지 않습니다. 깨끗하고 단순하며 빠릅니다.
import datetime
import time
################################################
#
# Takes the time (in seconds),
# and returns a string of the time in ISO8601 format.
# Note: Timezone is UTC
#
################################################
def TimeToISO8601(seconds):
strKv = datetime.datetime.fromtimestamp(seconds).strftime('%Y-%m-%d')
strKv = strKv + "T"
strKv = strKv + datetime.datetime.fromtimestamp(seconds).strftime('%H:%M:%S')
strKv = strKv +"Z"
return strKv
################################################
#
# Takes a string of the time in ISO8601 format,
# and returns the time (in seconds).
# Note: Timezone is UTC
#
################################################
def ISO8601ToTime(strISOTime):
K1 = 0
K2 = 9999999999
K3 = 0
counter = 0
while counter < 95:
K3 = (K1 + K2) / 2
strK4 = TimeToISO8601(K3)
if strK4 < strISOTime:
K1 = K3
if strK4 > strISOTime:
K2 = K3
counter = counter + 1
return K3
################################################
#
# Takes a string of the time in ISO8601 (UTC) format,
# and returns a python DateTime object.
# Note: returned value is your local time zone.
#
################################################
def ISO8601ToDateTime(strISOTime):
return time.gmtime(ISO8601ToTime(strISOTime))
#To test:
Test = "2014-09-27T12:05:06.9876"
print ("The test value is: " + Test)
Ans = ISO8601ToTime(Test)
print ("The answer in seconds is: " + str(Ans))
print ("And a Python datetime object is: " + str(ISO8601ToDateTime(Test)))