'2009/05/13 19:19:30 -0400'형식의 날짜 문자열이 있습니다. 이전 버전의 Python은 후행 시간대 사양에 대해 strptime에서 % z 형식 태그를 지원했을 수 있지만 2.6.x는이를 제거한 것으로 보입니다.
이 문자열을 datetime 객체로 구문 분석하는 올바른 방법은 무엇입니까?
답변:
dateutil에서 구문 분석 기능을 사용할 수 있습니다.
>>> from dateutil.parser import parse
>>> d = parse('2009/05/13 19:19:30 -0400')
>>> d
datetime.datetime(2009, 5, 13, 19, 19, 30, tzinfo=tzoffset(None, -14400))
이렇게하면 사용할 수있는 datetime 객체를 얻을 수 있습니다.
대답 했듯이 dateutil2.0은 Python 3.0 용으로 작성되었으며 Python 2.x에서는 작동하지 않습니다. Python 2.x의 경우 dateutil1.5를 사용해야합니다.
%z
Python 3.2 이상에서 지원됩니다.
>>> from datetime import datetime
>>> datetime.strptime('2009/05/13 19:19:30 -0400', '%Y/%m/%d %H:%M:%S %z')
datetime.datetime(2009, 5, 13, 19, 19, 30,
tzinfo=datetime.timezone(datetime.timedelta(-1, 72000)))
이전 버전 :
from datetime import datetime
date_str = '2009/05/13 19:19:30 -0400'
naive_date_str, _, offset_str = date_str.rpartition(' ')
naive_dt = datetime.strptime(naive_date_str, '%Y/%m/%d %H:%M:%S')
offset = int(offset_str[-4:-2])*60 + int(offset_str[-2:])
if offset_str[0] == "-":
offset = -offset
dt = naive_dt.replace(tzinfo=FixedOffset(offset))
print(repr(dt))
# -> datetime.datetime(2009, 5, 13, 19, 19, 30, tzinfo=FixedOffset(-240))
print(dt)
# -> 2009-05-13 19:19:30-04:00
경우 FixedOffset
에 따라 클래스입니다 워드 프로세서의 코드 예제 :
from datetime import timedelta, tzinfo
class FixedOffset(tzinfo):
"""Fixed offset in minutes: `time = utc_time + utc_offset`."""
def __init__(self, offset):
self.__offset = timedelta(minutes=offset)
hours, minutes = divmod(offset, 60)
#NOTE: the last part is to remind about deprecated POSIX GMT+h timezones
# that have the opposite sign in the name;
# the corresponding numeric value is not used e.g., no minutes
self.__name = '<%+03d%02d>%+d' % (hours, minutes, -hours)
def utcoffset(self, dt=None):
return self.__offset
def tzname(self, dt=None):
return self.__name
def dst(self, dt=None):
return timedelta(0)
def __repr__(self):
return 'FixedOffset(%d)' % (self.utcoffset().total_seconds() / 60)
ValueError: 'z' is a bad directive in format '%Y-%m-%d %M:%H:%S.%f %z'
제 경우에는 (Python 2.7) 이 발생합니다 .
다음은 "%z"
Python 2.7 및 이전 문제에 대한 수정입니다.
사용하는 대신:
datetime.strptime(t,'%Y-%m-%dT%H:%M %z')
다음 timedelta
과 같이 시간대를 설명하려면를 사용하십시오 .
from datetime import datetime,timedelta
def dt_parse(t):
ret = datetime.strptime(t[0:16],'%Y-%m-%dT%H:%M')
if t[18]=='+':
ret-=timedelta(hours=int(t[19:22]),minutes=int(t[23:]))
elif t[18]=='-':
ret+=timedelta(hours=int(t[19:22]),minutes=int(t[23:]))
return ret
날짜는로 변환되어 GMT
시간대에 대한 걱정없이 날짜 산술을 수행 할 수 있습니다.
+
문자가 있으면 타임 델타를 빼야 하며 그 반대의 경우도 마찬가지입니다. 코드를 수정하고 수정했습니다.
dateutil을 사용할 때의 문제는 dateutil에 제한된 형식 지정 옵션 ( dayfirst
및 전용 yearfirst
) 이 있으므로 serialization과 deserialization 모두에 대해 동일한 형식 문자열을 사용할 수 없다는 것 입니다.
내 응용 프로그램에서 형식 문자열을 .INI 파일에 저장하고 각 배포에는 고유 한 형식이있을 수 있습니다. 따라서 나는 dateutil 접근 방식을 정말로 좋아하지 않습니다.
대신 pytz를 사용하는 대체 방법은 다음과 같습니다.
from datetime import datetime, timedelta
from pytz import timezone, utc
from pytz.tzinfo import StaticTzInfo
class OffsetTime(StaticTzInfo):
def __init__(self, offset):
"""A dumb timezone based on offset such as +0530, -0600, etc.
"""
hours = int(offset[:3])
minutes = int(offset[0] + offset[3:])
self._utcoffset = timedelta(hours=hours, minutes=minutes)
def load_datetime(value, format):
if format.endswith('%z'):
format = format[:-2]
offset = value[-5:]
value = value[:-5]
return OffsetTime(offset).localize(datetime.strptime(value, format))
return datetime.strptime(value, format)
def dump_datetime(value, format):
return value.strftime(format)
value = '2009/05/13 19:19:30 -0400'
format = '%Y/%m/%d %H:%M:%S %z'
assert dump_datetime(load_datetime(value, format), format) == value
assert datetime(2009, 5, 13, 23, 19, 30, tzinfo=utc) \
.astimezone(timezone('US/Eastern')) == load_datetime(value, format)
Linux를 사용하는 경우 외부 date
명령을 사용하여 dwim 할 수 있습니다 .
import commands, datetime
def parsedate(text):
output=commands.getoutput('date -d "%s" +%%s' % text )
try:
stamp=eval(output)
except:
print output
raise
return datetime.datetime.frometimestamp(stamp)
물론 이것은 dateutil보다 이식성이 떨어지지 만 date
"어제"또는 "작년"과 같은 입력도 허용 하므로 약간 더 유연합니다. :-)
dateutil
Python 에서 나에게 잘 작동합니다 ( 2.1)2.7.2
. Python 3은 필요하지 않습니다. pip에서 설치하는 경우 패키지 이름은python-dateutil
.