How to get Monday and Sunday of last week - python-3.x

If today is November 28, 2021, I want to get last week's Monday and Sunday like:
Monday: 2021-11-15
Sunday: 2021-11-21
I tried like this:
today = datetime.date.today()
idx = (today.weekday() + 1) % 7
self.monday = (today - datetime.timedelta(7 + idx - 1)).strftime('%Y-%m-%d')
self.sunday = (today - datetime.timedelta(7 + idx - 7)).strftime('%Y-%m-%d')
But the output is like this, which is wrong:
Monday: 2021-11-22
Sunday: 2021-11-28
It is correct if today's date is November 29, 2021.
How will I be able to achieve this?

Take today's date and subtract 1 week plus today's weekday 'number':
today = datetime.date.today()
today - datetime.timedelta(days=today.weekday(), weeks=1)
For the Sunday before that, use days=today.weekday() + 1

Related

Need to get output of all weekdays starting from given date

Output is not how it should be
given_day = datetime.date(2022,10,31)
dates = given_day + datetime.timedelta(days=+1)
for i in range(0 - given_day.weekday(), 7 - given_day.weekday()):
print(given_day.strftime("%A"))
Output should start from Monday and end to Sunday
Output I get is:
Monday
Monday
Monday
Monday
Monday
Monday
Monday
Where i made a mistake :(
I can't make head or tail of your code, but the following works:
given_day = datetime.date(2022,10,31)
for i in range(0 + given_day.weekday(), 7):
print(given_day.strftime("%A"))
given_day += datetime.timedelta(days=1)

Get the first Friday of the Quarter of Today's Date

I was trying to get the first Friday of the quarter of today's date or any given date. Let's say the date is 12/06/2020, which falls to the 2nd quarter of the year. I should be able to get the first Friday of the 2nd Quarter and that should be April 3rd.
I was only been able to get the quarter of a given date, which you can see in the code below. Been stuck here for a while. Thanks in advance.
quarter = Int((Month(Now) + 2) / 3)
Here's a function that takes a date and returns the first Friday of the quarter:
Function FirstFridayOfTheQuarter(MyDate As Date) As Date
Dim FirstDayOfTheQuarter As Date
FirstDayOfTheQuarter = DateSerial(Year(MyDate), Int((Month(MyDate) - 1) / 3) * 3 + 1, 1)
FirstFridayOfTheQuarter = DateAdd("d", (13 - Weekday(FirstDayOfTheQuarter)) Mod 7, FirstDayOfTheQuarter)
End Function
This function is taking advantage of the Weekday function that returns:
1 for a Sunday
2 for a Monday
3 for a Tuesday
4 for a Wednesday
5 for a Thursday
6 for a Friday
7 for a Saturday
In case you want a non VBA solution:
My formula is:
=CEILING(EOMONTH(DATE(YEAR(A1);ROUNDUP(MONTH(A1)/3;0)+(ROUNDUP(MONTH(A1)/3;0)-1)*2;1);-1)-5;7)+6

find the last business date for June and Dec of any given year in Python

I want to find the last business day for the month of June and Dec for 2019. my below code gives me the last business day for last month and the current month. Ideally i want a code which allows me to input a year and month and it will tell me the last business day for the month and year i input.
i want my output to be like this for June 2019 and Dec 2019
2906
3112
hope someone can help me here, thanks
from pandas.tseries.offsets import BMonthEnd
from datetime import date
d=date.today()
offset = BMonthEnd()
#Last day of current month
current_month = offset.rollforward(d)
print(current_month)
#Last day of previous month
last_month = offset.rollback(d)
print(last_month)
Here's a function that will find the last weekday in a given month and format it as a string in the format given
import datetime
def last_weekday(year, month):
# Add a month
if month == 12:
month = 1
year += 1
else:
month += 1
d = datetime.date(year, month, 1)
# Subtract a day
d -= datetime.timedelta(days=1)
# Subtract more days if we have a weekend
while d.weekday() >= 5:
d -= datetime.timedelta(days=1)
return '{:02d}{:02d}'.format(d.month, d.day)
# Examples:
last_weekday(2019, 6) # -> '0628'
last_weekday(2019, 12) # -> '1231'

Pandas to recognize current date, and filter a date column relative to today's date

Having a lot of trouble translating the logic below in pandas/python, so I do not even have sample code or a df to work with :x
I run a daily report, that essentially filters for data from Monday thru the day before what 'Today' is. I have a Date column [ in dt.strftime('%#m/%#d/%Y') format] . It will never be longer than a Monday-Sunday scope.
1) Recognize the day it is 'today' when running the report, and recognize what day the closet Monday prior was. Filter the "Date" Column for the Monday-day before today's date [ in dt.strftime('%#m/%#d/%Y') format ]
2) Once the df is filtered for that, take this group of rows that have dates in the logic above, have it check for dates in a new column "Date2". If any dates are before the Monday Date, in Date2, change all of those earlier dates in 'Date2' to the Monday date it the 'Date' column.
3) If 'Today' is a Monday, then filter the scope from the Prior Monday through - Sunday in the "Date" Column. While this is filtered, do the step above [step 2] but also, for any dates in the "Date2" column that are Saturday and Sunday Dates - changes those to the Friday date.
Does this make sense?
Here're the steps:
from datetime import datetime
today = pd.to_datetime(datetime.now().date())
day_of_week = today.dayofweek
last_monday = today - pd.to_timedelta(day_of_week, unit='d')
# if today is Monday, we need to step back another week
if day_of_week == 0:
last_monday -= pd.to_timedelta(7, unit='d')
# filter for last Monday
last_monday_flags = (df.Date == last_mon)
# filter for Date2 < last Monday
date2_flags = (df.Date2 < last_monday)
# update where both flags are true
flags = last_monday_flags & date2_flags
df.loc[flags, 'Date2'] = last_monday
# if today is Monday
if day_of_week == 0:
last_sunday = last_monday + pd.to_timedelta(6, unit='d')
last_sat = last_sunday - pd.to_timedelta(1, unit='d')
last_week_flags = (df.Date >= last_monday) & (df.Date <= next_sunday)
last_sat_flags = (df.Date2 == last_sat)
last_sun_flags = (df.Date2 == last_sun)
# I'm just too lazy and not sure how Sat and Sun relates to Fri
# but i guess just subtract 1 day or 2 depending on which day
...

How do I know if today is a day due to change civil local time e.g. daylight saving time in standard python and pandas timestamps?

According to the rules of British Summer Time / daylight saving time (https://www.gov.uk/when-do-the-clocks-change) the clocks:
go forward 1 hour at 1am on the last Sunday in March,
go back 1 hour at 2am on the last Sunday in October.
In 2019 this civil local time change happens on March 31st and October 27th, but the days slightly change every year. Is there a clean way to know these dates for each input year?
I need to check these "changing time" dates in an automatic way, is there a way to avoid a for loop to check the details of each date to see if it is a "changing time" date?
At the moment I am exploring these dates for 2019 just to try to figure out a reproducible/automatic procedure and I found this:
# using datetime from the standard library
march_utc_30 = datetime.datetime(2019, 3, 30, 0, 0, 0, 0, tzinfo=datetime.timezone.utc)
march_utc_31 = datetime.datetime(2019, 3, 31, 0, 0, 0, 0, tzinfo=datetime.timezone.utc)
april_utc_1 = datetime.datetime(2019, 4, 1, 0, 0, 0, 0, tzinfo=datetime.timezone.utc)
# using pandas timestamps
pd_march_utc_30 = pd.Timestamp(march_utc_30) #, tz='UTC')
pd_march_utc_31 = pd.Timestamp(march_utc_31) #, tz='UTC')
pd_april_utc_1 = pd.Timestamp(april_utc_1) #, tz='UTC')
# using pandas wrappers
pd_local_march_utc_30 = pd_march_utc_30.tz_convert('Europe/London')
pd_local_march_utc_31 = pd_march_utc_31.tz_convert('Europe/London')
pd_local_april_utc_1 = pd_april_utc_1.tz_convert('Europe/London')
# then printing all these dates
print("march_utc_30 {} pd_march_utc_30 {} pd_local_march_utc_30 {}".format(march_utc_30, pd_march_utc_30, pd_local_march_utc_30))
print("march_utc_31 {} pd_march_utc_31 {} pd_local_march_utc_31 {}".format(march_utc_31, pd_march_utc_31, pd_local_march_utc_31))
print("april_utc_1 {} pd_april_utc_1 {} pd_local_april_utc_1 {}".format(april_utc_1, pd_april_utc_1, pd_local_april_utc_1))
The output of those print statements is:
march_utc_30 2019-03-30 00:00:00+00:00 pd_march_utc_30 2019-03-30 00:00:00+00:00 pd_local_march_utc_30 2019-03-30 00:00:00+00:00
march_utc_31 2019-03-31 00:00:00+00:00 pd_march_utc_31 2019-03-31 00:00:00+00:00 pd_local_march_utc_31 2019-03-31 00:00:00+00:00
april_utc_1 2019-04-01 00:00:00+00:00 pd_april_utc_1 2019-04-01 00:00:00+00:00 pd_local_april_utc_1 2019-04-01 01:00:00+01:00
I could use a for loop to find out if the current date is the last Sunday of the month, or compare the "hour delta" between the current date and the date of the day after to see if there is a +1, but I am wondering if there is a cleaner way to do this?
Is there something attached to the year e.g. knowing the input year is 2019 then we know for sure the "change date" in March will be day 31st?
Using dateutil.rrule can help (install with pip install python-dateutil).
Because we can fetch dates by weeks, we don't need any loops,
from dateutil.rrule import rrule, WEEKLY
from dateutil.rrule import SU as Sunday
from datetime import date
import datetime
def get_last_sunday(year, month):
date = datetime.datetime(year=year, month=month, day=1)
# we can find max 5 sundays in a months
days = rrule(freq=WEEKLY, dtstart=date, byweekday=Sunday, count=5)
# Check if last date is same month,
# If not this couple year/month only have 4 Sundays
if days[-1].month == month:
return days[-1]
else:
return days[-2]
def get_march_switch(year):
# Get 5 next Sundays from first March
day = get_last_sunday(year, 3)
return day.replace(hour=1, minute=0, second=0, microsecond=0)
def get_october_switch(year):
day = get_last_sunday(year, 10)
return day.replace(hour=2, minute=0, second=0, microsecond=0)
print('2019:')
print(' {}'.format(get_march_switch(2019)))
print(' {}'.format(get_october_switch(2019)))
print('2021:')
print(' {}'.format(get_march_switch(2021)))
print(' {}'.format(get_october_switch(2021)))
get_sundays() returns the 5 next sundays from the first day of the given month, because a month can have maximum 5 sundays.
Then I just check (within get_(march|october)_switch()) if the last given sunday is from the expected month, if not well this month only have 4 sunday, I took this one.
Finally I fix the hours, seconds and microseconds.
Output:
2019:
2019-03-31 01:00:00
2019-10-27 02:00:00
2021:
2021-03-28 01:00:00
2021-10-24 02:00:00
I know the topic is quite old now. However, I had the same question today, and at the end I found a solution which seems quite simple to me, using only the standard datetime:
I want to check whether my date refdate is the October DST day - I did it in the following way:
refdate is my standard datetime object.
If you have a panda timestamp, you can convert it to native datetime using .to_pydatetime()
if refdate.month == 10 and refdate.weekday() == 6 and (refdate + dt.timedelta(weeks = 1)).month == 11:
oct_dst = 1

Resources