Count the number of days of the week between two dates

Consider the following list of days of the week in 24H format:

 { 'Mon': [9,23], 'Thu': [12, 13, 14], 'Tue': [11, 12, 14], 'Wed': [11, 12, 13, 14] 'Fri': [13], 'Sat': [], 'Sun': [], } 

and two time points, for example:

  • Start:

     datetime.datetime(2015, 7, 22, 17, 58, 54, 746784) 
  • End

     datetime.datetime(2015, 8, 30, 10, 22, 36, 363912) 

Let's say we need to know how many hours between these two days (rounding up or down) for each pair of the day of the week indicated above.

How can I approach this problem in Python? I explored timedelta and relativedelta at a general level of detail, but I did not find anything that would provide anything close to this.

For simplicity, we can assume that everything refers to the same time zone.


Perhaps a simpler problem is to focus on one day pair, for example. How many Wednesdays: 14 exist between two arbitrary dates?

+7
python datetime timedelta
source share
5 answers

Maybe something like this:

 from calendar import day_abbr from datetime import datetime, timedelta def solve(start, end, data): days = list(day_abbr) output = dict.fromkeys(days, 0) while start <= end: day = days[start.weekday()] if start.hour in data[day]: output[day] += 1 start = start + timedelta(minutes=60) return output data = { 'Mon': [9, 23], 'Thu': [12, 13, 14], 'Tue': [11, 12, 14], 'Wed': [11, 12, 13, 14], 'Fri': [13], 'Sat': [], 'Sun': [], } start = datetime(2015, 7, 22, 17, 58, 54, 746784) end = datetime(2015, 8, 30, 10, 22, 36, 363912) print solve(start, end, data) # {'Wed': 20, 'Sun': 0, 'Fri': 6, 'Tue': 15, 'Mon': 10, 'Thu': 18, 'Sat': 0} 

Getting bills for every day hour by hour:

 from calendar import day_abbr from collections import defaultdict from datetime import datetime, timedelta from pprint import pprint def solve(start, end, data): days = list(day_abbr) output = defaultdict(lambda: defaultdict(int)) while start <= end: day = days[start.weekday()] if start.hour in data[day]: output[day][start.hour] += 1 start = start + timedelta(minutes=60) return {k: dict(v) for k, v in output.items()} data = { 'Mon': [9, 23], 'Thu': [12, 13, 14], 'Tue': [11, 12, 14], 'Wed': [11, 12, 13, 14], 'Fri': [13], 'Sat': [], 'Sun': [], } start = datetime(2015, 7, 22, 17, 58, 54, 746784) end = datetime(2015, 8, 30, 10, 22, 36, 363912) pprint(solve(start, end, data)) # output {'Fri': {13: 6}, 'Mon': {9: 5, 23: 5}, 'Thu': {12: 6, 13: 6, 14: 6}, 'Tue': {11: 5, 12: 5, 14: 5}, 'Wed': {11: 5, 12: 5, 13: 5, 14: 5}} 
+4
source share

I may not fully understand your problem, but you can get all the hours between two dates and summarize how many times each hour and day appears between two dates:

 from datetime import datetime from dateutil import rrule,parser d={ 'Mon': [9, 23], 'Thu': [12, 13, 14], 'Tue': [11, 12, 14], 'Wed': [11, 12, 13, 14], 'Fri': [13], 'Sat': [], 'Sun': [], } st = datetime(2015, 7, 22, 17, 58, 54, 746784) ed = datetime(2015, 8, 30, 10, 22, 36, 363912) dates = list(rrule.rrule(rrule.HOURLY, dtstart=parser.parse(st.strftime("%Y-%m-%d %H:%M:%S")), until=parser.parse(ed.strftime("%Y-%m-%d %H:%M:%S")))) days = {"Mon":0,"Tue": 1,"Wed":2,"Thu": 3,"Fri":4,"Sat":5,"Sun":6} for k, val in d.items(): for v in val: print("day: {} hour: {}".format(k,v)) day = days[k] print(sum((v == dt.hour and dt.weekday() == day) for dt in dates)) 

Output:

 day: Wed hour: 11 5 day: Wed hour: 12 5 day: Wed hour: 13 5 day: Wed hour: 14 5 day: Fri hour: 13 6 day: Tue hour: 11 5 day: Tue hour: 12 5 day: Tue hour: 14 5 day: Mon hour: 9 6 day: Mon hour: 23 5 day: Thu hour: 12 5 day: Thu hour: 13 5 day: Thu hour: 14 5 

Not sure if you want to receive the amount for all the hours in each list or the total amount for each individual hour, but in any case you can save the output in a file.

 counts = {'Thu':{}, 'Sun':{}, 'Fri':{}, 'Mon':{}, 'Tue':{}, 'Sat':{}, 'Wed':{}} for k, val in d.items(): for v in val: day = days[k] sm = sum((v == dt.hour and dt.weekday() == day) for dt in dates) counts[k][v] = sm from pprint import pprint as pp pp(counts) 

Output:

 {'Fri': {13: 6}, 'Mon': {9: 5, 23: 5}, 'Sat': {}, 'Sun': {}, 'Thu': {12: 6, 13: 6, 14: 6}, 'Tue': {11: 5, 12: 5, 14: 5}, 'Wed': {11: 5, 12: 5, 13: 5, 14: 5}} 
+2
source share

Here is a solution with loops and datetime :

 import datetime pairs = {1: [9,23], 2: [11, 12, 14], 3: [11, 12, 13, 14], 4: [12, 13, 14], 5: [13], 6: [], 7: [] } start = datetime.datetime(2015, 7, 22, 17, 58, 54, 746784) end = datetime.datetime(2015, 8, 30, 10, 22, 36, 363912) result={} for d,hl in pairs.items(): for h in hl: result[(d,h)] = 0 for diff in range((end-start).days*24): comp = start + datetime.timedelta(hours=diff) if comp.isoweekday() == d and comp.hour == h: result[(d,h)] += 1 

 >>> result {(3, 12): 5, (5, 13): 6, (3, 13): 5, (1, 23): 5, (2, 11): 5, (3, 11): 5, (4, 14): 6, (4, 13): 6, (4, 12): 6, (2, 12): 5, (2, 14): 5, (3, 14): 5, (1, 9): 5} 

I will also try to find a solution with timestamp() and % .

+2
source share

Here is another solution with arithmetic:

 import datetime pairs = {1: [9,23], 2: [11, 12, 14], 3: [11, 12, 13, 14], 4: [12, 13, 14], 5: [13], 6: [], 7: [] } start = datetime.datetime(2015, 7, 22, 17, 58, 54, 746784) end = datetime.datetime(2015, 8, 30, 10, 22, 36, 363912) result={} weeks = (end-start).days//7 for d,hl in pairs.items(): for h in hl: initial = weeks if d > start.isoweekday() or ( d == start.isoweekday() and h >= start.hour): initial += 1 result[(d,h)] = initial 

 >>> for k in sorted(result): ... print(k, result[k]) ... (1, 9) 5 (1, 23) 5 (2, 11) 5 (2, 12) 5 (2, 14) 5 (3, 11) 5 (3, 12) 5 (3, 13) 5 (3, 14) 5 (4, 12) 6 (4, 13) 6 (4, 14) 6 (5, 13) 6 
+2
source share

So, if I understood your question correctly, I would start by searching for the first occurrence of the β€œhour” within the time range, and then searching for the next events every week. Like this:

 #!/usr/bin/python from __future__ import print_function import datetime import dateutil.relativedelta def hours_between(start, end, weekday, hour): first = start + dateutil.relativedelta.relativedelta( weekday=weekday, hour=hour, minute=0, second=0, microsecond=0) week = dateutil.relativedelta.relativedelta(weeks=1) all_dates = [] d = first while d < end: all_dates.append(d) d += week return all_dates def main(): start = datetime.datetime(2015, 7, 22, 17, 58, 54, 746784) end = datetime.datetime(2015, 8, 30, 10, 22, 36, 363912) all_dates = hours_between(start, end, dateutil.relativedelta.WE, 14) print(all_dates) print(len(all_dates)) main() 
0
source share

All Articles