현지 시간 문자열을 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.