Python 给定一个日期范围,如何计算该范围内的部分或全部周末数?

Python 给定一个日期范围,如何计算该范围内的部分或全部周末数?,python,date,date-arithmetic,Python,Date,Date Arithmetic,给定一个日期范围,如何计算该范围内的部分或全部周末数 (按要求提供一些定义: 把“周末”理解为周六和周日。 日期范围包括在内,即结束日期是范围的一部分 “全部或部分”是指周末的任何部分在日期范围内意味着整个周末被计算在内。) 为了简化,我想你实际上只需要知道持续时间和一周中的哪一天是第一天 我补好了,现在需要做7的整数除法,还有一些逻辑,根据余数加1,但我不太清楚是什么 Python中答案的额外要点;-) 编辑 这是我的最终代码 周末是星期五和星期六(因为我们正在计算入住的夜数),从星期一开始,

给定一个日期范围,如何计算该范围内的部分或全部周末数

(按要求提供一些定义: 把“周末”理解为周六和周日。 日期范围包括在内,即结束日期是范围的一部分 “全部或部分”是指周末的任何部分在日期范围内意味着整个周末被计算在内。)

为了简化,我想你实际上只需要知道持续时间和一周中的哪一天是第一天

我补好了,现在需要做7的整数除法,还有一些逻辑,根据余数加1,但我不太清楚是什么

Python中答案的额外要点;-)

编辑

这是我的最终代码

周末是星期五和星期六(因为我们正在计算入住的夜数),从星期一开始,天数为0-1。我使用了一个接一个的算法和Tom的代码布局。非常感谢各位

def calc_weekends(start_day, duration):
    days_until_weekend = [5, 4, 3, 2, 1, 1, 6]
    adjusted_duration = duration - days_until_weekend[start_day]
    if adjusted_duration < 0:
        weekends = 0
    else:
        weekends = (adjusted_duration/7)+1
    if start_day == 5 and duration % 7 == 0: #Saturday to Saturday is an exception
        weekends += 1
    return weekends

if __name__ == "__main__":
    days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
    for start_day in range(0,7):
        for duration in range(1,16):
            print "%s to %s (%s days): %s weekends" % (days[start_day], days[(start_day+duration) % 7], duration, calc_weekends(start_day, duration))
        print
def calc_周末(开始日,持续时间):
到周末的天数=[5,4,3,2,1,1,6]
调整后的持续时间=持续时间-到周末的天数[开始日]
如果调整的持续时间小于0:
周末=0
其他:
周末=(调整的持续时间/7)+1
如果开始日=5,持续时间%7==0:#周六到周六是例外
周末+=1
返回周末
如果名称=“\uuuuu main\uuuuuuuu”:
天数=['星期一'、'星期二'、'星期三'、'星期四'、'星期五'、'星期六'、'星期日']
对于范围(0,7)内的开始日:
对于范围(1,16)内的持续时间:
打印“%s到%s(%s天):%s周末”%(天[开始日]、天[(开始日+持续时间)%7]、持续时间、计算周末(开始日,持续时间))
打印

除了原始数学,您还需要外部逻辑。你需要有一个日历库(或者如果你有足够的时间自己去实现),来定义一个周末,一周中的哪一天开始,结束,等等

看一看


如果代码中没有对天数的逻辑定义,纯数学方法在极端情况下会失败,比如间隔1天,或者,我相信,任何低于一周的时间(或者如果允许部分,则低于6天)。

除了原始数学之外,还需要外部逻辑。你需要有一个日历库(或者如果你有足够的时间自己去实现),来定义一个周末,一周中的哪一天开始,结束,等等

看一看


如果代码中没有对天数的逻辑定义,纯数学方法在极端情况下会失败,比如间隔1天,或者,我相信,任何低于一周的时间(或者如果允许部分,则低于6天)。

这类事情的一般方法:

对于一周中的每一天,计算从该天开始的时段“包含周末”需要多少天。例如,如果“包含周末”表示“包含周六和周日”,则我们有下表:

星期日:8 星期一:7 星期二:6 星期三:5 星期四:4 星期五:3 星期六:2

对于“部分或全部”,我们有:

星期日:1 星期一:6 星期二:5 星期三:4 星期四:3 星期五:2 星期六:1

显然,这不必编码为一个表,现在它的外观已经很明显了

然后,给定月经开始的一周中的哪一天,从以天为单位的月经长度中减去[*]魔法值(可能是开始-结束+1,以包括两个围栏柱)。如果结果小于0,则它包含0个周末。如果它等于或大于0,则它包含(至少)1个周末

然后你必须处理剩下的日子。在第一种情况下,这很容易,每7天额外增加一个周末。在第二种情况下,除了周日,每个开始日都是如此,因为周日只需要再增加6天就可以包括另一个周末。因此,在第二种情况下,对于从周日开始的时段,可以在时段开始时计算1个周末,然后从长度中减去1,然后从周一开始重新计算

更一般地说,“全部或部分”周末的情况是,我们检查是否在有趣的部分(“周末”)中途开始。如果是,我们可以:

  • 1) 数一,将开始日期移到感兴趣位的末尾,然后重新计算
  • 2) 将开始日期移回感兴趣位的开头,然后重新计算
在周末的情况下,只有一种特殊情况是从中途开始的,所以(1)看起来不错。但是,如果您将日期作为以秒为单位而不是以天为单位的日期+时间,或者如果您对5天工作周而不是2天周末感兴趣,那么(2)可能更容易理解


[*]当然,除非您使用的是无符号类型。

这类事情的一般方法:

对于一周中的每一天,计算从该天开始的时段“包含周末”需要多少天。例如,如果“包含周末”表示“包含周六和周日”,则我们有下表:

星期日:8 星期一:7 星期二:6 星期三:5 星期四:4 星期五:3 星期六:2

对于“部分或全部”,我们有:

星期日:1 星期一:6 星期二:5 星期三:4 星期四:3 星期五:2 星期六:1

显然,这不必编码为一个表,现在它的外观已经很明显了

然后,给定月经开始的一周中的哪一天,从以天为单位的月经长度中减去[*]魔法值(可能是开始-结束+1,以包括两个围栏柱)。如果结果小于0,则它包含0个周末。如果它等于或大于0,则它包含(至少)1个周末

然后你必须处理剩下的日子。在第一种情况下,这很容易,每7天额外增加一个周末。在第二种情况下,除了周日,每个开始日都是如此,因为周日只需要6天就可以包含ano
days = {"Saturday":-2, "Sunday":-1, "Monday":0, "Tuesday":1, "Wednesday":2, "Thursday":3, "Friday":4}

def n_full_weekends(n_days, start_day):
    n_days += days[start_day]
    if n_days <= 0:
        n_weekends = 0
    else:
        n_weekends = n_days//7
    return n_weekends

if __name__ == "__main__":
    tests = [("Tuesday", 10, 1), ("Monday", 7, 1), ("Wednesday", 21, 3), ("Saturday", 1, 0), ("Friday", 1, 0),
    ("Friday", 3, 1), ("Wednesday", 3, 0), ("Sunday", 8, 1), ("Sunday", 21, 2)]
    for start_day, n_days, expected in tests:
        print start_day, n_days, expected, n_full_weekends(n_days, start_day)
from datetime import date, timedelta    
FRI = 5; SAT = 6

# a couple of random test dates
now = date.today()
start_date = now - timedelta(57)
end_date = now - timedelta(13)
print start_date, '...', end_date    # debug

days = [date.fromordinal(d) for d in  
            range( start_date.toordinal(),
                   end_date.toordinal()+1 )]
weekend_days = [d for d in days if d.weekday() in (FRI,SAT)]

for day in weekend_days:      # debug
    print day, day.weekday()  # debug
num_weekends = len(weekend_days) // 2

# if we start on Friday and end on Saturday we're ok,
# otherwise add one weekend
#  
# F,S|F,S|F,S   ==3 and 3we, +0
# F,S|F,S|F     ==2 but 3we, +1
# S|F,S|F,S     ==2 but 3we, +1
# S|F,S|F       ==2 but 3we, +1

ends = (weekend_days[0].weekday(), weekend_days[-1].weekday())
if ends != (FRI, SAT):
    num_weekends += 1

print num_weekends    # your answer