当您输出感兴趣的接下来4天时,最大的问题是在for循环中.您有一行first_day = startdate.replace(day = 1),并在结果的等周前设置tempWeek.问题是,您不更新月份以反映add_months.这将抛弃一切.因此,将行更改为
first_day = startdate.replace(day=1, month=added_months)
但是,您还需要跟踪年份-将月份从12滚动到1很好,但是当您这样做时,还需要更新年份.这不会影响您的即时测试,但是您在年底附近尝试的任何其他测试都会受到影响.
for x in range(0, 5):
tempWeek = weekNumb
print("Date: ", startdate)
if(startdate.month + 1 > 12):
added_months = 1
added_years = startdate.year + 1
else:
added_months = startdate.month + 1
added_years = startdate.year
weeks = cal.monthdayscalendar(added_years, added_months)
first_day = startdate.replace(day=1, month=added_months, year=added_years)
if(first_day.isoweekday() in (6,7)): tempWeek += 1
plannedDay = weeks[tempWeek][dayOfTheWeek]
if(added_months < 10): added_months = str(added_months).zfill(2)
datestr = "{}-{}-{}".format(startdate.year, added_months, plannedDay)
startdate = datetime.strptime(datestr, "%Y-%m-%d").date()
这样做应该可以解决您的问题.
额外提示:
>我只需在交互式python shell中键入每一行即可解决此问题,并且每次设置变量后,我都会对其进行查看.随着这一点的提高,您可能会学会开始使用调试器,这将给您带来相同的效果,但是更加容易.
>我建议不要踩踏startdate.您所做的工作是完全有效的,但是奇怪的是您保留了一些变量而踩到了其他变量.为了与您拥有的变量名保持一致,我建议您使用add_date,但是在我的代码下面,我将其更改为first_date.
>用它的字符串表示形式覆盖add_months(一个整数)也很奇怪(但被允许).同样,我将使用其他变量,例如str_months.通常,让一个变量执行一件事可以使阅读更流畅.在下面的示例代码中,我通过利用格式的功能摆脱了对字符串的需求.
>通常不要将if语句的结果与if放在同一行是一种很好的样式.如今,空白确实很便宜,它使阅读更加轻松.
>如果for循环的最终结果在末尾而不是中途,则事情会变得更干净.
>另外,您应该希望在内部与您的名称(camelCase或underscored_names)保持一致,但理想情况下不要同时使用两者.
>尽可能避免使用for循环是pythonic的,通常,如果在len(…“中使用” for x“,则有一种更有效的方法.如注释中所述,枚举可以做到这一点.
> python中的一个不错的标准是对不需要的变量使用_,例如在固定的for循环中.
上面的代码是使代码正常工作的最低限度的更改.鉴于我刚才提到的提示,以下是我将进行的修改.另外,我包括了import语句,因为没有它们,代码是不可执行的.我们总是尝试将可执行代码发布到此处的Stack Overflow.
from datetime import datetime
import calendar
start_date = input("Enter a startdate: ")
start_date = datetime.strptime(start_date, "%Y-%m-%d").date()
day_of_the_week = start_date.weekday()
first_day = start_date.replace(day=1)
cal = calendar.Calendar()
weeks = cal.monthdayscalendar(start_date.year, start_date.month)
# This if statement could be a single line:
# adjust_range = 1 if first_day.isoweekday() in (6,7) else 0
if(first_day.isoweekday() in (6,7)):
adjust_range = 1
else:
adjust_range = 0
for x, week in enumerate(weeks):
if start_date.day in week:
week_numb = x - adjust_range
# This will happen only once, so you can break out of the loop
break
print("Date: ", start_date)
first_date = start_date.replace(day=1)
for _ in range(4):
temp_week = week_numb
if(first_date.month + 1 > 12):
new_months = 1
new_years = first_date.year + 1
else:
new_months = first_date.month + 1
new_years = first_date.year
weeks = cal.monthdayscalendar(new_years, new_months)
first_date = first_date.replace(day=1, month=new_months, year=new_years)
if(first_date.isoweekday() in (6,7)):
temp_week += 1
planned_day = weeks[temp_week][day_of_the_week]
# The if wasn't needed; let format do the work for you.
print("{}-{:02d}-{:02d}".format(new_years, new_months, planned_day))
# You could set something like
# interested_date = datetime(added_years, added_months, planned_day),
# but you don't seem to use it.