# Finding specific date ranges

Ricardo Aráoz ricaraoz at gmail.com
Fri Sep 7 19:59:12 CEST 2007

```Tim Golden wrote:
> kyosohma at gmail.com wrote:
>> Hi,
>>
>> I am working on a timesheet application in which I need to to find the
>> first pay period in a month that is entirely contained in that month
>> to calculate vacation time. Below are some example date ranges:
>>
>>
>> December 31, 2006    January 13, 2007 # doesn't earn
>> January 14, 2007	January 27, 2007 # does earn
>> January 28, 2007	February 10, 2007 # doesn't
>> February 11, 2007	February 24, 2007 # does
>>

import datetime

def itEarns(fromDate, toDate) :
return (fromDate.year == toDate.year and fromDate.month == toDate.month)

periods = [
(datetime.date(2006, 12, 31), datetime.date(2007, 1, 13)),
(datetime.date(2007, 1, 14), datetime.date(2007, 1, 27)),
(datetime.date(2007, 1, 28), datetime.date(2007, 2, 10)),
(datetime.date(2007, 2, 11), datetime.date(2007, 2, 24))
]

candidatePeriods = [(frm, to) for frm, to in periods if itEarns(frm, to)]

??

>>
>> So far, the best approach I've come up with is to create a list of
>> tuples that contain the pay period date ranges for the year and
>> iterate through the tuples looking for the first occurrence of the
>> month names matching. Then I'd add that date range to a separate list
>> and somehow ignore any other matches in that month. This seems like a
>> hack. Does anyone have a better idea?
>
>
> Well, I can come up with a solution which basically reflects the
> way I'd do it in SQL (since this kind of thing is my bread-and-butter
> there) but I'm not convinced it's really any better than your proposal.
> However, for the purposes of illustration:
>
> <code>
> import calendar
> import datetime
>
> YEAR = 2007
>
> months = [
>    (datetime.date (YEAR, n, 1), datetime.date (YEAR, n, calendar.monthrange (YEAR, n)[1]))
>    for n in range (1, 13)
> ]
>
> periods = [
>    (datetime.date(2006, 12, 31), datetime.date(2007, 1, 13)),
>    (datetime.date(2007, 1, 14), datetime.date(2007, 1, 27)),
>    (datetime.date(2007, 1, 28), datetime.date(2007, 2, 10)),
>    (datetime.date(2007, 2, 11), datetime.date(2007, 2, 24))
> ]
>
> for m in months:
>    candidate_periods = [p for p in periods if m[0] <= p[0] and p[1] <= m[1]]
>    if candidate_periods:
>      print m[0], "=>", min (candidate_periods)
>    else:
>      print m[0], "=>", "no period matches"
>
> </code>
>
> TJG

```