파이썬에서 부분 날짜를 어떻게 모델링합니까? 알 수없는 해 또는 달의 알 수없는 날처럼?


11

내가 좋아하는 사실을 캡처 할 수 싶어 Bob was born in 2000하고 Bill's birthday is May 7th.

두 예에서 우리는 그 사람의 생년월일 중 일부만을 알고 있습니다. 어떤 경우에는 연도 만 알고 있습니다. 다른 경우에는 월과 일을 알고 있지만 연도는 알 수 없습니다.

이 정보를 어떻게 캡처합니까?

이것이 어떻게 작동하는지 몇 가지 예 :

필드에 없음이 알 수없는 날짜를 허용 한 datetime과 같은 라이브러리를 상상해보십시오. 다음과 같은 코드가있을 수 있습니다.

date_a = date(2000, 5, None)
date_b = date(2000, 6, None)
difference = date_b - date_a
assert difference.min.days == 1
assert difference.max.days == 60  # Or something close to 60.
assert equal(date_a, date_b) == False

date_c = date(2000, 5, None)
assert equal(date_a, date_c) == Maybe

이것은 동작 방식의 예일뿐입니다. 나는 반드시이 정확한 행동을 원하지는 않습니다.


일반적으로 이와 같은 일을 처리하는 방법은 예를 들어 연도가없는 날짜에 .NET의 0001 연도를 사용하고 월과 일이없는 연도는 1 월 1 일을 사용하는 것입니다.
Robert Harvey

도서관에 대한 요청을 제거하기 위해 귀하의 질문을 편집했습니다. 이러한 질문은이 사이트에서 다루지 않습니다.

@RobertHarvey 나는 당신의 제안을 사용할 수 없습니다. 밥이 2000 년 1 월 1 일에 태어난 것을 본다면 이것이 정확히 무엇을 의미하는지 모릅니다. 우리는 그가 2000 년 첫째 날에 태어 났는지, 또는 2000 일에 태어 났는지 알 수 없습니다. 우리는 그 차이를 알아야합니다.
Buttons840

@RobertHarvey 나는 이것이 일반적이라는 것을 알고 있지만, 그러한 신호 값의 잘못된 선택으로 인해 많은 나쁜 실패를 보았습니다. (게다가, 나는 OP 요구 만 다루는로 질문에 응답 생각하지 않아 일부 날짜를 알 수있는 등의 경우에 1 월 1 일에 설정이 미지에서 실제 월 1 일 날짜를 구별 할 수 없습니다..
고트에게 로봇

5
@ Buttons840 : 그런 다음 원하는 동작을 캡슐화하는 클래스를 작성해야합니다. 기존 날짜 클래스를 래핑하고 원하는 동작을 추가해야합니다.
Robert Harvey

답변:


3

우선, 날짜를 구성 요소로 분해하기 시작하면 더 이상 날짜가 아닙니다.

OOP를 중단하지 않고 서브 클래스를 통해 기능을 제거 할 수없는 것과 같은 방식으로, 혼동 (또는 더 나쁘게)하지 않고 날짜 및 날짜 부분을 혼합하여 코드 예제에서와 같이 다른 것을 중단하지 않고 호환하지 못하게 할 수 없습니다.

연도를 캡처하려면 간단한 정수를 포함하는 객체에 어떤 문제가 있습니까? 월과 일을 캡처하려면 월 열거와 정수 일을 캡처하지 않겠습니까? 어쩌면 날짜 개체에 내부적으로 저장하여 적절한 경계 검사를받을 수도 있습니다 (예 : 2 월 31 일은 의미가 없습니다). 그러나 다른 인터페이스를 노출하십시오.

날짜를 1 년과 비교하여 동일한 지, 더 크거나 작은 지 확인하려는 이유는 무엇입니까? 이해가되지 않습니다 : 비교하기에 충분한 정보가 없습니다. 그러나 의미가있는 다른 비교가 있습니다 (의사 코드 임).

Year y = Year(2015)
Date d = Date(2015, 01, 01)
assert y.contains(d) == True

2

Robert Harvey의 두 번째 의견에는 정답이 포함되어 있지만 조금 확장하겠습니다.

사람들의 생년월일과 사람들의 생년월일은 완전히 다른 실체이므로 둘 다에 대해 동일한 메커니즘을 사용할 필요는 없습니다 (실제로는 사용하지 않아야 함).

생년월일의 경우 규칙에 따라 2000과 같이 일정한 연도 만 포함하는 BirthDate데이터 유형 (또는 아마도 YearlyRecurringDate지금은 적절한 이름을 제시 할 수 는 없지만)을 고안 할 수 있습니다 date. 2000 년은 도약했기 때문에 좋은 선택이므로, 생일이 2 월 28 일인 사람들은 실패하지 않을 것입니다.

출생 년 동안, 당신이 고안 할 수 BirthYear데이터 유형 (또는 아마도 ApproximateDate데이터 형식)가 포함됩니다 date, 및 정밀도의 지표를 : Year, Month, Full.

이러한 접근 방식의 이점은 여전히 ​​유지 관리하는 것의 핵심으로 date날짜 산술을 수행 할 수 있다는 것입니다.


1

나는 당신이 묘사하는 것이 속성 (연도, 월 등)을 불확실성 측정 값 (값이 아닌)으로 datetime구현하는 모듈 의 드롭 인 대체품이라고 생각합니다 datetime.datetime.

파이썬 패키지는 불확실한 숫자 (예 : 불확실성 패키지) 를 돕기 위해 존재하며 , datetime각 속성에 불확실성을 사용 하는 포크를 만드는 것은 그리 어렵지 않을 것 입니다. 나도 하나보고 싶어서 그것을 사용했을 수도 있습니다. udatetime앞서 언급 한 불확실성 패키지에 포함을 포함하는 것에 대한 논증이있을 수있다 .

귀하의 예는 다음과 같습니다.

bob_bday = udatetime(2000, (6,6))  # 2000-06 +/- 6mo
>>> 2000-??-?? T??:??:??
bil_bday = udatetime((1970, 50), 3, 7)  # assume bill is ~40 +/- 40 
>>> [1970+/-40]-03-07 T??:??:??

"신호 값"에는 많은 문제가 있지만, 또한 신호 값이 할 수없는 불확실성을 가진 것들을 나타낼 수 있습니다 :

# ali was born in spring
ali_bday = udatetime((), (4.5, 1.5))
>>> [1970+/-40]-[4.5+/-1.5]-?? T??:??:??

또 다른 고려 사항은 여기에서 불확실성을보다 정확하게하기 위해서는 실제로 유형이어야한다는 것입니다 timedelta. 나는 그것을 불확실성 을 udatetime사용 하기위한 간결하고 완전한 생성자를 알아내는 연습으로 남겨둔다 timedelta.

궁극적으로 나는 당신이 묘사하는 것이 "쉽게"불확실성으로 모델링되었다고 말하고 싶지만 a의 구현 udatetime은 실제로 매우 어렵습니다. 대부분은 "쉬운"경로를 취하여 날짜 / 시간을 구성 요소로 나누고 구성 요소에 대한 불확실성을 독립적으로 추적하지만, 야심 찬 느낌이들 경우 uncertainties패키지 (또는 다른 패키지)가에 대한 풀 요청에 관심이있을 수 있습니다 udatetime.


0

시작부터 구조까지 구현하는 "기간"클래스를 작성해보십시오.

"밥은 2000 년에 태어났다"->

period {
   from  {
      yy = 2000;
      mm = 01;
      dd = 01; 
   }
   to {
     yy = 2000;
     mm = 12;
     dd = 31;
   }
   fuzz = 365;
}

그런 다음 시작 날짜를 괄호로 묶어 다양한 검색 방법을 구현할 수 있습니다. fuzz 속성은 날짜가 얼마나 정확한지에 대한 유용한 표시를 제공하므로 정확한 일치에 fuzz == 1을 지정하거나 한 달 정도에 fuzz == 31을 지정할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.