【问题标题】:Store business days according to week in Python (2.7)?在Python(2.7)中按周存储工作日?
【发布时间】:2013-08-16 15:28:06
【问题描述】:

如何创建一个 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。

【问题讨论】:

  • 因此,为简化起见,您有一个假期列表,并且您想创建一个特定月份每周有多少工作日的映射?
  • 没错。对不起,今天是星期五,我的脑子很乱。 ://

标签: python date python-2.7 calendar


【解决方案1】:
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)]

}

【讨论】:

  • 呸!我爱你们和你们所有的知识。这适用于计算和存储几乎完美。在这个答案和 Joowani 的答案之间......我也许可以让它完全按照我的意愿去做。
  • 我不需要将数据存储为{'week1' : 4},而是将其存储为:{'week1' : (8/1/2013), (8/2/2013), etc}
  • 我爱你.. 这真的很有帮助。
【解决方案2】:

我不确定您希望如何存储数据,但您正在寻找这种类型的数据吗?

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']

【讨论】:

  • 谢谢@Joowani。这绝对让我朝着正确的方向前进,但它并不完整。我需要一个函数来计算并存储任何月份的天数和周数。您的代码可以帮助我进行存储过程,但不能帮助我进行计算。 :)
【解决方案3】:

假设您的“一个月中的一周”在星期日结束,工作日是星期一到星期五(根据您的示例)

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']}

【讨论】:

    【解决方案4】:

    试试这个:

    >>> 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])
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-19
      • 2016-06-10
      • 2023-03-26
      • 2020-11-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多