如何使用Python选择一年中的所有星期日?

时间:2010-01-05 02:48:55

标签: python datetime calendar

使用Python ......

如何在一年内选择所有星期日(或任何一天)?

[ '01/03/2010','01/10/2010','01/17/2010','01/24/2010', ...]

这些日期代表2010年的星期日。这也适用于我想的一周中的任何一天。

9 个答案:

答案 0 :(得分:42)

您可以使用datetime模块中的date查找一年中的第一个星期天,然后继续添加七天,从而产生新的星期日:

from datetime import date, timedelta

def allsundays(year):
   d = date(year, 1, 1)                    # January 1st
   d += timedelta(days = 6 - d.weekday())  # First Sunday
   while d.year == year:
      yield d
      d += timedelta(days = 7)

for d in allsundays(2010):
   print(d)

答案 1 :(得分:7)

使用dateutil module,您可以通过以下方式生成列表:

#!/usr/bin/env python
import dateutil.relativedelta as relativedelta
import dateutil.rrule as rrule
import datetime
year=2010
before=datetime.datetime(year,1,1)
after=datetime.datetime(year,12,31)
rr = rrule.rrule(rrule.WEEKLY,byweekday=relativedelta.SU,dtstart=before)
print rr.between(before,after,inc=True)

虽然如果没有dateutil,找到所有星期日并不难,但是如果您有更复杂或更多的日期计算,该模块非常方便。

如果您使用的是Debian / Ubuntu,则dateutil由python-dateutil包提供。

答案 2 :(得分:4)

您可以迭代该年的日历。 以下内容应返回给定年份的所有星期二和星期四。

# Returns all Tuesdays and Thursdays of a given year
from datetime import date
import calendar

year = 2016
c = calendar.TextCalendar(calendar.SUNDAY)
for m in range(1,13):
    for i in c.itermonthdays(year,m):
        if i != 0:                                      #calendar constructs months with leading zeros (days belongng to the previous month)
            day = date(year,m,i)
            if day.weekday() == 1 or day.weekday() == 3: #if its Tuesday or Thursday
                print "%s-%s-%s" % (year,m,i)

答案 3 :(得分:2)

Pandas凭借其date_range功能为此目的提供了强大的功能。

结果是pandas DatetimeIndex,但可以轻松转换为列表。

import pandas as pd

def allsundays(year):
    return pd.date_range(start=str(year), end=str(year+1), 
                         freq='W-SUN').strftime('%m/%d/%Y').tolist()

allsundays(2017)[:5]  # First 5 Sundays of 2017
# ['01/01/2017', '01/08/2017', '01/15/2017', '01/22/2017', '01/29/2017']

答案 4 :(得分:2)

使用列表理解:

dds::sub::cond::ReadCondition rc(*mp_reader,
                                 dds::sub::status::DataState::any(),
                                 std::bind(&MyClass::do_stuff, this));

答案 5 :(得分:1)

这是一个完整的生成器函数,它基于@sth的解决方案。它包括他的解决方案评论中提到的关键修复。

您可以指定星期几(使用Python的索引,0 =星期一到6 =星期日),开始日期和枚举的周数。

def get_all_dates_of_day_of_week_in_year(day_of_week, start_year, start_month, 
                                         start_day, max_weeks=None):
    '''
    Generator function to enumerate all calendar dates for a specific day
    of the week during one year. For example, all Wednesdays in 2018 are:
    1/3/2018, 1/10/2018, 1/17/2018, 1/24/2018, 1/31/2018, 2/7/2018, etc.

    Parameters:
    ----------
    day_of_week : int
        The day_of_week should be one of these values: 0=Monday, 1=Tuesday, 
        2=Wednesday, 3=Thursday, 4=Friday, 5=Saturday, 6=Sunday.
    start_year : int
    start_month : int
    start_day : int
        The starting date from which to list out all the dates
    max_weeks : int or None
        If None, then list out all dates for the rest of the year.
        Otherwise, end the list after max_weeks number of weeks.
    '''

    if day_of_week < 0 or day_of_week > 6:
        raise ValueError('day_of_week should be in [0, 6]')

    date_iter = date(start_year, start_month, start_day)

    # First desired day_of_week
    date_iter += timedelta(days=(day_of_week - date_iter.weekday() + 7) % 7) 
    week = 1
    while date_iter.year == start_year:
        yield date_iter
        date_iter += timedelta(days=7)
        if max_weeks is not None:
            week += 1
            if week > max_weeks:
                break

从2018年1月1日开始,为期10周的所有星期三的使用示例。

import calendar
day_of_week = 2
max_weeks = 10
for d in get_all_dates_of_day_of_week_in_year (day_of_week, 2018, 1, 1, max_weeks):
    print "%s, %d/%d/%d" % (calendar.day_name[d.weekday()], d.year, d.month, d.day)

上面的代码产生:

Wednesday, 2018/1/3
Wednesday, 2018/1/10
Wednesday, 2018/1/17
Wednesday, 2018/1/24
Wednesday, 2018/1/31
Wednesday, 2018/2/7
Wednesday, 2018/2/14
Wednesday, 2018/2/21
Wednesday, 2018/2/28
Wednesday, 2018/3/7

答案 6 :(得分:1)

根据@sth的答案,我想给你一个没有功能的选择

from datetime import date, timedelta,datetime

sunndays = list()

year_var = datetime.now() #get current date
year_var = year_var.year  #get only the year

d = date(year_var, 1, 1)  #get the 01.01 of the current year = 01.01.2020

#now we have to skip 4 days to get to sunday.
#d.weekday is wednesday so it has a value of 2
d += timedelta(days=6 - d.weekday()) # 01.01.2020 + 4 days (6-2=4)

sunndays.append(str(d.strftime('%d-%m-%Y'))) #you need to catch the first sunday

#here you get every other sundays
while d.year == year_var:
    d += timedelta(days=7)
    sunndays.append(str(d.strftime('%d-%m-%Y')))

print(sunndays) # only for control

如果您想每个星期一为例

#for 2021 the 01.01 is a friday the value is 4
#we need to skip 3 days 7-4 = 3
d += timedelta(days=7 - d.weekday())

答案 7 :(得分:0)

根据@ sth的答案,它将失去星期天1日。这会更好:

d = datetime.date(year, month-1, 28)
for _ in range(5):
    d = d + datetime.timedelta(days=-d.weekday(), weeks=1)
    if d.month!=month:
        break
    date.append(d)

答案 8 :(得分:0)

如果要寻找一种更一般的方法(即不仅是星期天),我们可以基于sthanswer

def weeknum(dayname):
    if dayname == 'Monday':   return 0
    if dayname == 'Tuesday':  return 1
    if dayname == 'Wednesday':return 2
    if dayname == 'Thursday': return 3
    if dayname == 'Friday':   return 4
    if dayname == 'Saturday': return 5
    if dayname == 'Sunday':   return 6

这会将日期名称转换为int

然后做:

从日期时间导入日期开始,时间增量

def alldays(year, whichDayYouWant):
    d = date(year, 1, 1)
    d += timedelta(days = (weeknum(whichDayYouWant) - d.weekday()) % 7)
    while d.year == year:
        yield d
        d += timedelta(days = 7)

for d in alldays(2020,'Sunday'):
    print(d)

请注意% 7中存在alldays()。输出:

2020-01-05
2020-01-12
2020-01-19
2020-01-26
2020-02-02
2020-02-09
2020-02-16
...

还可以:

for d in alldays(2020,'Friday'):
    print(d)

这将为您提供:

2020-01-03
2020-01-10
2020-01-17
2020-01-24
2020-01-31
2020-02-07
2020-02-14
...