2013-03-29 2 views
2

dateutil 파이썬에서 서로에 의해 두 시간 범위/:분할이 문제를 고려하시기 바랍니다

는 내가 기간을 추가하기 시작 곳에서 과거의 일이있다. 이 기간을 추가하면 오늘보다 더 큰 날짜가되고, 나는 멈추고 마지막 날짜가 무엇인지 확인하려고합니다.

회원 자격에서 직불 일을 계산하는 기능입니다. 회원은 2007 년 1 월 31 일에 가입합니다. 그는 매달 인출됩니다. 오늘은 2013-03-29 (실제로는 atm)라고 가정 해 보겠습니다. 그래서 2007 년 1 월 31 일부터 수개월을 시작해야하며 오늘 날짜가 지나면 그만해야합니다. 다음 자동 이체 날짜가 2013-03-31임을 알 수 있습니다.

나는 현재의 날짜를 능가 할 때까지 while 루프에 relativedelta를 추가하여 이것을 구현하기 위해 dateutil 라이브러리를 사용하고 있습니다. (필자는 아마도 이것이 최선의 방법은 아니라는 것을 알고 있지만 파이썬에서 아직 완전히 새로운 개념이며 이것은 증명의 개념이다). 문제는 2007-01-31에 한 달 추가하면 다음 날짜가 2007-02-28이며 올바른 것입니다. 그러나 날짜 반복은 2007-03-28입니다. 왜냐하면 dateutil은 28 일을 마지막 날로 인식하지 못하기 때문에 날짜를 그대로 유지하고 행진 마지막 날까지 반복합니다. Ofcourse, 그것은 완벽하게 유효한 구현입니다. 그런 다음 dateutils rrule 객체로 실험했지만 동일한 원칙을 가지고 있습니다. 날짜 목록을 출력하지만 충분한 일수가없는 달은 건너 뜁니다. 나는 2007-01-31와 2013년 3월 29일 사이의 시간 범위에서 기간의 수를 계산 할 수 있다면

것은, 내가 기간의 그 수를 추가 할 수 있습니다

period = rrule(MONTHLY, interval=1, dtstart=datetime.date(2012, 5, 31), until=datetime.date(2013, 3, 29)) 
print(list(period)) 

은 그 때 나는 다른 방법을 생각 datedil은 올바른 날짜를 반환합니다.
문제는 그 기간이 항상 한 달이 아니라는 것입니다. 예를 들어 4 주, 1 년 또는 1 년이 될 수도 있습니다.

나는 relativedelta를 가지고 다른 relativedelta로 나눌 수있는 방법을 찾지 못했습니다.

누구든지 올바른 방향으로 나를 가리킬 수 있으면 감사하겠습니다. 예를 들어, 이것을 할 수있는 라이브러리가 있습니까? (timespans를 나누고 몇 달이나 몇 주와 같이 주어진 타임 블록에서 결과를 출력합니까?) 아마도 입력을 마침표로 받아 들일 수있는 데이트 티프 함수가 있습니까 (예 : in vbscript you can get the difference between two dates in whatever period you want, 주, 월, 일 등). 아마도 완전히 다른 솔루션이 있습니까?

완성도를 들어

, 나는 코드를 포함하지만, 나는 텍스트가 이미 모든 설명 생각 : 지금 해결책을 가지고 :

편집,

def calculate(self, testdate=datetime.date.today()): 
    self._testdate = testdate 


    while self.next < self._testdate: 
     self.next += self._ddinterval 
    self.previous = self.next - self._ddinterval 
    return self.next 

감사

에릭 그것이하는 일을 합니다만, 우아하고 신속한 Pythonic은 거의 없습니다. 따라서 질문이 동일하게 유지됩니다. 누구든지보다 나은 해결책을 제시 할 수 있다면 제발하십시오.여기에 내가 무엇을 최대 온의 :

today = datetime.date.today() 
start = datetime.date(2007, 1, 31) 
period = relativedelta(months=1) 

delta = period 
while start + delta < today: 
    delta += period 

next = start + delta 

대신 다음 루프의 시작 지점으로 기간을 추가 한 후 새 값을 사용하는

def calculate(self, testdate=datetime.date.today()): 
    self._testdate = testdate 

    start = self.next 
    count = 0 
    while self.next < self._testdate: 
     count += 1 
     self.next = start + (count * self._ddinterval) 
    self.previous = self.next - self._ddinterval 
    return self.next 
+0

다른 날짜 처리 모듈을 사용하여 비슷한 문제가 발생했습니다. 개월 단위로 측정 한 기간에 대한 나의 해결책은 시작일의 간격에 간격을 더한 후 결과의 달의 날짜를 비교하고 필요한 경우 조정하는 것입니다. – martineau

+0

감사합니다. 마르티노우 (Martineau). 4 주간의 기간을 추가하는 것이 아니라 몇 달 동안 만 작동합니다. 나는 단지 몇 달 추가를위한 예제를 발견했습니다. –

+2

IMO 4 주 (또는 스팬의 일수가 고정되어있는 경우)를 추가하는 것은 쉽습니다. 4 주 동안 항상 귀하의 시간에 28 일을 더할 것입니다. 그래서'old_datetime + timedelta (days = 28)'와 같은 것이 작동 할 것입니다. 몇 개월 동안 다른 달에는 다른 일수가 있기 때문에 그렇게 쉬운 일은 아닙니다. – RedBaron

답변

2

대신 계속 증가하는 델타를 만들 이 분기 및 년간을 포함한 모든 변수 기간의 길이에 대한 작동

>>> import datetime 
>>> from dateutil.relativedelta import relativedelta 
>>> today = datetime.date.today() 
>>> start = datetime.date(2007, 1, 31) 
>>> period = relativedelta(months=1) 
>>> delta = period 
>>> while start + delta < today: 
...  delta += period 
... 
>>> delta 
relativedelta(years=+6, months=+3) 
>>> start + delta 
datetime.date(2013, 4, 30) 

:에이 발생합니다. 정확히 몇 주 또는 며칠 만에 측정 한 기간에 대해서는 timedelta() 개체를 사용할 수도 있지만 이는 일반적인 해결책입니다.

월 및 분기와 같은 가변 폭 기간을 사용하는 경우 기간을 '나눌 수 없습니다. 모든 일에 측정 된 기간은 간단합니다 (timedelta에서) 일 두 날짜 사이의 차이를 변환 한 후 계수를 얻을 수있는 경우 :

period = datetime.timedelta(days=28) # 4 weeks 
delta = today - start 
remainder = delta.days % period.days 
end = today + datetime.timedelta(days=remainder) 

제공 : 델타는

>>> period = datetime.timedelta(days=28) # 4 weeks 
>>> delta = today - start 
>>> remainder = delta.days % period.days 
>>> today + datetime.timedelta(days=remainder) 
datetime.date(2013, 4, 17) 
+0

편집하기 전에 다른 마침표를 언급 한 downvote를 추가했습니다. 문제의 언급과 같이, 몇 개월 만 사용할 수도 있습니다. –

+0

답변 해 주셔서 감사합니다. 나는 이것이 이것을하는 가장 우아한 방법이라고 생각한다. 나는 "고정 된"기간을 "가변적 인"기간과 분리하는 방법을 고안해야 할 것이지만 그것이 실현 가능하다고 나는 생각한다. –

+0

다음 월간 가장 가까운 날짜를 얻으려면 특히 월간 반복되는 작업에 아주 좋은 솔루션입니다. – Angela

0

경우를 변수가 기본 시간과 관련하여 (즉, 1 개월은 28-31 일 중 하나를 의미 할 수 있음) 루프가 붙어 있습니다.

그러나 델타가 일정한 일수 인 경우 정수로 변환하고 모듈러스 연산을 수행하여 반복을 회피 할 수 있습니다.