在Python(2.7)中按周存储工作日?

时间:2013-08-16 15:28:06

标签: python date python-2.7 calendar

如何创建一个Python脚本,用于存储营业日日期以及任何月份的相应周数?

这个问题令人困惑,所以这里有一个“视觉”:

August_2013 = {
  ( week1 : (8/1/2013),  (8/2/2013) ),
  ( week2 : (8/5/2013),  (8/6/2013),  (8/7/2013),  (8/8/2013),  (8/9/2013)  ),
  ( week3 : (8/12/2013), (8/13/2013), (8/14/2013), (8/15/2013), (8/16/2013) ),
  ( week4 : (8/19/2013), (8/20/2013), (8/21/2013), (8/22/2013), (8/23/2013) ),
  ( week5 : (8/26/2013), (8/27/2013), (8/28/2013), (8/29/2013), (8/30/2013) )
}

从搜索到的所有SO,我写了以下代码来计算两天之间的工作日数:

def businessDays(start_date, end_date):
  day_generator = (start_date + timedelta(x + 1) for x in xrange((end_date - start_date).days))
  holidays = [ date(2013, 7, 4), date(2013, 12, 25) ] # Will add more later
  return sum(1 for day in day_generator if day.weekday() < 5 and day not in holidays)

但这段代码还不够......我需要知道在任何一个月的哪一周有多少个工作日。

编辑:我的操作系统是Windows 7.我使用的是Python 2.7。

4 个答案:

答案 0 :(得分:2)

import calendar
import collections
from datetime import date

def get_weeks(year, month, holidays):
    cal = calendar.Calendar(0)
    weeks = collections.defaultdict(lambda: 0)
    for i, week in enumerate(cal.monthdatescalendar(year, month)):
        # Get just mon-fri
        for day in week[:-2]:
            if day.month == month and day not in holidays:
                weeks['week%s' % (i+1)] += 1
    return weeks
holidays = [date(2013, 8, 2), date(2013, 8, 6)]
print get_weeks(2013, 8, holidays)

这给了我:

{'week2': 4, 'week1': 1, 'week4': 5, 'week3': 5, 'week5': 5})

如果我在8月29日再添加一个假期,我会得到:

>>> holidays = [date(2013, 8, 2), date(2013, 8, 6), date(2013, 8, 29)]
>>> print  get_weeks(2013, 8, holidays)
{'week2': 4, 'week1': 1, 'week4': 5, 'week3': 5, 'week5': 4})

更新

import calendar
import collections
from datetime import date

def get_weeks(year, month, holidays):
    cal = calendar.Calendar(0)
    weeks = collections.defaultdict(list)
    for i, week in enumerate(cal.monthdatescalendar(year, month)):
        # Get just mon-fri
        for day in week[:-2]:
            if day.month == month and day not in holidays:
                weeks['week%s' % (i+1)].append(day)
    return weeks
holidays = [date(2013, 8, 2), date(2013, 8, 6), date(2013, 8, 29)]
print get_weeks(2013, 8, holidays)

这给了我:

{
  'week1': [date(2013, 8, 1)],
  'week2': [date(2013, 8, 5), date(2013, 8, 7), date(2013, 8, 8),
            date(2013, 8, 9)],
  'week3': [date(2013, 8, 12), date(2013, 8, 13), date(2013, 8, 14),
            date(2013, 8, 15), date(2013, 8, 16)],
  'week4': [date(2013, 8, 19), date(2013, 8, 20), date(2013, 8, 21),
            date(2013, 8, 22), date(2013, 8, 23)],
  'week5': [date(2013, 8, 26), date(2013, 8, 27), date(2013, 8, 28),
            date(2013, 8, 30)]

}

答案 1 :(得分:1)

我不确定你想要如何存储数据,但这是你想要的吗?

August_2013 = {}

def store(month, week, date):
    if week in month and date not in month[week]:
        month[week].append(date)
    else:
        month[week] = [date]

store(August_2013, "week1", "8/1/2013")
store(August_2013, "week1", "8/2/2013")
store(August_2013, "week2", "8/5/2013")

#calling August_2013 then returns {'week1': ['8/1/2013', '8/2/2013'], 'week2': ['8/5/2013']}

要访问您的数据,您可以执行以下操作:

def access(month, week):
    return month[week]

access(August_2013, "week1") # will return ['8/1/2013', '8/2/2013']

答案 2 :(得分:0)

假设你的每周一周&#34;在星期日结束,工作日是星期一到星期五(根据你的例子)

import calendar
from datetime import date

def get_working_days(year, month, holidays):
  first_day, last_day = calendar.monthrange(year, month) # this gives the weekday of the first day of the month followed by the last day

  week = 1
  if first_day > 4: week = 0 # Assuming if you have Saturday, Sunday at the beginning of the month this doesn't start as the first week.

  working_days = {}

  for day in range(1, last_day+1):
    weekstr = 'week{0}'.format(week)
    if week > 0 and not weekstr in working_days:
      working_days[weekstr] = []
    today = date(year,month,day)
    if today.weekday() < 5:
      if today not in holidays:
        working_days[weekstr].append(today.strftime('%m/%d/%Y'))
    if today.weekday() == 6:
      week += 1

  return working_days

holidays = [date(2013, 8, 2), date(2013, 8, 6)]
print get_working_days(2013, 8, holidays)

返回

{'week1': ['08/01/2013'], 'week3': ['08/12/2013', '08/13/2013', '08/14/2013', '08/15/2013', '08/16/2013'], 'week2': ['08/05/2013', '08/07/2013', '08/08/2013', '08/09/2013'], 'week5': ['08/26/2013', '08/27/2013', '08/28/2013', '08/29/2013', '08/30/2013'], 'week4': ['08/19/2013', '08/20/2013', '08/21/2013', '08/22/2013', '08/23/2013']}

答案 3 :(得分:0)

试试这个:

>>> import datetime
>>> def day_weekday(I_year, I_month):
    lst_weekday=[]
    lst_tmp=[]
    for day in range(1,32):
        try:
            day_temp=datetime.datetime(I_year, I_month, day)
            if day_temp.weekday() not in (6, 5):
                lst_tmp.append((I_year, I_month, day))
            elif len(lst_tmp)>0:
                lst_weekday.append(lst_tmp)
                lst_tmp=[]
            else:
                pass
        except ValueError:
            pass
    return lst_weekday, map(len, lst_weekday)

>>> day_weekday(2013, 8)
([[(2013, 8, 1), (2013, 8, 2)], \
 [(2013, 8, 5), (2013, 8, 6), (2013, 8, 7), (2013, 8, 8), (2013, 8, 9)], \
 [(2013, 8, 12), (2013, 8, 13), (2013, 8, 14), (2013, 8, 15), (2013, 8, 16)], \
 [(2013, 8, 19), (2013, 8, 20), (2013, 8, 21), (2013, 8, 22), (2013, 8, 23)], \
 [(2013, 8, 26), (2013, 8, 27), (2013, 8, 28), (2013, 8, 29), (2013, 8, 30)]], \
 [2, 5, 5, 5, 5])

该函数返回两个列表。第一个是列表清单,每个清单是该周的工作日。第二个是每周的工作日数。您可以将其格式化为您想要的其他格式。