파이썬에서 "시간대를 인식하는"datetime.today () 값을 얻으려면 어떻게해야합니까?


310

datetime.today()얼마나 오래 전에 무언가를 계산하기 위해 값에서 하나의 날짜 값을 빼려고 합니다. 그러나 그것은 불평합니다 :

TypeError: can't subtract offset-naive and offset-aware datetimes

값은 datetime.today()내 다른 날짜 값 인 반면, "시간대 인식"될 것 같지 않습니다. datetime.today()시간대를 인식하는 그 가치를 어떻게 얻 습니까?

현재 현지 시간으로 시간을 제공하고 있습니다. PST는 UTC-8 시간입니다. 최악의 경우, datetime반환 된 객체에 시간대 값을 수동으로 입력하고 datetime.today()UTC-8로 설정할 수 있습니까?

물론 이상적인 해결책은 시간대를 자동으로 아는 것입니다.



10
datetime.now().astimezone()파이썬 3.6부터 사용할 수있는 것 같습니다
johnchen902

답변:


362

표준 라이브러리에는 자체 시간대 클래스를 만들지 않고 인식 가능한 시간대를 만드는 플랫폼 간 방법이 없습니다.

Windows에는이 win32timezone.utcnow()있지만 pywin32의 일부입니다. 차라리 대부분의 시간대의 데이터베이스가 지속적으로 업데이트되는 pytz 라이브러리 를 사용하는 것이 좋습니다 .

현지 시간대로 작업하는 것은 매우 까다로울 수 있으므로 (아래의 "추가 읽기"링크 참조) 응용 프로그램 전체에서 UTC를 사용하는 것이 좋습니다. 특히 두 시점 간의 차이 계산과 같은 산술 연산에 유용합니다.

다음과 같이 현재 날짜 / 시간을 얻을 수 있습니다.

import pytz
from datetime import datetime
datetime.utcnow().replace(tzinfo=pytz.utc)

것을 마음 datetime.today()datetime.now()반환 지역 때문에 적용이 아닌 UTC 시간을 시간을 .replace(tzinfo=pytz.utc)그들에게이 올바르지 않을 것입니다.

또 다른 좋은 방법은 다음과 같습니다.

datetime.now(pytz.utc)

조금 짧아서 똑같습니다.


많은 경우에 UTC를 선호하는 이유를 더 읽고 :


75
방법에 대해 datetime.now(pytz.utc)대신 datetime.utcnow().replace(tzinfo = pytz.utc)?
유미로

5
now(utc)UTC로 자정이 아닌 한 오늘 반환하지 않으면 UTC로 현재 시간을 반환합니다. 또한 필요 .replace(hour=0, minute=0, ...)(같은 하루의 시작을 얻기 위해 datetime.today())
JFS

1
문서는 그 말을 today()반환에게 현재 시간이 아닌 자정. 자정이 필요한 유스 케이스가있는 경우, 그에 따라 교체를 수행해야합니다. 원래 질문은 날짜 시간 차이에 관한 것이 었으므로 자정이 필요하다고 생각하지 않습니다.
AndiDog

1
@AndiDog : 내 의견은 내가 그 (잘못) 생각한다는 의미 datetime.today()입니다 combine(date.today(), time()). datetime모두가 .now().today()방법 그 (정확하게 지적했듯이) 반환 (거의) 같은 일을. 방법이 없습니다 date.now(). datedatetime개체가 서로 호환되지 않습니다. 객체 대신 datetime 객체를 사용하면 date미묘한 버그가 발생할 수 있습니다. datetime.today()에 거의 복제 된 경우 존재할 이유가 없습니다 datetime.now().
jfs

6
이 답변에 django를 사용 timezone.now()하는 datetime.now()경우 UTC 대신 자동으로 if를 사용하기 때문에 대신 항상 사용 하십시오 USE_TZ = True. 문서 timezone위치 django.utils.timezone: docs.djangoproject.com/en/1.11/topics/i18n/timezones
Ryan

107

특정 시간대에서 현재 시간을 가져옵니다.

import datetime
import pytz
my_date = datetime.datetime.now(pytz.timezone('US/Pacific'))

2
참조 .
wim

1
출력을 제외하고 현지화 된 시간을 사용해서는 안됩니다. 표준 시간대 기반 날짜 시간을 사용할 때 많은 문제가 발생합니다. UTC 시간이 아닌 한 간단한 표준 시간대는 일광 절약 시간을 고려하지 않습니다. UTC를 기준으로 항상 시간대 인식을 사용하십시오. 필요할 때 출력에서 ​​현지 시간대로 변환합니다.
MrE

4
@MrE와의 의견 불일치를 반복하기 위해 이전에 허용 된 답변에 대한 의견에서 언급 한 바 있습니다. 현지화 된 날짜 시간으로 작업해야하는 이유는 완벽하며 "출력을 제외하고 현지화 된 시간을 사용해서는 안됩니다"라는 말 은 지나치게 광범위한 조언입니다. 시계가 1 시간 뒤로 돌아가는 일광 절약 시간제 경계 몇 시간 전에 날짜 / 시간에 1 일을 추가한다고 가정합니다. 어떤 결과를 원하십니까? 시간이 같아야한다고 생각되면 현지화 된 날짜 / 시간을 사용하십시오. 한 시간 더 빨라야한다고 생각되면 UTC 또는 표준 시간대 기반 날짜 시간을 사용하십시오. 의미는 도메인에 따라 다릅니다.
Mark Amery

@MarkAmery 나는 당신이 며칠 또는 몇 시간을 추가하거나 제출하고 시간대 문제 (예 :와 같은)를 신경 쓰지 않을 것이라고 동의 할 수있는 한,이 의견은 시간대 수정 시간을 고객에게 전달하는 것과 관련이 있습니다. Python은 주로 백엔드 프로세스에 사용되므로 시간이 클라이언트에 전달됩니다. 단지의 출력을 확인하십시오, 그렇지 않으면 나쁜 일이 발생, 서버는 항상 UTC 날짜 / 시간을 통과해야하며, 클라이언트는 자신의 현지 날짜 / 시간 / 시간대로 변환해야 datetime.datetime(2016, 11, 5, 9, 43, 45, tzinfo=pytz.timezone('US/Pacific'))그게 당신이 기대했던 있는지 볼
MRE

"서버는 항상 날짜 / 시간을 UTC로 전달해야하며 클라이언트는 해당 서버를 자체 로컬 날짜 / 시간 / 시간대로 변환해야합니다." -아니요, 이것은 사실이 아닙니다. 때때로 클라이언트의 시간대를 사용하는 것은 부적절하며 데이터의 일부로 적절한 시간대를 전송해야합니다. 런던 사람들이 자신의 웹 사이트에서 샌프란시스코 체스 클럽의 모임 시간을 보는 경우 런던 시간이 아닌 샌프란시스코 시간에 볼 수 있습니다.
Mark Amery

69

Python 3에서 표준 라이브러리를 사용하면 UTC를 시간대로 훨씬 쉽게 지정할 수 있습니다.

>>> import datetime
>>> datetime.datetime.now(datetime.timezone.utc)
datetime.datetime(2016, 8, 26, 14, 34, 34, 74823, tzinfo=datetime.timezone.utc)

표준 라이브러리 만 사용하고 Python 2와 Python 3 모두에서 작동하는 솔루션을 원한다면 jfs의 답변을 참조하십시오 .

UTC가 아닌 현지 시간대가 필요한 경우 Mihai Capotă의 답변을 참조하십시오


19

다음은 Python 2와 3에서 작동하는 stdlib 솔루션입니다.

from datetime import datetime

now = datetime.now(utc) # Timezone-aware datetime.utcnow()
today = datetime(now.year, now.month, now.day, tzinfo=utc) # Midnight

여기서 todayUTC의 하루 시작 (자정)을 나타내는 인식 가능한 날짜 시간 인스턴스 utc이며 tzinfo 객체입니다 ( 문서의 예 ).

from datetime import tzinfo, timedelta

ZERO = timedelta(0)

class UTC(tzinfo):
    def utcoffset(self, dt):
        return ZERO

    def tzname(self, dt):
        return "UTC"

    def dst(self, dt):
        return ZERO

utc = UTC()

관련 : 주어진 UTC 시간에 자정을 얻는 몇 가지 방법 의 성능 비교 . 참고 : UTC 오프셋이 고정되지 않은 시간대의 자정얻는 것이 더 복잡 합니다.


16

현재 시간을 나타내는 시간대 인식 날짜 / 시간 객체를 구성하는 다른 방법 :

import datetime
import pytz

pytz.utc.localize( datetime.datetime.utcnow() )  

참고 pytz.utcpytz.UTC모두 정의 (와 동일)있다
drevicko

2
더 보편적이기 때문에이 대답은 더 허용 하나보다 : replace()동안 시간대를 보내고하는 것은, 일반적으로 오류가 발생하기 쉬운 대부분의 다른 용도에 localize()보내고 순진 타임 스탬프에 시간대를 할당 선호하는 방법입니다.
Antony Hatchkins

@AntonyHatchkins : .localize()모호한 현지 시간 (비 UTC 입력)에 대해 메소드가 실패합니다. 이러한 경우에도 사용하는 @philfreo의 답변은.now(pytz_timezone) 계속 작동합니다.
jfs

python 문서에 지정된 .now(pytz_timezone)것과 같이 정확히 동일합니다 localize(utcnow)-먼저 UTC로 현재 시간을 생성 한 다음 시간대를 지정합니다. "<...>이 경우 결과는 tz.fromutc(datetime.utcnow().replace(tzinfo=tz))" 와 같습니다 . 두 대답 모두 정확하고 항상 작동합니다.
Antony Hatchkins

1
시간대를 안전하게 인식 할 수있는 유일한 순진한 (un-utc) 시간은 이제 기본 시스템은 UTC 값을 알고 있고 pytzOLSON db를 통해 세계의 시간대로 변환하는 방법을 알고 있어야합니다. 일광 절약 시간 제로 인한 애매 모호함으로 인해 다른 순진한 시간대를 인식하는 것은 어렵습니다. 그것은 문제가 아닙니다 .localize( is_dst값을 먹이면 어떤 날짜에도 효과가 있습니다). 그것은 일광 절약 연습의 본질적인 문제입니다.
Antony Hatchkins

16

표준 라이브러리 만 사용하는 단일 라이너는 Python 3.3부터 작동합니다. ( johnchen902에서 제안한대로 )를 datetime사용하여 현지 시간대 인식 객체를 얻을 수 있습니다 .astimezone

from datetime import datetime, timezone

aware_local_now = datetime.now(timezone.utc).astimezone()

print(aware_local_now)
# 2020-03-03 09:51:38.570162+01:00

print(repr(aware_local_now))
# datetime.datetime(2020, 3, 3, 9, 51, 38, 570162, tzinfo=datetime.timezone(datetime.timedelta(0, 3600), 'CET'))

2
이 문서는 docs.python.org/3.8/library/…에 있는 큰 도움이됩니다 . 이 믿을 수 없을만큼 기본적인 기능은 문서의 모호한 단락에 깊이 묻혀 있어이 스택 오버 플로우 답변이 효과적으로 전체 인터넷 에서이 정보를 얻을 수있는 유일한 장소입니다. 문서에서 파이썬 3.6부터는 datetime.now()인수없이 호출 할 수 있으며 올바른 지역 결과를 반환 할 수 있음을 알 수 있습니다 (순진한 datetime것은 현지 시간대에 있다고 가정합니다).
atimholt

8

Django 를 사용하는 경우 날짜를 tz를 인식하지 못하도록 설정할 수 있습니다 ( UTC 만 ).

settings.py에서 다음 줄을 주석 처리 하십시오.

USE_TZ = True

8
이 질문에서 django가 어디에서 언급 되었습니까?
vonPetrushev

1
어떤 친절한 영혼이 내 이전의 주석 사과를 여기에서 삭제 했으므로 다시 한 번 : 부끄러움, 질문이 장고 특정이 아니기 때문에 잘못된 대답. 어쨌든 일부 사용자에게 도움이 될 수 있기 때문에 점수를 매겼지만 점수가 0에 가까워지면 삭제하겠습니다.이 답변이 부적절하면 자유롭게 투표하십시오.
laffuste

6

피츠 는 Python 2.3 이상을 사용하여 정확하고 교차 플랫폼 시간대 계산을 허용하는 Python 라이브러리입니다.

stdlib를 사용하면 불가능합니다.

SO 에 대한 비슷한 질문을 참조하십시오 .


6

stdlib로 생성하는 방법은 다음과 같습니다.

import time
from datetime import datetime

FORMAT='%Y-%m-%dT%H:%M:%S%z'
date=datetime.strptime(time.strftime(FORMAT, time.localtime()),FORMAT)

date 는 UTC 시간대의 날짜가 아닌 UTC 의 현지 날짜와 오프셋을 저장 하므로 날짜가 생성 된 시간대 를 식별해야하는 경우이 솔루션을 사용할 수 있습니다 . 이 예와 현지 시간대 :

date
datetime.datetime(2017, 8, 1, 12, 15, 44, tzinfo=datetime.timezone(datetime.timedelta(0, 7200)))

date.tzname()
'UTC+02:00'

핵심은 %z생성 된 시간 구조체의 UTC 오프셋을 나타 내기 위해 FORMAT 표시에 지시문을 추가하는 것 입니다. 다른 표현 형식은 datetime 모듈 문서 에서 참조 할 수 있습니다

UTC 시간대의 날짜가 필요한 경우 time.localtime ()time.gmtime ()으로 바꿀 수 있습니다.

date=datetime.strptime(time.strftime(FORMAT, time.gmtime()),FORMAT)

date    
datetime.datetime(2017, 8, 1, 10, 23, 51, tzinfo=datetime.timezone.utc)

date.tzname()
'UTC'

편집하다

이것은 python3에서만 작동합니다 . Python 2 _strptime.py 코드 에서 z 지시문을 사용할 수 없습니다.


ValueError : 'z'는 '% Y- % m- % dT % H : % M : % S % z'형식의 잘못된 지시문입니다.
jno

파이썬 2에 있습니까? 불행히도, 파이썬 2에서는 z 지시어를 사용할 수없는 것 같습니다. _strptime.py 코드
jcazor

6

시간대를 인식하는 Python datetime.datetime.now ()에 설명 된대로 dateutil을 사용하십시오 .

from dateutil.tz import tzlocal
# Get the current date/time with the timezone.
now = datetime.datetime.now(tzlocal())

1
이것이 잘못된 결과를 초래하는 상황에 대해서는 JF Sebastian의 답변 을 참조하십시오 .
Antony Hatchkins

2
다른 게시물의 오류는 특정 사용 사례에만 관련이 있다고 생각합니다. 이 tzlocal()기능은 여전히 ​​가장 간단한 솔루션 중 하나이며 여기에서 분명히 언급해야합니다.
user8162

2

시간대 인식 날짜 얻기 utc 표준 시간대로 가져 오면 날짜 빼기가 작동하기에 충분합니다.

그러나 현재 시간대의 시간대 인식 날짜를 원하면 다음을 수행하십시오 tzlocal.

from tzlocal import get_localzone  # pip install tzlocal
from datetime import datetime
datetime.now(get_localzone())

PS dateutil는 비슷한 기능을 가지고 있습니다 ( dateutil.tz.tzlocal). 그러나 이름을 공유하더라도 JF Sebastian이 지적한 바와 같이 완전히 다른 코드베이스가 있으므로 잘못된 결과를 얻을 수 있습니다.


파이썬은 일반적으로 서버에서 사용됩니다. 서버의 현지 시간대는 일반적으로 무의미하며 항상 UTC로 설정해야합니다. 이 방법으로 datetime tzinfo를 설정하지 못하는 경우가 있습니다. UTC를 더 잘 사용하고 출력시 원하는 시간대로 현지화하십시오. 예를 들어 모든 타임 델타 계산은 일광 절약을 고려하지 않으므로 UTC로 수행 한 다음 현지화해야합니다.
MrE

@MrE 틀린 주제, 예?
Antony Hatchkins

일광 절약 시간을 준수하는 시간대로 현지화 된 날짜 / 시간 객체를 사용하고 일광 절약 상태를 변경하기 위해 며칠을 추가하면 현지화 된 시간대의 날짜 / 시간 객체에서 작동하는 데 실패하고 일광 절약을 고려하지 않음을 알 수 있습니다. 따라서 항상 UTC 시간으로 날짜 시간 작업을 수행해야한다는 의견.
MrE

요점 :이 작업을 수행하지 말고 UTC로 작업 한 다음 datetime.astimezone (timezone)을 사용하여 출력시 현지 시간대로 변환하십시오.
MrE

2

다음은 읽을 수있는 시간대를 사용하는 솔루션이며 today ()와 작동합니다.

from pytz import timezone

datetime.now(timezone('Europe/Berlin'))
datetime.now(timezone('Europe/Berlin')).today()

다음과 같이 모든 시간대를 나열 할 수 있습니다.

import pytz

pytz.all_timezones
pytz.common_timezones # or

1

특히 비 UTC 시간대의 경우 :

자체 방법이있는 유일한 시간대는 timezone.utc이지만 필요한 경우 timedelta& 를 사용 timezone하고 강제 로 사용하여 UTC 오프셋으로 시간대를 퍼지 할 수 있습니다 .replace.

In [1]: from datetime import datetime, timezone, timedelta

In [2]: def force_timezone(dt, utc_offset=0):
   ...:     return dt.replace(tzinfo=timezone(timedelta(hours=utc_offset)))
   ...:

In [3]: dt = datetime(2011,8,15,8,15,12,0)

In [4]: str(dt)
Out[4]: '2011-08-15 08:15:12'

In [5]: str(force_timezone(dt, -8))
Out[5]: '2011-08-15 08:15:12-08:00'

timezone(timedelta(hours=n))표준 시간대로 사용 하는 것이 여기의 진정한 총알이며 다른 유용한 응용 프로그램이 많이 있습니다.


0

파이썬에서 현재 시간과 날짜를 얻은 다음 날짜와 시간을 가져옵니다 .pytz 패키지는 파이썬에서 현재 날짜와 시간을 가져옵니다.

from datetime import datetime
import pytz
import time
str(datetime.strftime(datetime.now(pytz.utc),"%Y-%m-%d %H:%M:%S%t"))

0

내 마음에 더 좋은 대안은 Pendulum대신에를 사용하는 것입니다 pytz. 다음과 같은 간단한 코드를 고려하십시오.

>>> import pendulum

>>> dt = pendulum.now().to_iso8601_string()
>>> print (dt)
2018-03-27T13:59:49+03:00
>>>

Pendulum을 설치하고 해당 설명서를 보려면 여기 로 이동 하십시오 . 많은 옵션 (간단한 ISO8601, RFC3339 및 기타 여러 형식 지원)이 있으며 성능이 향상되며 더 간단한 코드를 생성하는 경향이 있습니다.


왜 투표가 여기에 실패했는지 잘 모르겠습니다.이 코드는 7/24를 실행하는 여러 프로그램에서 작동합니다 :). 나는 다른 의견을 신경 쓰지 않지만, 그것이 당신을 위해 작동하지 않는 이유를 말해 주시면 감사하겠습니다. 미리 감사드립니다
ng10

0

시간대 인식 날짜 시간에 대해 아래 표시된 시간대를 사용하십시오. 기본값은 UTC입니다.

from django.utils import timezone
today = timezone.now()

0

'howchoo'의 Tyler는 Datetime Objects에 대한 더 나은 아이디어를 얻는 데 도움이되는 훌륭한 기사를 만들었습니다. 아래 링크

Datetime으로 작업

본질적으로 방금 datetime 객체의 끝에 다음을 추가했습니다.

.replace(tzinfo=pytz.utc)

예:

import pytz
import datetime from datetime

date = datetime.now().replace(tzinfo=pytz.utc)

0

시도 pnp_datetime을 사용하고 반환 된 모든 시간은 시간대로, 그리고 어떤 오프셋 순진 오프셋 인식 문제가 발생하지 않습니다.

>>> from pnp_datetime.pnp_datetime import Pnp_Datetime
>>>
>>> Pnp_Datetime.utcnow()
datetime.datetime(2020, 6, 5, 12, 26, 18, 958779, tzinfo=<UTC>)

0

Python 3.6부터는 현지 시간 (OS 설정)을 나타내는 표준 시간대 인식 datetime 객체를 가져 오려면 표준 lib 만 필요하다는 점을 강조해야합니다. 사용 ) (astimezone를

import datetime

datetime.datetime(2010, 12, 25, 10, 59).astimezone()
# e.g.
# datetime.datetime(2010, 12, 25, 10, 59, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600), 'Mitteleuropäische Zeit'))

datetime.datetime(2010, 12, 25, 12, 59).astimezone().isoformat()
# e.g.
# '2010-12-25T12:59:00+01:00'

# I'm on CET/CEST

(@ johnchen902의 의견 참조).

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