Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 从给定日期计算下一个和第三个业务日期_Python_Python 3.x_Algorithm - Fatal编程技术网

Python 从给定日期计算下一个和第三个业务日期

Python 从给定日期计算下一个和第三个业务日期,python,python-3.x,algorithm,Python,Python 3.x,Algorithm,我正在尝试实现一个函数来计算从给定日期算起的下一个和第三个工作日(理想情况下考虑一些给定的假期) def day of_week(年、月、日): t=[0,3,2,5,0,3,5,1,4,6,2,4] 年-=月=5,第天==30): 如果((周中的天(年、月、日)==5)): 返回str(年份+1)+“01”+“02” 如果((周中的天(年、月、日)=6)): 返回str(年份+1)+“01”+“01” 如果((周中的天(年、月、日)==0)): 返回str(年+1)+str(月)+str(日+

我正在尝试实现一个函数来计算从给定日期算起的下一个和第三个工作日(理想情况下考虑一些给定的假期)

def day of_week(年、月、日):
t=[0,3,2,5,0,3,5,1,4,6,2,4]
年-=月<3
报税表(年+整数(年/4)-整数(年/100)+整数(年/400)+t[第一个月]+天)%7
输入格式为YYYYMMDD,2018年3月21日写为20180321,输出日期应采用相同格式

我试着这样做,但我意识到这不是最好的做法

def leap_year(year):
if(year%4==0 and year%100!=0):
    return True
elif (year%4==0 and year%100==0 and year%400==0):
    return True
else:
    return False

def business_day(year, month, day):
if (month==12):
    if(day_of_week(year, month, day)<5 and day_of_week(year, month, day)>0 and day==31):
        return str(year+1)+str(0)+str(1)+str(0)+str(1)
    elif (day_of_week(year, month, day)<5 and day_of_week(year, month, day)>0 and day!=31):
        newDay="0"
        if(day<10):
            newDay = newDay + str(day+1)
        else:
            newDay = str(day+1)
        return str(year) + str(month) + newDay
    elif (day_of_week(year, month, day)>=5 and day==31):
       if(day_of_week(year, month, day)==5):
            return str(year+1)+"01"+"03"
       if (day_of_week(year, month, day) == 6):
           return str(year + 1) + "01" + "02"
       if (day_of_week(year, month, day) == 0):
           return str(year + 1) + "01" + "01"
    elif (day_of_week(year, month, day)>=5 and day==30):
        if((day_of_week(year, month, day)==5)):
            return str(year + 1) + "01" + "02"
        if ((day_of_week(year, month, day) == 6)):
            return str(year + 1) + "01" + "01"
        if ((day_of_week(year, month, day) == 0)):
            return str(year + 1) + str(month) + str(day+1)
def闰年(年):
如果(年份%4==0,年份%100!=0):
返回真值
elif(第%4年==0,第%100年==0,第%400年==0):
返回真值
其他:
返回错误
def营业日(年、月、日):
如果(月份==12):
如果(周中的日(年、月、日)为0,且日=31):
返回str(年份+1)+str(0)+str(1)+str(0)+str(1)
elif(周中的天(年、月、日)0和天!=31):
newDay=“0”
如果(第5天和第31天):
如果(周中的天(年、月、日)=5):
返回str(年份+1)+“01”+“03”
如果(周中的天(年、月、日)=6):
返回str(年份+1)+“01”+“02”
如果(周中的天(年、月、日)=0):
返回str(年份+1)+“01”+“01”
elif(一周中的第天(年、月、日)>=5,第天==30):
如果((周中的天(年、月、日)==5)):
返回str(年份+1)+“01”+“02”
如果((周中的天(年、月、日)=6)):
返回str(年份+1)+“01”+“01”
如果((周中的天(年、月、日)==0)):
返回str(年+1)+str(月)+str(日+1)
无法使用解决方案中的任何库。谢谢你的帮助

import datetime


example = '20180321'
# you can parse the time string directly to a datetime object
next_buisness_day = datetime.datetime.strptime(example, '%Y%m%d')
# specify the increment based on the day of the week or any
#other condition
increment = 1
print('day day is', next_buisness_day.weekday())
# if friday
if next_buisness_day.weekday() == 4:
    increment = 3
# if saturday
elif next_buisness_day.weekday() == 5:
    increment = 2

next_buisness_day += datetime.timedelta(days=increment)
# and convert back to whatever format you like
print('{:%Y%m%d}'.format(next_buisness_day))
看看datetime模块,你可以用它做各种事情。

我使用了“datetime”库中的几个函数。编写它们会很有趣:date(y,m,d),timedelta(days=7),day,weekday(),“{:%y%m%d}.”格式(day),strtime(输入,'%y%m%d'),strftime(日期时间,'%a%x')。好主意是为date创建一个类,并摆脱所有格式转换。因此,只有日期(y,m,d),时间差(days=7),day,weekday()将留给练习

import datetime
from datetime import date, timedelta


def day2string(day):
    return '{:%Y%m%d}'.format(day)


def year_holidays(year):
    holidays = [
        ["New Year's Day", 1, 1],  # Fixed: January 1
        ["Birthday of Martin Luther King, Jr.", 1, 0, 0, 3],  # Floating
        ["Washington's Birthday", 2, 0, 0, 3],  # Third Monday in February
        ["Memorial Day", 5, 0, 0, 5],  # Last Monday
        ["Independence Day", 7, 4],
        ["Labor Day", 9, 0, 0, 1],
        ["Columbus Day", 10, 0, 0, 2],
        ["Veterans Day", 11, 11],
        ["Thanksgiving Day", 11, 0, 3, 4],
        ["Christmas Day", 12, 25]
    ]
    year_list = []
    for h in holidays:
        if h[2] > 0:
            day = date(year, h[1], h[2])  # Fixed day
        else:
            day = date(year, h[1], 1)  # Floating day
            while h[3] != day.weekday():  # Advance to match the weekday
                day += timedelta(days=1)
            count = 1
            while count != h[4]:  # Match the repetition of this day
                next_week = day + timedelta(days=7)
                if next_week.month == day.month:
                    day = next_week
                count += 1
        year_list.append(day2string(day))
    return year_list  # return the holidays as list of strings


def str2datetime(string):
    return datetime.datetime.strptime(string, '%Y%m%d')


def next_working_day(string):
    day = str2datetime(string)
    day += timedelta(days=1)
    while True:
        while day.weekday() >= 5:
            day += timedelta(days=1)
        holidays_list = year_holidays(day.year)
        for str_day in holidays_list:
            s2 = day2string(day)
            if str_day == s2:
                day += timedelta(days=1)
                break  # for
        if day.weekday() < 5:
            break  # while True
    return day2string(day)


if __name__ == '__main__':
    dates = [
        ['20190308', '20190311', '20190313'],
        ['20190309', '20190311', '20190313'],
        ['20190310', '20190311', '20190313'],
        ['20190311', '20190312', '20190314'],
        ['20190329', '20190401', '20190403'],
        ['20181231', '20190102', '20190104'],
        ['20190118', '20190122', '20190124'],
        ['20190216', '20190219', '20190221'],
        ['20190526', '20190528', '20190530'],
        ['20190703', '20190705', '20190709'],
        ['20190828', '20190829', '20190903'],
        ['20191010', '20191011', '20191016'],
        ['20191108', '20191112', '20191114'],
        ['20191125', '20191126', '20191129'],
        ['20191224', '20191226', '20191230'],
        ['20191227', '20191230', '20200102']]
    print('\n              Today        Next   and   3rd business day')
    for days in dates:
        next_day = next_working_day(days[0])
        third_day = next_working_day(next_working_day(next_day))
        if next_day != days[1] or third_day != days[2]:
            print('*** ERROR *** ', end='')
        else:
            print('              ', end='')

        def f(x): return datetime.datetime.strftime(str2datetime(x), '%a %x')

        print(f(days[0]), f(next_day), f(third_day))

没有图书馆!我在学习Python时很开心。是吗?:-)


问题是什么?你需要一个函数将一年一月的一天转换成某个历元以来的天数(只需选择一个日期,如1900年1月1日),然后一个函数将这样的数字转换回一个日期。一旦你有了这些功能,加上3天,只需转换成一个数字,加上3,再转换回来。要处理周末,您需要一个函数,给定一个数字,该函数将返回距下一个工作日的天数。这可能与您的day of week函数类似。这是一个要求:算法将计算2020年2月28日星期五之后下一个工作日的日期。输入日期为20200228,答案也应为YYYYMMDDSide note格式-您是否考虑过
day\u name=day\u of_week(年、月、日)
以节省大约12个电话?不太可能,谢谢您指出@DillonDavis
import datetime
from datetime import date, timedelta


def day2string(day):
    return '{:%Y%m%d}'.format(day)


def year_holidays(year):
    holidays = [
        ["New Year's Day", 1, 1],  # Fixed: January 1
        ["Birthday of Martin Luther King, Jr.", 1, 0, 0, 3],  # Floating
        ["Washington's Birthday", 2, 0, 0, 3],  # Third Monday in February
        ["Memorial Day", 5, 0, 0, 5],  # Last Monday
        ["Independence Day", 7, 4],
        ["Labor Day", 9, 0, 0, 1],
        ["Columbus Day", 10, 0, 0, 2],
        ["Veterans Day", 11, 11],
        ["Thanksgiving Day", 11, 0, 3, 4],
        ["Christmas Day", 12, 25]
    ]
    year_list = []
    for h in holidays:
        if h[2] > 0:
            day = date(year, h[1], h[2])  # Fixed day
        else:
            day = date(year, h[1], 1)  # Floating day
            while h[3] != day.weekday():  # Advance to match the weekday
                day += timedelta(days=1)
            count = 1
            while count != h[4]:  # Match the repetition of this day
                next_week = day + timedelta(days=7)
                if next_week.month == day.month:
                    day = next_week
                count += 1
        year_list.append(day2string(day))
    return year_list  # return the holidays as list of strings


def str2datetime(string):
    return datetime.datetime.strptime(string, '%Y%m%d')


def next_working_day(string):
    day = str2datetime(string)
    day += timedelta(days=1)
    while True:
        while day.weekday() >= 5:
            day += timedelta(days=1)
        holidays_list = year_holidays(day.year)
        for str_day in holidays_list:
            s2 = day2string(day)
            if str_day == s2:
                day += timedelta(days=1)
                break  # for
        if day.weekday() < 5:
            break  # while True
    return day2string(day)


if __name__ == '__main__':
    dates = [
        ['20190308', '20190311', '20190313'],
        ['20190309', '20190311', '20190313'],
        ['20190310', '20190311', '20190313'],
        ['20190311', '20190312', '20190314'],
        ['20190329', '20190401', '20190403'],
        ['20181231', '20190102', '20190104'],
        ['20190118', '20190122', '20190124'],
        ['20190216', '20190219', '20190221'],
        ['20190526', '20190528', '20190530'],
        ['20190703', '20190705', '20190709'],
        ['20190828', '20190829', '20190903'],
        ['20191010', '20191011', '20191016'],
        ['20191108', '20191112', '20191114'],
        ['20191125', '20191126', '20191129'],
        ['20191224', '20191226', '20191230'],
        ['20191227', '20191230', '20200102']]
    print('\n              Today        Next   and   3rd business day')
    for days in dates:
        next_day = next_working_day(days[0])
        third_day = next_working_day(next_working_day(next_day))
        if next_day != days[1] or third_day != days[2]:
            print('*** ERROR *** ', end='')
        else:
            print('              ', end='')

        def f(x): return datetime.datetime.strftime(str2datetime(x), '%a %x')

        print(f(days[0]), f(next_day), f(third_day))
          Today        Next   and   3rd business day
          Fri 03/08/19 Mon 03/11/19 Wed 03/13/19
          Sat 03/09/19 Mon 03/11/19 Wed 03/13/19
          Sun 03/10/19 Mon 03/11/19 Wed 03/13/19
          Mon 03/11/19 Tue 03/12/19 Thu 03/14/19
          Fri 03/29/19 Mon 04/01/19 Wed 04/03/19
          Mon 12/31/18 Wed 01/02/19 Fri 01/04/19
          Fri 01/18/19 Tue 01/22/19 Thu 01/24/19
          Sat 02/16/19 Tue 02/19/19 Thu 02/21/19
          Sun 05/26/19 Tue 05/28/19 Thu 05/30/19
          Wed 07/03/19 Fri 07/05/19 Tue 07/09/19
          Wed 08/28/19 Thu 08/29/19 Tue 09/03/19
          Thu 10/10/19 Fri 10/11/19 Wed 10/16/19
          Fri 11/08/19 Tue 11/12/19 Thu 11/14/19
          Mon 11/25/19 Tue 11/26/19 Fri 11/29/19
          Tue 12/24/19 Thu 12/26/19 Mon 12/30/19
          Fri 12/27/19 Mon 12/30/19 Thu 01/02/20
def day_of_week(year, month, day):
    t = [0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4]
    year -= month < 3
    dw = (year + year // 4 - year // 100 + year // 400 + t[month-1] + day) % 7
    return [6, 0, 1, 2, 3, 4, 5][dw]  # To be consistent with 'datetime' library


def leap_year(year):
    leap = year % 4 == 0 and (year % 100 != 0 or year % 400 == 0)
    return True if leap else False


def valid_day(year, month, day):
    month_list = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
    if year < 1 or year > 9999 or month < 1 or month > 12:
        return False
    m = month_list[month-1] if month != 2 or not leap_year(year) else 29
    return True if 1 <= day <= m else False


class Career(Exception):
        def __str__(self): return 'So I became a waiter...'


MAX_DATE_AND_DAYS_INT = 365 * 100


class Date:
    #         raise ValueError

    def __init__(self, year, month, day):
        if not valid_day(year, month, day):
            raise Career()
        self.y, self.m, self.d = year, month, day

    @classmethod
    def fromstring(cls, s):
        s1, s2, s3 = int(s[0:4]), int(s[4:6]), int(s[6:8])
        return cls(s1, s2, s3)

    def __repr__(self) -> str:
        return '%04d%02d%02d' % (self.y, self.m, self.d)

    def weekday_date(self) -> str:
        names = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
        return names[self.weekday()] + ' ' + str(self)

    def next_day(self):
        if valid_day(self.y, self.m, self.d + 1):
            return Date(self.y, self.m, self.d + 1)
        elif valid_day(self.y, self.m + 1, 1):
            return Date(self.y, self.m + 1, 1)
        elif valid_day(self.y + 1, 1, 1):
            return Date(self.y + 1, 1, 1)
        else:
            raise Career

    def weekday(self):
        return day_of_week(self.y, self.m, self.d)

    def __add__(self, other):
        "Add a Date to an int."
        if isinstance(other, int):
            if other < 1 or other > MAX_DATE_AND_DAYS_INT:
                raise OverflowError("int > MAX_DATE_AND_DAYS_INT")
            new_date = Date(self.y, self.m, self.d)
            while other >= 1:
                new_date = new_date.next_day()
                other -= 1
            return new_date
        return NotImplemented

    def next_working_day(self):
        day = self.next_day()
        while True:
            while day.weekday() >= 5:
                day = day.next_day()
            holidays_list = year_holidays(day.y)
            for str_day in holidays_list:
                s2 = str(day)
                if str_day == s2:
                    day = day.next_day()
                    break  # for
            if day.weekday() < 5:
                break  # while True
        return day


def year_holidays(year):
    holidays = [
        ["New Year's Day", 1, 1],  # Fixed: January 1
        ["Birthday of Martin Luther King, Jr.", 1, 0, 0, 3],  # Floating
        ["Washington's Birthday", 2, 0, 0, 3],  # Third Monday in February
        ["Memorial Day", 5, 0, 0, 5],  # Last Monday
        ["Independence Day", 7, 4],
        ["Labor Day", 9, 0, 0, 1],
        ["Columbus Day", 10, 0, 0, 2],
        ["Veterans Day", 11, 11],
        ["Thanksgiving Day", 11, 0, 3, 4],
        ["Christmas Day", 12, 25]
    ]
    year_list = []
    for h in holidays:
        if h[2] > 0:
            day = Date(year, h[1], h[2])  # Fixed day
        else:
            day = Date(year, h[1], 1)  # Floating day
            while h[3] != day.weekday():  # Advance to match the weekday
                day = day.next_day()
            count = 1
            while count != h[4]:  # Match the repetition of this day
                next_week = day + 7
                if next_week.m == day.m:
                    day = next_week
                count += 1
        year_list.append(str(day))
    return year_list  # return the holidays as list of strings


if __name__ == '__main__':
    dates = [
        ['20190308', '20190311', '20190313'],
        ['20190309', '20190311', '20190313'],
        ['20190310', '20190311', '20190313'],
        ['20190311', '20190312', '20190314'],
        ['20190329', '20190401', '20190403'],
        ['20181231', '20190102', '20190104'],
        ['20190118', '20190122', '20190124'],
        ['20190216', '20190219', '20190221'],
        ['20190526', '20190528', '20190530'],
        ['20190703', '20190705', '20190709'],
        ['20190828', '20190829', '20190903'],
        ['20191010', '20191011', '20191016'],
        ['20191108', '20191112', '20191114'],
        ['20191125', '20191126', '20191129'],
        ['20191224', '20191226', '20191230'],
        ['20191227', '20191230', '20200102']]
    print('\n              Today        Next   and   3rd business day')
    for days in dates:
        today = Date.fromstring(days[0])
        next_day = today.next_working_day()
        third_day = next_day.next_working_day().next_working_day()
        if str(next_day) != days[1] or str(third_day) != days[2]:
            print('*** ERROR *** ', end='')
        else:
            print('              ', end='')
        print(today.weekday_date(), next_day.weekday_date(), third_day.weekday_date())
          Today        Next   and   3rd business day
          Fri 20190308 Mon 20190311 Wed 20190313
          Sat 20190309 Mon 20190311 Wed 20190313
          Sun 20190310 Mon 20190311 Wed 20190313
          Mon 20190311 Tue 20190312 Thu 20190314
          Fri 20190329 Mon 20190401 Wed 20190403
          Mon 20181231 Wed 20190102 Fri 20190104
          Fri 20190118 Tue 20190122 Thu 20190124
          Sat 20190216 Tue 20190219 Thu 20190221
          Sun 20190526 Tue 20190528 Thu 20190530
          Wed 20190703 Fri 20190705 Tue 20190709
          Wed 20190828 Thu 20190829 Tue 20190903
          Thu 20191010 Fri 20191011 Wed 20191016
          Fri 20191108 Tue 20191112 Thu 20191114
          Mon 20191125 Tue 20191126 Fri 20191129
          Tue 20191224 Thu 20191226 Mon 20191230
          Fri 20191227 Mon 20191230 Thu 20200102