[python] UTC 날짜 / 시간 문자열을 현지 날짜 / 시간으로 변환

UTC와의 시간을 변환 할 필요가 없었습니다. 최근에 내 앱을 표준 시간대로 인식하라는 요청을 받았으며 서클에서 나 자신을 실행하고 있습니다. 현지 시간을 UTC로 변환하는 데 대한 많은 정보가 있습니다. 이것은 상당히 초등 한 것으로 나타났습니다 (아마도 잘못하고 있습니다) .UTC 시간을 최종 사용자 시간대로 쉽게 변환하는 방법에 대한 정보를 찾을 수 없습니다.

간단히 말해서 안드로이드 앱은 나에게 (appengine 앱) 데이터를 보내며 그 데이터 내에서 타임 스탬프입니다. 해당 타임 스탬프를 utc 시간으로 저장하려면 다음을 사용하십시오.

datetime.utcfromtimestamp(timestamp)

작동하는 것 같습니다. 내 앱이 데이터를 저장하면 5 시간 앞서 저장됩니다 (EST -5입니다)

데이터는 appengine의 BigTable에 저장되고 검색되면 다음과 같은 문자열로 나타납니다.

"2011-01-21 02:37:21"

사용자가 올바른 시간대에서이 문자열을 DateTime으로 어떻게 변환합니까?

또한 사용자 시간대 정보에 권장되는 스토리지는 무엇입니까? (일반적으로 tz 정보 (예 : “-5 : 00″또는 “EST”등)를 저장하는 방법은 무엇입니까?) 첫 번째 질문에 대한 답변에 두 번째 질문에 대한 매개 변수가 포함되어있을 것입니다.



답변

자신의 tzinfo객체 를 제공하지 않으려면 python-dateutil 라이브러리를 확인하십시오 . 다소 정식 이름으로 시간대 규칙을 참조 할 수 tzinfo있도록 zoneinfo (Olson) 데이터베이스 위에 구현을 제공합니다 .

from datetime import datetime
from dateutil import tz

# METHOD 1: Hardcode zones:
from_zone = tz.gettz('UTC')
to_zone = tz.gettz('America/New_York')

# METHOD 2: Auto-detect zones:
from_zone = tz.tzutc()
to_zone = tz.tzlocal()

# utc = datetime.utcnow()
utc = datetime.strptime('2011-01-21 02:37:21', '%Y-%m-%d %H:%M:%S')

# Tell the datetime object that it's in UTC time zone since 
# datetime objects are 'naive' by default
utc = utc.replace(tzinfo=from_zone)

# Convert time zone
central = utc.astimezone(to_zone)

strptime사용법 을 보여주기 위해 확장 된 예제 편집

더 나은 진입 점 방법을 표시하기 위해 2 개의 고정 API 사용량 편집

시간대에 대한 3 가지 자동 감지 방법 편집 (야린)


답변

외부 라이브러리에 의존하지 않는 탄력적 인 방법은 다음과 같습니다.

from datetime import datetime
import time

def datetime_from_utc_to_local(utc_datetime):
    now_timestamp = time.time()
    offset = datetime.fromtimestamp(now_timestamp) - datetime.utcfromtimestamp(now_timestamp)
    return utc_datetime + offset

이것은 DelboyJay의 예제에서 타이밍 문제를 피합니다. 그리고 Erik van Oosten의 개정에서 더 적은 타이밍 문제.

흥미로운 각주로서 위에서 계산 된 표준 시간대 오프셋은 일광 절약 규칙 변경으로 인해 다음과 같은 겉보기에 해당되는 표현과 다를 수 있습니다.

offset = datetime.fromtimestamp(0) - datetime.utcfromtimestamp(0) # NO!

업데이트 : 이 스 니펫은 현재 시간의 UTC 오프셋을 사용하는 취약점이 있으며 입력 날짜 시간의 UTC 오프셋과 다를 수 있습니다. 다른 솔루션에 대해서는이 답변에 대한 의견을 참조하십시오.

다른 시간을 돌아 다니려면 지나간 시간부터 신기원 시간을 잡으십시오. 다음은 내가하는 일입니다.

def utc2local (utc):
    epoch = time.mktime(utc.timetuple())
    offset = datetime.fromtimestamp (epoch) - datetime.utcfromtimestamp (epoch)
    return utc + offset


답변

tzinfo 객체 에 대한 날짜 및 시간 설명서를 참조하십시오 . 자신을 지원하려는 시간대를 구현해야합니다. 문서 하단에있는 예입니다.

다음은 간단한 예입니다.

from datetime import datetime,tzinfo,timedelta

class Zone(tzinfo):
    def __init__(self,offset,isdst,name):
        self.offset = offset
        self.isdst = isdst
        self.name = name
    def utcoffset(self, dt):
        return timedelta(hours=self.offset) + self.dst(dt)
    def dst(self, dt):
            return timedelta(hours=1) if self.isdst else timedelta(0)
    def tzname(self,dt):
         return self.name

GMT = Zone(0,False,'GMT')
EST = Zone(-5,False,'EST')

print datetime.utcnow().strftime('%m/%d/%Y %H:%M:%S %Z')
print datetime.now(GMT).strftime('%m/%d/%Y %H:%M:%S %Z')
print datetime.now(EST).strftime('%m/%d/%Y %H:%M:%S %Z')

t = datetime.strptime('2011-01-21 02:37:21','%Y-%m-%d %H:%M:%S')
t = t.replace(tzinfo=GMT)
print t
print t.astimezone(EST)

산출

01/22/2011 21:52:09
01/22/2011 21:52:09 GMT
01/22/2011 16:52:09 EST
2011-01-21 02:37:21+00:00
2011-01-20 21:37:21-05:00a


답변

모호한 현지 시간에 해당하는 시간 (예 : DST 전환 중) 및 / 또는 현지 utc 오프셋이 현지 시간대의 시간에 따라 다른 경우에도 정확한 결과를 얻으려면 시간대를 사용하십시오 pytz.

#!/usr/bin/env python
from datetime import datetime
import pytz    # $ pip install pytz
import tzlocal # $ pip install tzlocal

local_timezone = tzlocal.get_localzone() # get pytz tzinfo
utc_time = datetime.strptime("2011-01-21 02:37:21", "%Y-%m-%d %H:%M:%S")
local_time = utc_time.replace(tzinfo=pytz.utc).astimezone(local_timezone)


답변

이 답변은 이외의 다른 모듈을 사용하지 않으려는 경우 유용합니다 datetime.

datetime.utcfromtimestamp(timestamp)순진한 datetime객체 (인식 대상 아님)를 반환합니다 . 인식하는 것은 시간대를 인식하고 순진하지 않습니다. 시간대 간 (예 : UTC와 현지 시간 간) 변환하려는 경우 알고 있어야합니다.

시작 날짜를 인스턴스화하는 사람이 아니지만 datetimeUTC 시간 으로 순진한 객체를 만들 수있는 경우이 Python 3.x 코드를 사용하여 변환하려고 할 수 있습니다.

import datetime

d=datetime.datetime.strptime("2011-01-21 02:37:21", "%Y-%m-%d %H:%M:%S") #Get your naive datetime object
d=d.replace(tzinfo=datetime.timezone.utc) #Convert it to an aware datetime object in UTC time.
d=d.astimezone() #Convert it to your local timezone (still aware)
print(d.strftime("%d %b %Y (%I:%M:%S:%f %p) %Z")) #Print it with a directive of choice

표준 시간대가 현재 MDT 인 경우 일광 절약 시간이 MST를 인쇄하므로 위의 코드에서 작동하지 않는다고 잘못 생각하지 않도록주의하십시오. 월을 8 월로 변경하면 MDT가 인쇄됩니다.

datetime파이썬 3.x에서도 인식 객체 를 얻는 또 다른 쉬운 방법 은 시작하도록 지정된 시간대로 객체를 만드는 것입니다. UTC를 사용한 예는 다음과 같습니다.

import datetime, sys

aware_utc_dt_obj=datetime.datetime.now(datetime.timezone.utc) #create an aware datetime object
dt_obj_local=aware_utc_dt_obj.astimezone() #convert it to local time

#The following section is just code for a directive I made that I liked.
if sys.platform=="win32":
    directive="%#d %b %Y (%#I:%M:%S:%f %p) %Z"
else:
    directive="%-d %b %Y (%-I:%M:%S:%f %p) %Z"

print(dt_obj_local.strftime(directive))

Python 2.x를 사용하는 경우 Python 2.x 에는 존재하지 않으므로 datetime.tzinfo인식 datetime객체 를 작성하는 데 도움 이되도록 서브 클래스 를 작성하고 사용해야합니다 datetime.timezone.


답변

Django를 사용하는 경우 다음 timezone.localtime방법을 사용할 수 있습니다 .

from django.utils import timezone
date
# datetime.datetime(2014, 8, 1, 20, 15, 0, 513000, tzinfo=<UTC>)

timezone.localtime(date)
# datetime.datetime(2014, 8, 1, 16, 15, 0, 513000, tzinfo=<DstTzInfo 'America/New_York' EDT-1 day, 20:00:00 DST>)


답변

화살표 를 사용할 수 있습니다

from datetime import datetime
import arrow

now = datetime.utcnow()

print(arrow.get(now).to('local').format())
# '2018-04-04 15:59:24+02:00'

arrow.get()무엇이든 먹일 수 있습니다 . 타임 스탬프, iso 문자열 등