복붙노트

[PYTHON] pytz를 사용하는 날짜 / 시간대 변환

PYTHON

pytz를 사용하는 날짜 / 시간대 변환

이것은 pytz에 대한 또 다른 게시물입니다.

두 시간대 사이에 datetime 개체를 변환하는 두 가지 함수가 있습니다. 두 번째 기능은 모든 경우에 적용됩니다. 첫 번째 기능은 (3)과 (4) 두 가지 경우에서 실패합니다. 비슷한 SO 게시물에는 이와 같은 문제가 없었습니다. localize (datetime.datetime)와 replace (tzinfo)의 차이점을 기반으로하는 설명은 큰 도움이됩니다.

>>> from dateutil.parser import parse
>>> import pytz

아래 함수는 datetime.datetime.replace (tzinfo)를 사용합니다.

def buggy_timezone_converter(input_dt, current_tz='UTC', target_tz='US/Eastern'):
    '''input_dt is a datetime.datetime object'''
    current_tz = pytz.timezone(current_tz)
    target_tz = pytz.timezone(target_tz)
    target_dt = input_dt.replace(tzinfo=current_tz).astimezone(target_tz)
    return target_tz.normalize(target_dt)

네 datetime 변환을 지금 확인하십시오.

(1) UTC에서 EST까지 - OK

>>> buggy_timezone_converter(parse('2013-02-26T04:00:00'))
Out[608]: datetime.datetime(2013, 2, 25, 23, 0, tzinfo=<DstTzInfo 'US/Eastern' EST-1 day, 19:00:00 STD>)

(2) UTC에서 EDT까지 - OK

>>> buggy_timezone_converter(parse('2013-05-26T04:00:00'))
Out[609]: datetime.datetime(2013, 5, 26, 0, 0, tzinfo=<DstTzInfo 'US/Eastern' EDT-1 day, 20:00:00 DST>)

(3) EST에서 UTC - OK가 아닙니다. 시간 간격은 4 시간 56 분입니다. 5 시간으로되어있다.

>>> buggy_timezone_converter(parse('2013-02-26T04:00:00'), target_tz='UTC', current_tz='US/Eastern')
Out[610]: datetime.datetime(2013, 2, 26, 8, 56, tzinfo=<UTC>)

(4) EDT에서 UTC - OK가 아닙니다. 시간 간격은 4 시간 56 분입니다. 그것은 4 시간이기로되어 있습니다. 일광 절약 시간은 고려하지 않습니다.

>>> buggy_timezone_converter(parse('2013-05-26T04:00:00'), current_tz='US/Eastern', target_tz='UTC')
Out[611]: datetime.datetime(2013, 5, 26, 8, 56, tzinfo=<UTC>)

아래 함수는 pytz.timezone.localize (datetime.datetime)를 사용합니다. 완벽하게 작동합니다.

def good_timezone_converter(input_dt, current_tz='UTC', target_tz='US/Eastern'):
    current_tz = pytz.timezone(current_tz)
    target_tz = pytz.timezone(target_tz)
    target_dt = current_tz.localize(input_dt).astimezone(target_tz)
    return target_tz.normalize(target_dt) 

(1) UTC에서 EST까지 - OK

>>> good_timezone_converter(parse('2013-02-26T04:00:00'))
Out[618]: datetime.datetime(2013, 2, 25, 23, 0, tzinfo=<DstTzInfo 'US/Eastern' EST-1 day, 19:00:00 STD>)

(2) UTC에서 EDT까지 - OK

>>> good_timezone_converter(parse('2013-05-26T04:00:00'))
Out[619]: datetime.datetime(2013, 5, 26, 0, 0, tzinfo=<DstTzInfo 'US/Eastern' EDT-1 day, 20:00:00 DST>)

(3) EST에서 UTC까지 - OK.

>>> good_timezone_converter(parse('2013-02-26T04:00:00'), current_tz='US/Eastern', target_tz='UTC')
Out[621]: datetime.datetime(2013, 2, 26, 9, 0, tzinfo=<UTC>)

(4) EDT에서 UTC - OK.

>>> good_timezone_converter(parse('2013-05-26T04:00:00'), current_tz='US/Eastern', target_tz='UTC')
Out[620]: datetime.datetime(2013, 5, 26, 8, 0, tzinfo=<UTC>)

해결법

  1. ==============================

    1.나는 당신이 다음과 같은 질문을 가지고 있다고 가정합니다.

    나는 당신이 다음과 같은 질문을 가지고 있다고 가정합니다.

    첫 번째 함수는 dsttzinfo_instance.localize (d) 대신 d.replace (tzinfo = dsttzinfo_instance)를 사용하므로 올바르지 않습니다.

    두 번째 함수는 모호하거나 존재하지 않는 시간 (예 : DST 전환 중)을 제외하고는 대부분 정확합니다. is_dst 매개 변수를 .localize ()에 전달하여 동작을 변경할 수 있습니다. False (기본값) / True / None 예외).

    첫 번째 함수는 모든 날짜에 대해 고정 된 utc 오프셋 (0)을 가지기 때문에 UTC 표준 시간대에서 작동합니다. America / New_York과 같은 다른 시간대는 다른 시간대 (일광 절약 시간, 전쟁 시간, 일부 지역 정치인이 좋은 생각이라고 생각할 수있는 모든 시간)에 다른 utc 오프셋을 가질 수 있습니다. 그것은 무엇이든 될 수 있습니다 - 대부분의 경우 tz 데이터베이스가 작동합니다 ). tzinfo.utcoffset (dt), tzinfo.tzname (dt), tzinfo.dst (dt) 메서드를 구현하려면 pytz는 (_tzname, _utcoffset, _dst) 특성 집합이 다른 DstTzInfo 인스턴스 컬렉션을 사용합니다. dt (날짜 / 시간) 및 is_dst가 주어지면 .localize () 메서드는 컬렉션에서 DstTzInfo 인스턴스를 적절하게 선택합니다 (항상 그런 것은 아니지만 대부분의 경우). pytz.timezone ( 'America / New_York')은 문서화되지 않은 일부 순간에 해당하는 (_tzname, _utcoffset, _dst) 속성이있는 DstTzInfo 인스턴스를 반환합니다 (다른 pytz 버전은 다른 값을 반환 할 수 있습니다. 현재 버전은 해당하는 tzinfo 인스턴스를 반환 할 수 있습니다. zoneinfo를 사용할 수있는 가장 빠른 날짜까지 -이 값은 대부분 원하지 않습니다. 기본값을 선택하는 동기는 pytz.timezone을 datetime 생성자 또는 .replace로 전달하는 것입니다 () 메소드).

    요약하면 .localize ()는 적절한 utcoffset, tzname, dst 값을 선택합니다 .replace ()는 기본 (부적합한) 값을 사용합니다. UTC에는 utcoffset, tzname, dst가 하나만 있으므로 기본값을 사용할 수 있으며 .replace () 메서드는 UTC 시간대와 함께 작동합니다. 'America / New_York'와 같은 다른 시간대에 적절한 값을 선택하려면 datetime 객체와 is_dst 매개 변수를 전달해야합니다.

    원칙적으로, pytz는 dt.tzinfo == self 인 경우에도 utcoffset (), tzname (), dst () 메서드를 구현하기 위해 localize () 메서드를 호출 할 수있었습니다. n이 number 인 시간에 O (log n) (utcoffset, tzname, dst) 값은 다르지만 datetime 생성자와 .replace ()가있는 것처럼 작동합니다. 즉, 명시 적 localize () 호출은 is_dst를 전달하는 데만 필요합니다.

  2. from https://stackoverflow.com/questions/27531718/datetime-timezone-conversion-using-pytz by cc-by-sa and MIT license