현지 시간 문자열을 UTC로 변환하는 방법?


307

현지 시간 의 날짜 시간 문자열을 UTC 시간 의 문자열 로 어떻게 변환 합니까?

나는 내가 전에 이것을 한 것이 확실하지만 그것을 찾을 수 없으며 그렇게하면 나 (그리고 다른 사람들)가 미래에 그렇게하도록 희망적으로 도울 것입니다.

설명 : 예를 들어 2008-09-17 14:02:00현지 시간대 ( +10)에있는 경우 동등한 UTC시간 으로 문자열을 생성하고 싶습니다 2008-09-17 04:02:00.

또한 http://lucumr.pocoo.org/2011/7/15/eppur-si-muove/ 에서 일반적으로 DST 및 기타 문제와 같이 현지 시간에서 고유 한 전환이 불가능하므로 불가능합니다. UTC 시간.


1
mktime () 메소드는 "현지 시간"을 입력으로 사용합니다. 이것은 예상 한 것과 다를 수 있으므로 사용하고 모든 것을 망쳤습니다. 에 눈을하시기 바랍니다 이 링크
— 하이 펭 장에게

답변:


287

먼저 문자열을 순진한 datetime 객체로 구문 분석합니다. datetime.datetime시간대 정보가 첨부되지 않은 인스턴스입니다 . datetime.strptime날짜 문자열 구문 분석 에 대한 정보는 문서를 참조하십시오 .

pytz표준 시간대 + UTC와 함께 제공 되는 모듈을 사용하십시오 . 현지 시간대가 무엇인지 파악하고 그로부터 시간대 개체를 구성한 후 순진한 날짜 / 시간을 조작 및 첨부합니다.

마지막으로, datetime.astimezone()메소드를 사용 하여 날짜 시간을 UTC로 변환하십시오.

"2001-2-3 10:11:12"문자열에 대해 현지 시간대 "America / Los_Angeles"를 사용하는 소스 코드 :

import pytz, datetime
local = pytz.timezone ("America/Los_Angeles")
naive = datetime.datetime.strptime ("2001-2-3 10:11:12", "%Y-%m-%d %H:%M:%S")
local_dt = local.localize(naive, is_dst=None)
utc_dt = local_dt.astimezone(pytz.utc)

여기에서 필요에 따라 strftime()메소드를 사용하여 UTC 날짜 시간을 형식화 할 수 있습니다 .

utc_dt.strftime ("%Y-%m-%d %H:%M:%S")

7
편집 다음 코드로 답하십시오 : [코드] local.localize (순진) [/ 코드] 문서를 참조하십시오 : 링크 불행하게도 표준 날짜 생성자 '많은 시간대에 대한 pytz와' '일을하지 않는다'의 인수 tzinfo를 사용하여. >>> 날짜 (2002, 10, 27, 12, 0, 0, tzinfo = 암스테르담)는 .strftime (FMT) '0020 2002년 10월 27일 12시 0분 0초 AMT +'
— 샘 Stoelinga

2
분명히 "현지 시간대가 무엇인지 파악하는"단계는 소리보다 어려워 보입니다 (실제로는 불가능합니다).
— Jason R. Coombs

2
@SamStoelinga가 제안한 local.localize를 사용하십시오. 그렇지 않으면 일광 절약 시간을 고려하지 않습니다.
— 에밀 Stenström

이 답변은 저에게 매우 도움이되었지만, 내가 겪었던 함정을 지적하고 싶습니다. 시간은 제공하지만 날짜는 제공하지 않으면 예기치 않은 결과가 발생할 수 있습니다. 따라서 전체 타임 스탬프를 제공해야합니다.
— Steven Mercatante


144

datetime 모듈의 utcnow () 함수를 사용하여 현재 UTC 시간을 얻을 수 있습니다.

>>> import datetime
>>> utc_datetime = datetime.datetime.utcnow()
>>> utc_datetime.strftime("%Y-%m-%d %H:%M:%S")
'2010-02-01 06:59:19'

Tom이 위에서 언급 한 링크 : http://lucumr.pocoo.org/2011/7/15/eppur-si-muove/ 는 말합니다 :

UTC는 일광 절약 시간 제가없는 시간대이며 여전히 구성 변경이없는 시간대입니다.

항상 UTC로 시간을 측정하고 저장하십시오 .

시간이 걸린 곳을 기록해야 할 경우 별도로 보관하십시오. 현지 시간 + 시간대 정보를 저장 하지 마십시오 !

참고 -데이터가 DST를 사용하는 지역에있는 경우 pytzJohn Millikin의 답변을 사용하십시오.

주어진 문자열에서 UTC 시간을 얻고 DST를 사용하지 않는 세계의 지역에있을만큼 운이 좋거나 DST를 적용하지 않고 UTC에서만 오프셋 된 데이터가있는 경우 :

-> 오프셋 시간의 기준으로 현지 시간 사용 :

>>> # Obtain the UTC Offset for the current system:
>>> UTC_OFFSET_TIMEDELTA = datetime.datetime.utcnow() - datetime.datetime.now()
>>> local_datetime = datetime.datetime.strptime("2008-09-17 14:04:00", "%Y-%m-%d %H:%M:%S")
>>> result_utc_datetime = local_datetime + UTC_OFFSET_TIMEDELTA
>>> result_utc_datetime.strftime("%Y-%m-%d %H:%M:%S")
'2008-09-17 04:04:00'

-> 또는 datetime.timedelta ()를 사용하여 알려진 오프셋에서

>>> UTC_OFFSET = 10
>>> result_utc_datetime = local_datetime - datetime.timedelta(hours=UTC_OFFSET)
>>> result_utc_datetime.strftime("%Y-%m-%d %H:%M:%S")
'2008-09-17 04:04:00'

최신 정보:

파이썬 3.2부터 datetime.timezone사용 가능합니다. 아래 명령을 사용하여 시간대 인식 날짜 시간 객체를 생성 할 수 있습니다.

import datetime

timezone_aware_dt = datetime.datetime.now(datetime.timezone.utc)

시간대 변환을 할 준비가 되었다면 다음을 읽으십시오.

https://medium.com/@eleroy/10-things-you-need-to-know-about-date-and-time-in-python-with-datetime-pytz-dateutil-timedelta-309bfbafb3f7


14
현재 시간 만 변환하므로 주어진 시간 (문자열)을 가져 와서 UTC로 변환해야합니다.
— Tom

표준 오프셋 값을 사용하는 경우 여기서 중요하지 않다고 생각합니다. local_time = utc_time + utc_offset 및 utc_time = local_time-utc_offset.
— monkut

5
과거 및 미래 타임 스탬프는 DST로 인해 UTC 오프셋이 다를 수 있으므로 현재 시간에서만 작동합니다.
— Alex B

좋은 지적은 ... DST를 다루어야한다면 John Millikin이 언급 한 것처럼 pytz를 사용해야 할 것입니다.
— monkut

1
utcnow ()와 now () 호출 사이에는 산발적 인 델타가 있습니다. 나중에 위험한 오류가 발생할 수있는 위험한 코드 줄입니다 tzinfo.utcoffset() must return a whole number of minutes.
— Pavel Vlasov

62

@rofly 덕분에 문자열에서 문자열로의 전체 변환은 다음과 같습니다.

time.strftime("%Y-%m-%d %H:%M:%S", 
              time.gmtime(time.mktime(time.strptime("2008-09-17 14:04:00", 
                                                    "%Y-%m-%d %H:%M:%S"))))

time/ calendar함수 에 대한 요약 :

time.strptime
string-> 튜플 (시간대가 적용되지 않으므로 문자열과 일치)

time.mktime
현지 시간 튜플-에포크 이후 초 (항상 현지 시간)

time.gmtime
epoch 이후의 초-> UTC

과

calendar.timegm
에포크 이후 UTC-> 초의 튜플

time.localtime
시대 이후 초-> 현지 시간대의 튜플


4
(always local time)mktime ()의 입력은 현지 시간이고, 1970-01-01 00:00:00 +0000 (UTC)시간대에 의존하지 않는 epoch ( ) 이후의 출력은 초 입니다.
— jfs

3
또한 DST 전환 중에 실패 할 확률이 50 %입니다. 현지 시간
— jfs

38

일반적인 파이썬 시간 변환에 대한 요약은 다음과 같습니다.

일부 방법은 몇 초 만에 삭제되며 (s) 로 표시됩니다 . ts = (d - epoch) / unit대신 jfs 덕분에 명시 적 수식을 사용할 수 있습니다.

  • struct_time (UTC) → POSIX (s) :
    calendar.timegm(struct_time)
  • 나이브 날짜 시간 (로컬) → POSIX (s) :
    calendar.timegm(stz.localize(dt, is_dst=None).utctimetuple())
    (DST 전환 중 예외, jfs의 설명 참조)
  • 나이브 날짜 시간 (UTC) → POSIX (s) :
    calendar.timegm(dt.utctimetuple())
  • 인식 날짜 시간 → POSIX (s) :
    calendar.timegm(dt.utctimetuple())
  • POSIX → struct_time (UTC, s ) :
    time.gmtime(t)
    (jfs의 주석 참조)
  • 나이브 날짜 시간 (로컬) → struct_time (UTC, s ) :
    stz.localize(dt, is_dst=None).utctimetuple()
    (DST 전환 중 예외, jfs의 설명 참조)
  • 나이브 날짜 시간 (UTC) → struct_time (UTC, s ) :
    dt.utctimetuple()
  • 인식 날짜 시간 → struct_time (UTC, s ) :
    dt.utctimetuple()
  • POSIX → Naïve 날짜 시간 (현지) :
    datetime.fromtimestamp(t, None)
    (특정 조건에서 실패 할 수 있습니다 . 아래 jfs의 주석 참조)
  • struct_time (UTC) → Naive 날짜 시간 (local, s ) :
    datetime.datetime(struct_time[:6], tzinfo=UTC).astimezone(tz).replace(tzinfo=None)
    (윤초를 나타낼 수 없음, jfs의 설명 참조)
  • 나이브 날짜 시간 (UTC) → 나이브 날짜 시간 (현지) :
    dt.replace(tzinfo=UTC).astimezone(tz).replace(tzinfo=None)
  • 날짜 시간 인식 → 나이브 날짜 시간 (현지) :
    dt.astimezone(tz).replace(tzinfo=None)
  • POSIX → 나이브 날짜 시간 (UTC) :
    datetime.utcfromtimestamp(t)
  • struct_time (UTC) → 나이브 날짜 시간 (UTC, s ) :
    datetime.datetime(*struct_time[:6])
    (윤초를 나타낼 수 없음, jfs의 설명 참조)
  • 나이브 날짜 시간 (로컬) → 나이브 날짜 시간 (UTC) :
    stz.localize(dt, is_dst=None).astimezone(UTC).replace(tzinfo=None)
    (DST 전환 중 예외, jfs의 설명 참조)
  • 날짜 시간 인식 → 나이브 날짜 시간 (UTC) :
    dt.astimezone(UTC).replace(tzinfo=None)
  • POSIX → 인식 날짜 시간 :
    datetime.fromtimestamp(t, tz)
    (pytz가 아닌 시간대의 경우 실패 할 수 있음)
  • struct_time (UTC) → Aware datetime (s) :
    datetime.datetime(struct_time[:6], tzinfo=UTC).astimezone(tz)
    (윤초를 나타낼 수 없음, jfs의 주석 참조)
  • 나이브 날짜 시간 (로컬) → 인식 날짜 시간 :
    stz.localize(dt, is_dst=None)
    (DST 전환 중 예외, jfs의 설명 참조)
  • 나이브 날짜 시간 (UTC) → 인식 날짜 시간 :
    dt.replace(tzinfo=UTC)

출처 : taaviburns.ca


1
(1) fromtimestamp(t, None)로컬 시간대가 다른 utc 오프셋을 가지고 t 있고 C 라이브러리가 주어진 플랫폼의 tz 데이터베이스에 액세스 할 수없는 경우 실패 할 수 있습니다. tzlocal.get_localzone()tzdata를 이식 가능한 방식으로 제공하는 데 사용할 수 있습니다 . (2) fromtimestamp(t, tz)피츠 시간대가 아닌 경우 실패 할 수 있습니다. (3) datetime(*struct_time[:6])당신은 실종* . (4)는 timegm(), utctimetuple(), struct_time기반 솔루션 초의 분수 놓는다. ts = (d - epoch) / unit대신 다음과 같은 명시 적 수식을 사용할 수 있습니다 .
— jfs

1
(5) stz.localize(dt, is_dst=None)예를 들어 DST 전환 중에 모호하거나 존재하지 않는 현지 시간에 대한 예외를 제기합니다. 예외를 피하려면 stz.normalize(stz.localize(dt))부정확 한 결과를 반환 할 수 있습니다. (6) datetime ()은 윤초를 나타낼 수 없습니다. 해결 방법으로 먼저 "에포크 이후 초"로 변환하십시오 struct_time. (7) time.gmtime(t)달리 calendar.timegm()"올바른"시간대를 사용하면 POSIX 이외의 입력을 예상 할 수 있습니다. 입력이 POSIX 인 경우 명시 적 공식을 사용하십시오.gmtime = lambda t: datetime(1970,1,1, tzinfo=utc) + timedelta(seconds=t)
— jfs

나는 이것이 읽기 쉬운 테이블에 있었으면 좋겠다 (링크에있다)
— MichaelChirico

1
@MichaelChirico의 답변 은 " <table>태그를 허용하지 않습니다 (불가능합니다) . 죄송합니다. 의도적이며 의도적으로 설계된 것입니다. 빠르고 더러운"테이블 "이 필요하면 <pre>ASCII 레이아웃을 사용하십시오." ASCII 테이블이 위의 목록보다 더 읽기 쉽다고 생각하지 않습니다.
— akaihola

불행히도 어쨌든 내 공감대를 가지고 있습니다 ... 어쩌면 대답 내 링크의 표를 참조하십시오?
— MichaelChirico

25
def local_to_utc(t):
    secs = time.mktime(t)
    return time.gmtime(secs)

def utc_to_local(t):
    secs = calendar.timegm(t)
    return time.localtime(secs)

출처 : http://feihonghsu.blogspot.com/2008/02/converting-from-local-time-to-utc.html

bd808의 사용 예 : 소스가 datetime.datetime객체 t인 경우 다음 과 같이 호출하십시오.

local_to_utc(t.timetuple())

5
소스가 datetime.datetime 객체 t인 경우 다음 과 같이 호출하십시오. local_to_utc (t.timetuple ())
— bd808

2
.timetuple()세트를 호출 tm_isdst합니다 -1; mktime()DST 전환 중에 50 %의 확률로 실패합니다.
— jfs

1
척의 솔루션은 밀리 초 정보를 잃습니다.
— Luca

21

dateutil을 사용 하여 행운을 빕니다 (다른 관련 질문은 SO에 널리 권장됩니다).

from datetime import *
from dateutil import *
from dateutil.tz import *

# METHOD 1: Hardcode zones:
utc_zone = tz.gettz('UTC')
local_zone = tz.gettz('America/Chicago')
# METHOD 2: Auto-detect zones:
utc_zone = tz.tzutc()
local_zone = tz.tzlocal()

# Convert time string to datetime
local_time = datetime.strptime("2008-09-17 14:02:00", '%Y-%m-%d %H:%M:%S')

# Tell the datetime object that it's in local time zone since 
# datetime objects are 'naive' by default
local_time = local_time.replace(tzinfo=local_zone)
# Convert time to UTC
utc_time = local_time.astimezone(utc_zone)
# Generate UTC time string
utc_string = utc_time.strftime('%Y-%m-%d %H:%M:%S')

(코드는이 답변에서 UTC 날짜 시간 문자열을 로컬 날짜 시간 으로 변환 하기 위해 파생되었습니다 )


dateutil구현에서 히스토리 시간대 데이터베이스 (특히 Windows)를 사용하지 않는 시스템에서 로컬 시간대가 다른 UTC 오프셋 (DST 전환과 관련이 없음)을 가진 경우 지난 날짜에 ​​실패 할 수 있습니다. 대신 pytz+를 tzlocal사용할 수 있습니다.
— jfs

@ JFSebastian- 그 소식을 듣지 못했습니다. 자세한 정보는 어디서 얻을 수 있습니까?
— Yarin

Windows 시스템을 사용하여 과거에 유럽 / 모스크바와 같이 utc 오프셋이 다른 시간대를 설정하십시오. pytz와 결과를 비교하십시오 . 또한 이 경우 올바른 API 사용에 대해 확실하지 않지만 우분투에서도 실패하는이 버그를 테스트 할 수 있습니다.
— jfs

출력은 무엇입니까? 출력을 게시하십시오.
— not2qubit

18

pytz의 또 다른 예이지만 localize ()가 포함되어있어 하루를 절약했습니다.

import pytz, datetime
utc = pytz.utc
fmt = '%Y-%m-%d %H:%M:%S'
amsterdam = pytz.timezone('Europe/Amsterdam')

dt = datetime.datetime.strptime("2012-04-06 10:00:00", fmt)
am_dt = amsterdam.localize(dt)
print am_dt.astimezone(utc).strftime(fmt)
'2012-04-06 08:00:00'


7
import time

import datetime

def Local2UTC(LocalTime):

    EpochSecond = time.mktime(LocalTime.timetuple())
    utcTime = datetime.datetime.utcfromtimestamp(EpochSecond)

    return utcTime

>>> LocalTime = datetime.datetime.now()

>>> UTCTime = Local2UTC(LocalTime)

>>> LocalTime.ctime()

'Thu Feb  3 22:33:46 2011'

>>> UTCTime.ctime()

'Fri Feb  4 05:33:46 2011'

mktime(dt.timetuple())DST 전환 중에 실패 할 수 있습니다 . 이 LocalTimezone워드 프로세서 (이것은 가장 최근의 시간대 정의에 대한 작동하지만 DST에 (과거 날짜에 대해 무관을 실패 할 수 있습니다))에
— JFS

5

datetime.datetime을 선호하는 경우 :

dt = datetime.strptime("2008-09-17 14:04:00","%Y-%m-%d %H:%M:%S")
utc_struct_time = time.gmtime(time.mktime(dt.timetuple()))
utc_dt = datetime.fromtimestamp(time.mktime(utc_struct_time))
print dt.strftime("%Y-%m-%d %H:%M:%S")

1
물론, 왜 당신이 그것을 선호하는지 알 수 없습니다. 내 버전보다 추가 가져 오기와 3 개의 함수 호출이 더 필요합니다.
— Tom

% Z 및 % z는 여전히 공백을 인쇄합니다.
— Pavel Vlasov

2
잘못되었습니다. 현지 시간대가 UTC가 아닌 경우 실패합니다. mktime()입력으로 현지 시간을 예상합니다. fromtimestamp()utc가 아닌 현지 시간을 반환합니다. 문제를 해결하면 다음 과 같은 추가 문제가 나타납니다 (예 dateutil: stdlib 전용 솔루션이 실패 할 수 있음)
— jfs

5

단순한

나는 이렇게했다 :

>>> utc_delta = datetime.utcnow()-datetime.now()
>>> utc_time = datetime(2008, 9, 17, 14, 2, 0) + utc_delta
>>> print(utc_time)
2008-09-17 19:01:59.999996

멋진 구현

화려하고 싶다면 이것을 functor로 바꿀 수 있습니다.

class to_utc():
    utc_delta = datetime.utcnow() - datetime.now()

    def __call__(cls, t):
        return t + cls.utc_delta

결과:

>>> utc_converter = to_utc()
>>> print(utc_converter(datetime(2008, 9, 17, 14, 2, 0)))
2008-09-17 19:01:59.999996

5
일광 절약 시간 제로는 작동하지 않습니다. 예를 들어 현재 여름이고 전환 날짜가 겨울 인 경우. 질문은 문자열로 저장된 날짜를 변환하는 것에 관한 것이 었습니다.
— Tom

1
참고로 이 방법의 가장 큰 문제 (일광 절약 외에)는 델타가 꺼지는 몇 밀리 초입니다. 내 캘린더 초대가 모두 1 분 정도 꺼짐으로 표시됩니다.
— Nostalg.io

4

당신은 그것을 할 수 있습니다 :

>>> from time import strftime, gmtime, localtime
>>> strftime('%H:%M:%S', gmtime()) #UTC time
>>> strftime('%H:%M:%S', localtime()) # localtime

3

어때요-

time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(seconds))

초이면 None로컬 시간을 UTC 시간으로 변환하고 그렇지 않으면 전달 된 시간을 UTC로 변환합니다.


2

일광 절약 시간제 등을 이용하는 경우

위의 답변 중 어느 것도 특히 도움이되지 않았습니다. 아래 코드는 GMT에서 작동합니다.

def get_utc_from_local(date_time, local_tz=None):
    assert date_time.__class__.__name__ == 'datetime'
    if local_tz is None:
        local_tz = pytz.timezone(settings.TIME_ZONE) # Django eg, "Europe/London"
    local_time = local_tz.normalize(local_tz.localize(date_time))
    return local_time.astimezone(pytz.utc)

import pytz
from datetime import datetime

summer_11_am = datetime(2011, 7, 1, 11)
get_utc_from_local(summer_11_am)
>>>datetime.datetime(2011, 7, 1, 10, 0, tzinfo=<UTC>)

winter_11_am = datetime(2011, 11, 11, 11)
get_utc_from_local(winter_11_am)
>>>datetime.datetime(2011, 11, 11, 11, 0, tzinfo=<UTC>)

2

http://crsmithdev.com/arrow/ 사용

arrowObj = arrow.Arrow.strptime('2017-02-20 10:00:00', '%Y-%m-%d %H:%M:%S' , 'US/Eastern')

arrowObj.to('UTC') or arrowObj.to('local') 

이 라이브러리는 인생을 쉽게 만듭니다 :)


화살표는 최고입니다 : arrow.get (datetime.now (), 'local'). to ( 'utc'). naive
— SteveJ

1

나는 또 다른 질문에 대한 최선의 답을 찾을 여기를 . 파이썬 내장 라이브러리 만 사용하고 현지 시간대를 입력 할 필요가 없습니다 (필자의 경우 요구 사항)

import time
import calendar

local_time = time.strptime("2018-12-13T09:32:00.000", "%Y-%m-%dT%H:%M:%S.%f")
local_seconds = time.mktime(local_time)
utc_time = time.gmtime(local_seconds)

이 질문은 검색 키워드에 따라 연결된 질문 대신 Google에 표시되므로 답변을 다시 게시하고 있습니다.


1

내 프로젝트 중 하나에이 코드가 있습니다.

from datetime import datetime
## datetime.timezone works in newer versions of python
try:
    from datetime import timezone
    utc_tz = timezone.utc
except:
    import pytz
    utc_tz = pytz.utc

def _to_utc_date_string(ts):
    # type (Union[date,datetime]]) -> str
    """coerce datetimes to UTC (assume localtime if nothing is given)"""
    if (isinstance(ts, datetime)):
        try:
            ## in python 3.6 and higher, ts.astimezone() will assume a
            ## naive timestamp is localtime (and so do we)
            ts = ts.astimezone(utc_tz)
        except:
            ## in python 2.7 and 3.5, ts.astimezone() will fail on
            ## naive timestamps, but we'd like to assume they are
            ## localtime
            import tzlocal
            ts = tzlocal.get_localzone().localize(ts).astimezone(utc_tz)
    return ts.strftime("%Y%m%dT%H%M%SZ")

0

python3에서 :

pip install python-dateutil

from dateutil.parser import tz

mydt.astimezone(tz.gettz('UTC')).replace(tzinfo=None) 

이것은 작동하지 않는 것 같습니다. ValueError 예외가 발생합니다. ValueError : astimezone ()은 순진한 날짜 시간에 적용 할 수 없습니다
— Stormsson

그것은해야한다 : from dateutil import tz
— 하비에르

-3

어때요-

time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(seconds))

초이면 None로컬 시간을 UTC 시간으로 변환하고 그렇지 않으면 전달 된 시간을 UTC로 변환합니다.


1
이것은 도움이되지 않습니다. 질문은 주어진 현지 시간 문자열을 utc 문자열로 변환하는 것이 었습니다.
— Tom
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.