PEP 500 – datetime 메서드를 해당 tzinfo 구현에 위임하기 위한 프로토콜
- Author:
- Alexander Belopolsky <alexander.belopolsky at gmail.com>, Tim Peters <tim.peters at gmail.com>
- Discussions-To:
- Datetime-SIG list
- Status:
- Rejected
- Type:
- Standards Track
- Requires:
- 495
- Created:
- 08-Aug-2015
- Resolution:
- Datetime-SIG message
Table of Contents
번역·라이선스 안내
이 비공식 한국어 번역은 원문 Copyright 절의 Public Domain 조건에 따라 제공합니다. 원저자와 공식 원문은 그대로 표시합니다. 수정되지 않은 기준 원문 · 공식 최신판
초록
이 PEP는 datetime.tzinfo 인터페이스의 구체적인 구현이 aware datetime의 산술 연산, 서식화, 파싱을 재정의하는 데 사용할 수 있는 새로운 프로토콜(PDDM - “A Protocol for Delegating Datetime Methods”, datetime 메서드 위임 프로토콜)을 명세합니다. 새 프로토콜을 지원하기 위한 datetime.datetime 클래스의 변경 사항을 설명하고, aware datetime 인스턴스가 “엄격한” 산술 규칙을 따르도록 하는 데 필요한 이 프로토콜의 일부를 구현하는 새로운 추상 클래스 datetime.tzstrict를 제안합니다.
근거
Python 3.5 기준으로, tzinfo 객체를 공유하는 aware datetime 인스턴스들은 (연, 월, 일, 시, 분, 초, 마이크로초) 7-튜플과 큰 정수 사이의 단순한 전단사로부터 유도되는 산술 규칙을 따릅니다. 이 산술에서 YEAR-11-02T12:00과 YEAR-11-01T12:00의 차이는 항상 24시간입니다. 하지만 예를 들어 US/Eastern 시간대에서는 2014-11-02T02:00에 현지 시계가 한 시간 뒤로 되돌려져 2014-11-01과 2014-11-02 사이의 밤에 한 시간이 추가되었으므로, 2014-11-01T12:00과 2014-11-02T12:00 사이에는 25시간이 있습니다.
많은 비즈니스 애플리케이션은 현지 날짜에 대한 Python의 단순화된 관점을 사용해야 합니다. 제대로 된 렌터카 회사라면 DST 종료 시점에 걸친 한 주에 대해 다른 주보다 고객에게 요금을 더 청구하거나 차를 한 시간 일찍 반납하라고 요구하지 않을 것입니다. 따라서 aware datetime 산술에 대한 현재 규칙을 변경하면 하위 호환성 측면에서 악몽 같은 상황이 벌어질 뿐만 아니라, 정당하고 흔한 사용 사례에 대한 지원도 사라지게 됩니다.
현지 시간 산술에 대한 보편적인 규칙을 선택하는 것은 불가능하므로, 이러한 규칙의 구현을 datetime.tzinfo 인터페이스를 구현하는 클래스에 위임할 것을 제안합니다. 이러한 위임이 마련되면, 사용자는 tzinfo 값으로 서로 다른 클래스의 인스턴스를 고르기만 하면 서로 다른 산술 방식 중에서 선택할 수 있게 됩니다.
프로토콜
datetime의 뺄셈
PDDM을 지원하는 tzinfo 서브클래스는 __datetime_diff__라는 메서드를 정의할 수 있으며, 이 메서드는 두 개의 datetime.datetime 인스턴스를 받아 첫 번째 datetime 인스턴스가 나타내는 시각부터 다른 인스턴스가 나타내는 시각까지 경과한 시간을 나타내는 datetime.timedelta 인스턴스를 반환해야 합니다.
덧셈
PDDM을 지원하는 tzinfo 서브클래스는 __datetime_add__라는 메서드를 정의할 수 있으며, 이 메서드는 두 개의 인자(datetime 인스턴스와 timedelta 인스턴스)를 받아 datetime 인스턴스를 반환해야 합니다.
timedelta의 뺄셈
PDDM을 지원하는 tzinfo 서브클래스는 __datetime_sub__라는 메서드를 정의할 수 있으며, 이 메서드는 두 개의 인자(datetime 인스턴스와 timedelta 인스턴스)를 받아 datetime 인스턴스를 반환해야 합니다.
서식화
PDDM을 지원하는 tzinfo 서브클래스는 __datetime_isoformat__ 및 __datetime_strftime__이라는 메서드를 정의할 수 있습니다.
__datetime_isoformat__ 메서드는 datetime 인스턴스와 선택적인 구분자를 받아, 주어진 datetime 인스턴스의 문자열 표현을 생성해야 합니다.
__datetime_strftime__ 메서드는 datetime 인스턴스와 형식 문자열을 받아, 주어진 datetime 인스턴스를 주어진 형식에 따라 서식화한 문자열 표현을 만들어 내야 합니다.
파싱
PDDM을 지원하는 tzinfo 서브클래스는 __datetime_strptime__이라는 클래스 메서드를 정의하고, 자신이 구현하는 시간대의 “정식” 이름을 레지스트리에 등록할 수 있습니다. TODO 레지스트리에 대한 설명을 추가해야 합니다.
datetime 메서드의 변경 사항
뺄셈
class datetime:
def __sub__(self, other):
if isinstance(other, datetime):
try:
self_diff = self.tzinfo.__datetime_diff__
except AttributeError:
self_diff = None
try:
other_diff = self.tzinfo.__datetime_diff__
except AttributeError:
other_diff = None
if self_diff is not None:
if self_diff is not other_diff and self_diff.__func__ is not other_diff.__func__:
raise ValueError("Cannot find difference of two datetimes with "
"different tzinfo.__datetime_diff__ implementations.")
return self_diff(self, other)
elif isinstance(other, timedelta):
try:
sub = self.tzinfo.__datetime_sub__
except AttributeError:
pass
else:
return sub(self, other)
return self + -other
else:
return NotImplemented
# current implementation
덧셈
datetime 인스턴스에 timedelta를 더하는 연산은 self.tzinfo.__datetime_add__ 메서드가 정의되어 있으면 언제나 해당 메서드에 위임됩니다.
엄격한 산술
datetime.tzinfo 클래스의 새로운 추상 서브클래스인 datetime.tzstrict가 datetime 모듈에 추가됩니다. 이 서브클래스는 utcoffset(), tzname(), dst() 메서드는 구현하지 않지만, PDDM의 메서드 중 일부는 구현합니다.
tzstrict가 구현하는 PDDM 메서드는 다음과 동등합니다:
class tzstrict(tzinfo):
def __datetime_diff__(self, dt1, dt2):
utc_dt1 = dt1.astimezone(timezone.utc)
utc_dt2 = dt2.astimezone(timezone.utc)
return utc_dt2 - utc_dt1
def __datetime_add__(self, dt, delta):
utc_dt = dt.astimezone(timezone.utc)
return (utc_dt + delta).astimezone(self)
def __datetime_sub__(self, dt, delta):
utc_dt = dt.astimezone(timezone.utc)
return (utc_dt - delta).astimezone(self)
파싱과 포매팅
datetime 메서드 strftime과 isoformat은 자신의 tzinfo 멤버에 같은 이름의 메서드가 정의되어 있으면 언제나 그 메서드에 처리를 위임합니다.
datetime.strptime 메서드에 %Z 지시자가 포함된 형식 문자열이 주어지면, 이 메서드는 주어진 시간대 이름으로 레지스트리에서 tzinfo 구현을 찾아 그 구현의 __datetime_strptime__ 메서드를 호출합니다.
응용
이 PEP를 통해 서드파티가 다음을 비롯한 다양한 시간 기록 체계를 구현할 수 있게 됩니다:
- 율리우스력 / Microsoft Excel 달력.
- 윤초를 지원하는 “Right” 시간대.
- 프랑스 혁명력(상당한 작업이 필요함).
Copyright
This document has been placed in the public domain.