Python의 ISO 시간 (ISO 8601)


340

파일이 있습니다. 파이썬에서는 생성 시간을 가져 와서 동부 표준시 (ET) 에서 만들어진 사실을 유지하면서 ISO 시간 (ISO 8601) 문자열 로 변환하고 싶습니다 .

파일의 ctime을 동부 표준 시간대를 나타내는 ISO 시간 문자열로 변환하고 필요한 경우 일광 절약 시간을 고려하는 방법은 무엇입니까?



11
@ Nick- 유용한 링크이지만 중복은 아닙니다. 그는 다른 방법으로 변환을 요구하고 있습니다.
— Yarin

1
@ Joseph- 방금 RFC 3999와 관련하여이 질문을했습니다.이 작업을 수행해야합니다.- Python에서 RFC 3339 타임 스탬프 생성
— Yarin

답변:


560

로컬 ISO 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

마이크로 초가없는 ISO 8601에 로컬 :

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

TimeZone 정보 (Python 3)와 함께 UTC에서 ISO 8601로 :

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

마이크로 초가없는 로컬 TimeZone 정보를 사용하여 UTC에서 ISO 8601로 (Python 3) :

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

TimeZone 정보가 포함 된 ISO 8601에 로컬 (Python 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

Python 2의 경우 pytz를 참조하십시오 .


17
.isoformat()구분자 매개 변수를 사용할 수 있습니다 ( 'T'이외의 다른 것을 원하는 경우) :.isoformat(' ')
— ThorSummoner

5
@ThorSummoner를 알게되었습니다! 그러나 구분 기호를 변경해도 더 이상 ISO-8601을 준수하지 않도록주의하십시오 ... 이것은 거의 이해가되지 않습니다 (날짜를 인쇄하는 더 좋은 방법이 있지만 여기서는 문제가되지 않았습니다). RFC
— estani

4
공간은 ISO-8601 표준의 일부로 허용됩니다. It is permitted to omit the 'T' character by mutual agreement.
— raychi

4
@raychi 항상 상호 합의에 의해 표준을 변경할 수 있습니다 (많은 경우에 표준을 어기는 것이지만 누가 상호 합의인지에 관심이 있습니까?). 내 2c : 그대로 두지 마십시오.
— estani

14
datetime.datetime.now (). isoformat ()은 로컬 ISO로 레이블을 지정하지 않고 로컬 ISO 8601 문자열을 반환하기 때문에이 답변은 잘못되었습니다. isoformat이 올바른 작업을 수행하도록하려면 현지 시간대를 나타내는 datetime.timezone이 있어야합니다.
— Sam Hartman

66

다음은 XSD 날짜 / 시간 형식으로 변환하는 데 사용하는 것입니다.

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

XSD 날짜 시간 형식 ( xs:dateTime)을 찾을 때이 질문을 보았습니다 . 에서 마이크로 초를 제거해야했습니다 isoformat.


4
"XSD" 란 무엇입니까 ?
— Peter Mortensen

1
나는 그가 xs:dateXSD / XML 스타일 시트 를 의미한다고 생각 합니다.
— sventechie

1
그것은 의미xs:dateTime
— radtek

56

ISO 8601 시간 표현

국제 표준 ISO 8601은 날짜 및 시간에 대한 문자열 표현을 설명합니다. 이 형식의 간단한 두 가지 예는

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

(이 둘은 2010 년 12 월 16 일을 의미하지만) 형식은 초 단위의 해결 시간을 허용하고 시간대를 지정할 수도 있습니다. 이 형식은 물론 Python에 한정되지 않지만 날짜와 시간을 이식 가능한 형식으로 저장하는 데 좋습니다. 이 형식에 대한 자세한 내용은 Markus Kuhn 항목을 참조하십시오 .

이 형식을 사용하여 파일에 시간을 저장하는 것이 좋습니다.

이 표현에서 현재 시간을 얻는 한 가지 방법은 Python 표준 라이브러리의 시간 모듈에서 strftime을 사용하는 것입니다.

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

datetime 클래스의 strptime 생성자를 사용할 수 있습니다.

>>> 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
어떤 점에서 "보다 강력"합니까?
— Stéphane

날짜 :2018-05-25
— loxaxs 12

UTC로 결합 된 날짜 및 시간 :2018-05-25T12:16:14+00:00
— loxaxs

2
UTC로 결합 된 날짜 및 시간 :2018-05-25T12:16:14Z
— loxaxs

UTC로 결합 된 날짜 및 시간 :20180525T121614Z
— loxaxs

49

설명서 에서 datetime.isoformat을 찾았습니다 . 원하는 것을하는 것 같습니다.

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

ISO 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 는 모든 사람들이 문장 부호를 사용하면 여러 ISO 8601 문자열과 같은 문장 부호가 그룹으로 분류 될 위험이 없으므로 스타일을 권장합니다. 따라서 호환 문자열에 대한 하나의 라이너는 다음과 같습니다.

>>> 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()
— Miranda

19

ISO 8601 시간 형식 시간대 이름을 저장하지 않고, 단지 대응 UTC 오프셋은 유지된다.

Python 3에서 UTC 오프셋을 유지하면서 파일 ctime을 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 타임 스탬프 ( ts)에 대해 올바른 UTC 오프셋을 제공 한다고 가정합니다 . 즉, Python이 시스템의 히스토리 시간대 데이터베이스에 액세스하거나 시간대가 주어진 날짜에 동일한 규칙.

휴대용 솔루션이 필요한 경우 tz 데이터베이스에 대한 액세스를 제공 하는 pytz모듈 을 사용하십시오 .

>>> 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'

이 경우 결과는 동일합니다.

시간대 이름 / 약어 / 구역 ID가 필요한 경우 별도로 저장하십시오.

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

참고 : 아니요, :UTC 오프셋 및 EST시간대 약어는 ISO 8601 시간 형식의 일부가 아닙니다. 고유하지 않습니다.

동일한 라이브러리의 다른 라이브러리 / 다른 버전은 동일한 날짜 / 시간대에 대해 다른 시간대 규칙을 사용할 수 있습니다. 미래 날짜 인 경우 규칙을 아직 알 수 없습니다. 즉, 동일한 UTC 시간은 사용하는 규칙에 따라 다른 현지 시간에 해당 할 수 있습니다. ISO 8601 형식으로 시간을 절약하면 UTC 시간과 플랫폼에서 사용 중인 현재 시간대 규칙에 해당하는 현지 시간이 보존 됩니다. . 규칙이 다른 다른 플랫폼에서 현지 시간을 다시 계산해야 할 수도 있습니다.


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는 같은 것 같습니다.
— Joseph Turian

2
현재 적용되는 오프셋이 무엇이든됩니다. DST가 활성화되어 있으면 DST가 아닌 경우와 다른 오프셋을 갖습니다.
— Max Shawabkeh

4

내가 틀렸다면 정정하십시오.하지만 UTC와의 오프셋은 일광 절약 시간에 따라 변경됩니다. 그래서 당신은 사용해야합니다

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

또한 표시가 달라야한다고 생각합니다.

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

나는 틀릴 수 있지만 그렇게 생각하지 않습니다.


2

나는 Jarek에 동의하며 ISO 오프셋 구분 문자는 콜론이라는 점에 유의해야하므로 최종 답변은 다음과 같아야합니다.

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

2

estani의 탁월한 답변에 작은 변형 추가

TimeZone 및 마이크로 초 정보가 없는 ISO 8601에 로컬 (Python 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'

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