Get last day of week of a given date - python-3.x

Given any day of the year, such as today, I would have the last day of the current week.
For example, current day is 2021-12-27 (Monday), so the last day of this week is 2022-01-01 (Saturday), because of isoWeek in my systems starts from Sundays.
from datetime import datetime
dt = datetime.now()
print(dt) # 2021-12-27 12:57:57.004108
last_day_of_week = get_ldow(dt)
print(last_day_of_week) # 2022-01-01 00:00:00.000000
How get_ldow(df) could be implemented?

Import of datatime can be tricky.
import datetime
dt = datetime.datetime.today() # 2021-12-27 13:40:10.204296
def get_ldow(dt_input):
return dt_input + datetime.timedelta(days=(6 - dt_input.isoweekday() % 7))
last_day_of_week = get_ldow(dt)
print(last_day_of_week) # 2022-01-01 13:40:10.204296

Related

Python3 Get epoch time first and last day of month

Given a month and a year, such as 03 2022, I need to get the epoch time of the first day of the month and the last day of the month. I am not sure how to do that. Any help would be appreciated. Thank you.
You can get the beginning of the month easily by setting the day to 1.
To get the end of the month conveniently, you can calculate the first day of the next month, then go back one day.
Then set the time zone (tzinfo) to UTC to prevent Python using local time.
Finally a call to .timestamp()
import datetime
def date_to_endofmonth(
dt: datetime.datetime, offset: datetime.timedelta = datetime.timedelta(days=1)
) -> datetime.datetime:
"""
Roll a datetime to the end of the month.
Parameters
----------
dt : datetime.datetime
datetime object to use.
offset : datetime.timedelta, optional.
Offset to the next month. The default is 1 day; datetime.timedelta(days=1).
Returns
-------
datetime.datetime
End of month datetime.
"""
# reset day to first day of month, add one month and subtract offset duration
return (
datetime.datetime(
dt.year + ((dt.month + 1) // 12), ((dt.month + 1) % 12) or 12, 1
)
- offset
)
year, month = 2022, 11
# make datetime objects; make sure to set UTC
dt_month_begin = datetime.datetime(year, month, 1, tzinfo=datetime.timezone.utc)
dt_month_end = date_to_endofmonth(dt_month_begin).replace(tzinfo=datetime.timezone.utc)
ts_month_begin = dt_month_begin.timestamp()
ts_month_end = dt_month_end.timestamp()
print(ts_month_begin, ts_month_end)
# 1667260800.0 1701302400.0
Unable to comment due to reputation but #FObersteiner is excellent just I would recommend a small change.
For example running the current code it would produce this for Nov 2022
print(dt_month_begin.timestamp())
print(dt_month_begin)
print(dt_month_end.timestamp())
print(dt_month_end)
--->
1667260800.0
2022-11-01 00:00:00+00:00
1701302400.0
2023-11-30 00:00:00+00:00
Note the year field
I'd suggest the following
import datetime
def date_to_endofmonth(
dt: datetime.datetime, offset: datetime.timedelta = datetime.timedelta(seconds=1)
) -> datetime.datetime:
"""
Roll a datetime to the end of the month.
Parameters
----------
dt : datetime.datetime
datetime object to use.
offset : datetime.timedelta, optional.
Offset to the next month. The default is 1 second; datetime.timedelta(seconds=1).
Returns
-------
datetime.datetime
End of month datetime.
"""
# reset day to first day of month, add one month and subtract offset duration
return (
datetime.datetime(
dt.year + ((dt.month + 1) // 13), ((dt.month + 1) % 12) or 12, 1
)
- offset
)
year, month = 2022, 11
# make datetime objects; make sure to set UTC
dt_month_begin = datetime.datetime(year, month, 1, tzinfo=datetime.timezone.utc)
dt_month_end = date_to_endofmonth(dt_month_begin).replace(tzinfo=datetime.timezone.utc)
Differences being floor division by 13 instead of 12 to handle the month of November.
Changing the offset to seconds delta because I felt the user ( and myself who came looking for the answer) wanted the starting epoch time and the ending epoch time so
Nov 1st 00:00:00 --> Nov 30th 23:59:59 would be better than
Nov 1st 00:00:00 --> Nov 30th 00:00:00 ( Losing a day worth of seconds)
Output of the above would be
:
1667260800.0
2022-11-01 00:00:00+00:00
1669852799.0
2022-11-30 23:59:59+00:00

Python: Converting Standard Time to Military time

Write a program that prompts a user to enter time in a 12-hour format and converts it to a 24-hour format. Converting a 12-hour time to 24-hour time requires adding 12 hours to any time between 1:00PM-11:59PM and subtracting 12 hours from any time between 12:00AM-12:59AM. 24-hour time uses leading zeros for hours so that there are always 4 digits.
This is currently in one my labs that I am trying to finish up for the semester and I do not know how to finish it.
from datetime import datetime
def convert_24hrs():
txt = input('input the 12-hour format: ')
tim = datetime.strftime(f'2021-12-09 {txt}', '%Y-%m-%d %I:%M %p')
print(datetime.strptime(tim, '%H:%M'))
convert_24hrs()
# input the 12-hour format: 4:21 am
# 04:21
convert_24hrs()
# input the 12-hour format: 5:36 pm
# 17:36
Incase anyone want to have the hour or minutes as an integers you can use this concept.
import datetime
YEAR = datetime.date.today().year # the current year
MONTH = datetime.date.today().month # the current month
DATE = datetime.date.today().day # the current day
HOUR = datetime.datetime.now().hour # the current hour
MINUTE = datetime.datetime.now().minute # the current minute
SECONDS = datetime.datetime.now().second #the current second
print(YEAR, MONTH, DATE, HOUR, MINUTE, SECONDS)
So with the above understanding you can get the difference in hours.
Let's reproduce onyambu example:
from datetime import datetime
def convert_24hrs():
txt = input('input the 12-hour format: ')
tim = datetime.strptime(f'2021-12-09 {txt}', '%Y-%m-%d %I:%M %p')
print(f'{str(tim.hour)}:{str(tim.minute)}')
convert_24hrs()
# input the 12-hour format: 5:36 pm
# 17:36

Python - Calculate date difference in months

I need to get the difference between the days in months and days (eg. 3months 20days).
from datetime import datetime
from dateutil import relativedelta
date1 = datetime.strptime('2019-06-23', "%Y-%m-%d")
date2 = datetime.strptime('2018-04-17', '%Y-%m-%d')
r = relativedelta.relativedelta(date1, date2)
print(r)
This gives me result like relativedelta(years=+1, months=+2, days=+6) whereas I need result like 14 months 6 days
Thank you
Incorporate a minor modification to get the answer.
print(r.years, 'years,', r.months,'months and', r.days, 'days')

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'

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