I have three columns in a pandas dataframe that I want to convert into a single date column. The problem is that one of the columns is day column. I am not able to convert into exact date of that month and year. Can anyone please help me to solve this issue. It looks something like this:
BirthMonth BirthYear Day
0 5 88 1st Monday
1 10 87 3rd Tuesday
2 12 87 2nd Saturday
3 1 88 1st Tuesday
4 2 88 1st Monday
Based on your reply to my first comment I updated my answer as follows. I think this is what you are looking for:
import re
import time
import calendar
import numpy as np
days = ['1st Monday', '3rd Tuesday', '4th wednesday']
months = [2, 3, 5]
years = [1990, 2000, 2019]
def extract_numeric(text: str):
return int(re.findall(r'\d+', text)[0])
def weekday_to_number(weekday: str):
return time.strptime(weekday, "%A").tm_wday
def get_date(number: int, weekday: int, month: int, year: int) -> str:
""" 3rd Tuesday translates to number: 3, weekday: 1 """
firstday, n_days = calendar.monthrange(year, month)
day_list = list(range(7)) * 6
month_days = day_list[firstday:][:n_days]
day = (np.where(np.array(month_days) == weekday)[0] + 1)[number - 1]
return '{}/{}/{}'.format(day, month, year)
numbers = []
weekdays = []
for day in days:
number, weekday = day.split()
numbers.append(extract_numeric(number))
weekdays.append(weekday_to_number(weekday))
dates = []
for number, weekday, month, year in zip(numbers, weekdays, months, years):
dates.append(get_date(number, weekday, month, year))
print(dates) # ['5/2/1990', '21/3/2000', '22/5/2019']
use the calendar module to get the day from days. then convert day,monyh,year to DateTime
import calendar
import datetime
def get_date(rows):
day = {'monday':0,'tuesday':1,'wednesday':2,'thursday':3,'friday':4,'saturday':5,'sunday':6}
day_num = day.get(rows.days.split()[1].lower())
weekday_num = [week[day_num] for week in calendar.monthcalendar(rows.years, rows.months) if week[day_num] >0][int(rows.days.split()[0][0])-1]
return datetime.date(rows.years, rows.months, weekday_num)
apply the above function to all rows
df['date'] = df(lambda row: get_date(row), axis=1)
df
>>
days months years date
0 1st Monday 8 2015 2015-08-03
1 3rd Tuesday 12 2017 2017-12-19
2 4th wednesday 5 2019 2019-05-22
Not very fast solution(since it involves 2 nested loops) but I hope this solves your question
import pandas as pd
import datetime
import calendar
pd.set_option('display.max_rows', 100)
cols = ['day', 'month', 'year']
data = [
['1st Monday', 8, 2015],
['3rd Tuesday', 12, 2017],
['4th Wednesday', 5, 2019]
]
df = pd.DataFrame(data=data, columns=cols)
df['week_number'] = df['day'].str.slice(0, 1)
df['week_number'] = df['week_number'].astype('int')
df['day_name'] = df['day'].str.slice(4)
def generate_dates(input_df, index_num):
_, days = calendar.monthrange(input_df.loc[index_num, 'year'], input_df.loc[index_num, 'month'])
df_dates = pd.DataFrame()
for i in range(1, days + 1):
df_dates.loc[i - 1, 'date'] = datetime.date(input_df.loc[index_num, 'year'], input_df.loc[index_num, 'month'],
i)
df_dates.loc[i - 1, 'year'] = input_df.loc[index_num, 'year']
df_dates.loc[i - 1, 'days'] = calendar.weekday(input_df.loc[index_num, 'year'],
input_df.loc[index_num, 'month'], i)
df_dates.loc[i - 1, 'day_name'] = df_dates.loc[i - 1, 'date'].strftime("%A")
df_dates['week_number'] = 1
df_dates['week_number'] = df_dates.groupby('day_name')['week_number'].cumsum()
return df_dates
dates = pd.DataFrame(columns=['date', 'year', 'days', 'day_name', 'week_number'])
for row in df.index:
dates = pd.concat([dates, generate_dates(df, row)])
df2 = df.merge(dates, on=['year', 'day_name', 'week_number'])
print(df2)
Edit to match SO new dataframe
My solution using pandas dayofweek function:
import numpy as np
import pandas as pd
from datetime import date
from dateutil.relativedelta import relativedelta
#generate dataframe
df=pd.DataFrame({'BirthMonth':[5, 10, 12, 1 ,2],
'BirthYear':[88, 87, 87, 88, 88],
'Day':['1st Monday', '3rd Tuesday', '2nd Saturday','1st Tuesday','1st Monday']})
#Assuming the year refers to 19xx
df.BirthYear=1900+df.BirthYear
#list of day names
weekday=['Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday']
#Identify day name in input df
days_ex=[s.split()[1].title() for s in df.Day]
#initialize output list
dateout= ["" for x in range(len(days_ex))]
for j in range(len(days_ex)):
#Identify the day number in the week (Monday is 1, Sunday is 7)
daynum=np.nonzero(np.char.rfind(weekday,days_ex[j])==0)[0][0]
#create start and end date for the month
date_start=date(df.BirthYear[j],df.BirthMonth[j],1)
date_end=date_start+relativedelta(months=+1)
#daily index range within month of interest
idx=pd.date_range(date_start,date_end,freq='d').dayofweek
# Find matching date based on input df
realday=np.where(idx==daynum)[0][int(df.Day[j][0])-1]+1
#output list
dateout[j]=str(realday)+'/'+str(df.BirthMonth[j])+'/'+str(df.BirthYear[j])
the result i got is:
['2/5/1988', '20/10/1987', '12/12/1987', '5/1/1988', '1/2/1988']
Related
I have a column with the weekday, another with the month and another with the year. How do I get the actual date in python?
import pandas as pd
df = pd.DataFrame({"year": [2018], "month": [12], "day": [1]})
df["date"] = pd.to_datetime(df[["year", "month", "day"]]).dt.date
print(df)
# year month day date
# 0 2018 12 1 2018-12-01
You can use the datetime library:
import datetime
x = datetime.datetime(year, month, day)
print(x)
Documentation: https://docs.python.org/3/library/datetime.html
from datetime import date
print(date.today())
This should work!
Using Python...
How can I select all of the Sundays (or any day for that matter) in a year?
[ '01/03/2010','01/10/2010','01/17/2010','01/24/2010', ...]
These dates represent the Sundays for 2010. This could also apply to any day of the week I suppose.
You can use date from the datetime module to find the first Sunday in a year and then keep adding seven days, generating new Sundays:
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)
Pandas has great functionality for this purpose with its date_range() function.
The result is a pandas DatetimeIndex, but can be converted to a list easily.
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']
Using the dateutil module, you could generate the list this way:
#!/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)
Although finding all Sundays is not too hard to do without dateutil, the module is handy especially if you have more complicated or varied date calculations.
If you are using Debian/Ubuntu, dateutil is provided by the python-dateutil package.
from datetime import date, timedelta
from typing import List
def find_sundays_between(start: date, end: date) -> List[date]:
total_days: int = (end - start).days + 1
sunday: int = 6
all_days = [start + timedelta(days=day) for day in range(total_days)]
return [day for day in all_days if day.weekday() is sunday]
date_start: date = date(2018, 1, 1)
date_end: date = date(2018, 12, 31)
sundays = find_sundays_between(date_start, date_end)
If looking for a more general approach (ie not only Sundays), we can build on sth's answer:
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
This will translate the name of the day into an int.
Then do:
from datetime import date, timedelta
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)
Note the presence of % 7 in alldays(). This outputs:
2020-01-05
2020-01-12
2020-01-19
2020-01-26
2020-02-02
2020-02-09
2020-02-16
...
Can also do:
for d in alldays(2020,'Friday'):
print(d)
which will give you:
2020-01-03
2020-01-10
2020-01-17
2020-01-24
2020-01-31
2020-02-07
2020-02-14
...
You can iterate over a calendar for that year.
The below should return all Tuesdays and Thursdays for a given year.
# 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)
import time
from datetime import timedelta, datetime
first_date = '2021-01-01'
final_date = '2021-12-31'
first_date = datetime.strptime(first_date, '%Y-%m-%d')
last_date = datetime.strptime(final_date, '%Y-%m-%d')
week_day = 'Sunday'
dates = [first_date + timedelta(days=x) for x in range((last_date - first_date).days + 1) if (first_date + timedelta(days=x)).weekday() == time.strptime(week_day, '%A').tm_wday]
It will return all Sunday date of given date range.
Here's a complete generator function that builds on the solution from #sth. It includes the crucial fix that was mentioned in his solution's comments.
You can specify the day of week (using Python's indexing with 0=Monday to 6=Sunday), the starting date, and the number of weeks to enumerate.
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
Example usage to get all Wednesdays starting on January 1, 2018, for 10 weeks.
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)
The above code produces:
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
according to #sth answer I like to give you an alternative without a function
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
if you want every monday for example
#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())
according to #sth answer,it will lost the day when 1st is sunday.This will be better:
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)
I have a column in df that contains numerical values that correlate to the customers hour of week for that row. For example 0 = Sunday 12:00am and 24 would be Monday 12:00am and 5 would be Sunday 5:00am.
Value
0
4
10
24
Value Expected Output Column
0 Sunday 12:00am
4 Sunday 4:00am
10 Sunday 10:00am
24 Monday 12:00am
49 Tuesday 1:00am
How can I create the new column if I want all values to assign to a correct corresponding Day and time for the week? Values start at 0 which would represent Sunday 12:00am first value of week and would end at 167 which would be Saturday 11:59pm of that week.
Thanks!
This does what you want:
Value = pd.Series([0, 4, 10, 24, 49])
AnyGivenSunday = pd.to_datetime('Sunday 2020') # yes this works
(AnyGivenSunday + pd.to_timedelta(Value, 'h')).dt.strftime('%A %I:%M%P')
import pandas as pd
from datetime import datetime
import calendar as cal
df = pd.DataFrame(data={'val': [0, 0, 0, 0, 0], 'date': ["Sunday 12:00am", "Sunday 4:00am", "Sunday 10:00am", "Monday 12:00am", "Tuesday 1:00am"]})
def convertDate(dateString):
hour = datetime.strptime(dateString, '%A %I:%M%p').hour # Convert to 24 hour format
day, time = dateString.split(" ") # Get text of day, cannot get datetime.weekday() without full date
if day.lower() == cal.day_name[6].lower(): # cal.day_name index starts at Monday and not Sunday
return hour + ((list(cal.day_name).index(day) - 6) * 24)
else:
return hour + ((list(cal.day_name).index(day) + 1) * 24)
df['val'] = df['date'].apply(convertDate) # Apply function to all columns
I have a DataFrame which is indexed with the last day of the month. Sometimes this date is a weekday and sometimes it is a weekend. Ignoring holidays, I'm looking to offset the date to the next business date if the date is on a weekend and leave the result unchanged if it is already on a weekday.
Some example data would be
import pandas as pd
idx = [pd.to_datetime('20150430'), pd.to_datetime('20150531'),
pd.to_datetime('20150630')]
df = pd.DataFrame(0, index=idx, columns=['A'])
df
A
2015-04-30 0
2015-05-31 0
2015-06-30 0
df.index.weekday
array([3, 6, 1], dtype=int32)
Something like the following works, however I would appreciate if someone has a solution that is a little more straightforward.
idx = df.index.copy()
wknds = (idx.weekday == 5) | (idx.weekday == 6)
idx2 = idx[~wknds]
idx2 = idx2.append(idx[wknds] + pd.datetools.BDay(1))
idx2 = idx2.order()
df.index = idx2
df
A
2015-04-30 0
2015-06-01 0
2015-06-30 0
You can add 0*BDay()
from pandas.tseries.offsets import BDay
df.index = df.index.map(lambda x : x + 0*BDay())
You can also use this with a Holiday calendar with CDay(calendar) in case there are holidays.
You can map the index with a lambda function, and set the result back to the index.
df.index = df.index.map(lambda x: x if x.dayofweek < 5 else x + pd.DateOffset(7-x.dayofweek))
df
A
2015-04-30 0
2015-06-01 0
2015-06-30 0
Using DataFrame.resample
A more idiomatic method would be to resample to business days:
df.resample('B', label='right', closed='right').first().dropna()
A
2015-04-30 0.0
2015-06-01 0.0
2015-06-30 0.0
Can also use a variation of the logic: a)given input date = 'inputdate', go back one business day using pandas date_range which has business days input; then b) go forward one business day using the same. To do this, you generate a vector with 2 inputs using data_range and select the min or max value to return the appropriate single value. So this could look as follows:
a) get business day before:
date_1b_bef = min(pd.date_range(start=inputdate, periods = 2, freq='-1B'))
b) get business day after the 'business day before':
date_1b_aft = max(pd.date_range(start=date_1b_bef, periods = 2, freq='1B'))
or substituting a) into b) to get one line:
date_1b_aft = max(pd.date_range(start=min(pd.date_range(start=inputdate, periods = 2, freq='-1B')), periods = 2, freq='1B'))
This can also be used with relativedelta to get the business day after some calendar period offset from inputdate. For example:
a) get the business day (using 'following' convention if offset day is not a business day) for 1 calendar month prior to 'input date':
date_1mbef_fol = max(pd.date_range(min(pd.date_range(start=inputdate + relativedelta(months=-1), periods = 2, freq='-1B')), periods = 2, freq = '1B'))
b) get the business day (using 'preceding' convention if offset day is not a business day) for 1 year prior to 'input date':
date_1ybef_pre = min(pd.date_range(max(pd.date_range(start=inputdate + relativedelta(years=-1), periods = 2, freq='1B')), periods = 2, freq = '-1B'))
Using Python...
How can I select all of the Sundays (or any day for that matter) in a year?
[ '01/03/2010','01/10/2010','01/17/2010','01/24/2010', ...]
These dates represent the Sundays for 2010. This could also apply to any day of the week I suppose.
You can use date from the datetime module to find the first Sunday in a year and then keep adding seven days, generating new Sundays:
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)
Pandas has great functionality for this purpose with its date_range() function.
The result is a pandas DatetimeIndex, but can be converted to a list easily.
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']
Using the dateutil module, you could generate the list this way:
#!/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)
Although finding all Sundays is not too hard to do without dateutil, the module is handy especially if you have more complicated or varied date calculations.
If you are using Debian/Ubuntu, dateutil is provided by the python-dateutil package.
from datetime import date, timedelta
from typing import List
def find_sundays_between(start: date, end: date) -> List[date]:
total_days: int = (end - start).days + 1
sunday: int = 6
all_days = [start + timedelta(days=day) for day in range(total_days)]
return [day for day in all_days if day.weekday() is sunday]
date_start: date = date(2018, 1, 1)
date_end: date = date(2018, 12, 31)
sundays = find_sundays_between(date_start, date_end)
If looking for a more general approach (ie not only Sundays), we can build on sth's answer:
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
This will translate the name of the day into an int.
Then do:
from datetime import date, timedelta
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)
Note the presence of % 7 in alldays(). This outputs:
2020-01-05
2020-01-12
2020-01-19
2020-01-26
2020-02-02
2020-02-09
2020-02-16
...
Can also do:
for d in alldays(2020,'Friday'):
print(d)
which will give you:
2020-01-03
2020-01-10
2020-01-17
2020-01-24
2020-01-31
2020-02-07
2020-02-14
...
You can iterate over a calendar for that year.
The below should return all Tuesdays and Thursdays for a given year.
# 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)
import time
from datetime import timedelta, datetime
first_date = '2021-01-01'
final_date = '2021-12-31'
first_date = datetime.strptime(first_date, '%Y-%m-%d')
last_date = datetime.strptime(final_date, '%Y-%m-%d')
week_day = 'Sunday'
dates = [first_date + timedelta(days=x) for x in range((last_date - first_date).days + 1) if (first_date + timedelta(days=x)).weekday() == time.strptime(week_day, '%A').tm_wday]
It will return all Sunday date of given date range.
Here's a complete generator function that builds on the solution from #sth. It includes the crucial fix that was mentioned in his solution's comments.
You can specify the day of week (using Python's indexing with 0=Monday to 6=Sunday), the starting date, and the number of weeks to enumerate.
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
Example usage to get all Wednesdays starting on January 1, 2018, for 10 weeks.
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)
The above code produces:
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
according to #sth answer I like to give you an alternative without a function
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
if you want every monday for example
#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())
according to #sth answer,it will lost the day when 1st is sunday.This will be better:
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)