파이썬 strptime () 및 시간대?


157

IPDDump를 사용하여 생성 된 Blackberry IPD 백업의 CSV 덤프 파일이 있습니다. 여기의 날짜 / 시간 문자열은 다음과 같습니다 ( EST호주 시간대).

Tue Jun 22 07:46:22 EST 2010

이 날짜를 파이썬으로 구문 분석 할 수 있어야합니다. 처음에는 strptime()datettime부터 함수 를 사용하려고했습니다 .

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

그러나 어떤 이유로 datetime되돌아 오는 개체 와 관련된 개체가없는 것 같습니다 tzinfo.

나는 이 페이지 에서 분명히 datetime.strptime자동으로 버리는 내용을 읽었 tzinfo지만 문서를 확인했는데 여기에 문서화 된 그 영향에 대한 것을 찾을 수 없습니다 .

타사 Python 라이브러리 인 dateutil을 사용하여 날짜를 파싱 할 수 있었지만 내장 기능을 strptime()잘못 사용하는 방법에 대해 여전히 궁금합니다 . strptime()시간대를 잘 활용하는 방법이 있습니까?


1
모든 날짜를 GMT로 변환 할 수 없습니까?
Robus

2
@Robus : 흠, 나는 그렇게하기를 바랐지만 strftime / datetime이 어떻게 든 그렇게 할 수 있다고 가정하고 있습니까? 어느 쪽이든, 나는 날짜 시간이 EST 시간대에 있다는 사실 또는 그들이 나에게 발생하는 시간대를 저장 / 파싱해야합니다. 스크립트는 시간대 정보로 일반 날짜 시간을 구문 분석 할 수 있어야합니다 (예 : ETC는 다른 시간대 일 수 있음).
victorhooi

3
EST는 미국 시간대 약어이기도합니다. 유사하게 BST는 영국 및 브라질 시간대 abbrev입니다. 이러한 약어는 본질적으로 모호합니다. 대신 UTC / GMT를 기준으로 오프셋을 사용하십시오. (약어를 지원해야하는 경우 매핑 로캘에 따라 달라야하며 지저분한 쥐 구멍입니다.)
Donal Fellows

답변:


58

datetime모듈 문서는 말합니다 :

형식에 따라 파싱 된 date_string에 해당하는 날짜 시간을 반환합니다. 이는에 해당합니다 datetime(*(time.strptime(date_string, format)[0:6])).

저거 봐 [0:6]? 그게 당신을 얻는다 (year, month, day, hour, minute, second). 다른 건 없어 시간대에 대한 언급이 없습니다.

흥미롭게도, [Win XP SP2, Python 2.6, 2.7] 예제를 time.strptime전달해도 작동하지 않지만 "% Z"와 "EST"를 제거하면 작동합니다. 또한 "EST"대신 "UTC"또는 "GMT"를 사용하십시오. "PST"및 "MEZ"가 작동하지 않습니다. 수수께끼.

이것이 3.2 버전으로 업데이트되었으며 동일한 문서에도 다음 내용이 표시됩니다.

% z 지시문이 strptime () 메소드에 제공되면 인식하는 datetime 오브젝트가 생성됩니다. 결과의 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

python-dateutil 사용하는 것이 좋습니다 . 파서는 지금까지 던진 모든 날짜 형식을 파싱 할 수있었습니다.

>>> 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. 그러나이 답변이 날짜 구문 분석 질문이 있고 해당 모듈의 유틸리티를 볼 때이 질문을 우연히 발견하는 다른 사람들에게 여전히 유용하기를 바랍니다.


너무 많은 사람들이 python-dateutil을 사용하는 경향이 있다는 것을 감안할 때, 나는 그 lib의 한 가지 한계를 지적하고 싶습니다. >>> 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
wanghq

1
@wanghq 마지막 쉼표를 마침표로 바꿔야합니다. 그때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))
flyingfoxlee

7
@ flyingfoxlee, 예, 이해합니다. 사람들에게 python-dateutil의 한계를 말하고 싶습니다. 그것은 마술적인 일을하지만 때로는 그렇게하지 않습니다. 그래서 "그냥 날짜를 던져서 올바른 일을합니다." 100 % 사실이 아닙니다.
wanghq

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)

다양한 Python 버전에 대해 시간대 인식 datetime 객체를 생성하는 솔루션을 참조하십시오 : 전자 메일에서 시간대로 날짜 구문 분석 .

이 형식에서는 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)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.