This question already has answers here:
how to calculate 38 days from next month starting in Python
(4 answers)
Closed 1 year ago.
let us consider date as
invoice.created_at = datetime.date(2021, 11, 17)
next_month_first_date here is getting the nextmonth first date
next_month_first_date = (invoice.created_at.replace(day=1) + datetime.timedelta(days=32)).replace(day=1)
# datetime.date(2021, 12, 1)
Now I need last day of invoice.created_at month
this_month_last_day = ?
how to find last date of invoice.created_at month i.e 30/11/2021 and calculate 38 days from this_month_last_day? 38 days from this_month_last_day is 7/01/2022
Since you already have the 1st day of the next month you can simply subtract 1 day from this to get the last day of the current month:
this_month_last_day = next_month_first_date - datetime.timedelta(days=1)
>>> this_month_last_day + datetime.timedelta(days=38)
datetime.date(2022, 1, 7)
You can use Python's calender module to get the last day of the month
import calendar
import datetime
created_at = datetime.date(2021, 11, 17)
last_day_as_int = calendar.monthrange(created_at.year, created_at.month)[1] # 30
last_day_as_date = created_at.replace(day=last_day_as_int) # datetime.date(2021, 11, 30)
target_date = last_day_as_date + datetime.timedelta(days=38) # datetime.date(2022, 1, 7)
I need to calculate a price based on a given date weekdays a month.
This is what im currently working with:
month = time.month
year = time.year
weekdays = 0
cal = calendar.Calendar()
for day in cal.itermonthdates(year, month):
if day.weekday() == 6 and day.month == month:
weekdays += 1
But this does not rely on a given date.
I want this to return 6 for the date 10.01.2020, or 6 for 03.01.2020 or 4 for 06.01.2020.
Any help would be very nice.
Following can be a dry approach:
import datetime
# ...
prev_day = time.day - datetime.timedelta(days=1)
month = time.month
year = time.year
cal = calendar.Calendar()
days_iterator = cal.itermonthdates(year, month)
while next(days_iterator) != prev_day:
pass
weekdays = 0
for d in days_iterator:
if d.weekday() == 6 and d.month == month:
weekdays += 1
Try this:
import datetime
d=datetime.date(2020, 1, 10) #Format YYYY, MM, DD
print(d.isoweekday())
Now this will print 5 not 6 as it is a Friday and the counting starts at Monday (using isoweekday instead of weekday will let the counting start by 1 instead of 0) but there should be an easy fix if you want your week begin on Sunday just add 1 and calculate modulo 7:
print((d.isoweekday()+1)%7)
https://docs.python.org/3/library/datetime.html
This question already has answers here:
How do I get the day of week given a date?
(30 answers)
Closed 4 years ago.
Given a 4 digit year, return the number of the day on which January 1st falls. 0 is Sunday, …, 6 is Saturday
You can use the datetime library
import datetime
d = datetime.date(year, 1, 1)
weekday = d.isoweekday() % 7
The datetime library starts all weeks on Monday, so you need to do a bit of a conversion to get Sunday to be 0
How would one go about finding the date of the next Saturday in Python? Preferably using datetime and in the format '2013-05-25'?
>>> from datetime import datetime, timedelta
>>> d = datetime.strptime('2013-05-27', '%Y-%m-%d') # Monday
>>> t = timedelta((12 - d.weekday()) % 7)
>>> d + t
datetime.datetime(2013, 6, 1, 0, 0)
>>> (d + t).strftime('%Y-%m-%d')
'2013-06-01'
I use (12 - d.weekday()) % 7 to compute the delta in days between given day and next Saturday because weekday is between 0 (Monday) and 6 (Sunday), so Saturday is 5. But:
5 and 12 are the same modulo 7 (yes, we have 7 days in a week :-) )
so 12 - d.weekday() is between 6 and 12 where 5 - d.weekday() would be between 5 and -1
so this allows me not to handle the negative case (-1 for Sunday).
Here is a very simple version (no check) for any weekday:
>>> def get_next_weekday(startdate, weekday):
"""
#startdate: given date, in format '2013-05-25'
#weekday: week day as a integer, between 0 (Monday) to 6 (Sunday)
"""
d = datetime.strptime(startdate, '%Y-%m-%d')
t = timedelta((7 + weekday - d.weekday()) % 7)
return (d + t).strftime('%Y-%m-%d')
>>> get_next_weekday('2013-05-27', 5) # 5 = Saturday
'2013-06-01'
I found this pendulum pretty useful. Just one line
In [4]: pendulum.now().next(pendulum.SATURDAY).strftime('%Y-%m-%d')
Out[4]: '2019-04-27'
See below for more details:
In [1]: import pendulum
In [2]: pendulum.now()
Out[2]: DateTime(2019, 4, 24, 17, 28, 13, 776007, tzinfo=Timezone('America/Los_Angeles'))
In [3]: pendulum.now().next(pendulum.SATURDAY)
Out[3]: DateTime(2019, 4, 27, 0, 0, 0, tzinfo=Timezone('America/Los_Angeles'))
In [4]: pendulum.now().next(pendulum.SATURDAY).strftime('%Y-%m-%d')
Out[4]: '2019-04-27'
You need two main packages,
import datetime
import calendar
Once you have those, you can simply get the desired date for the week by the following code,
today = datetime.date.today() #reference point.
saturday = today + datetime.timedelta((calendar.SATURDAY-today.weekday()) % 7 )
saturday
Bonus
Following the content, if you type
saturday.weekday()
It will result 5.
Therefore, you can also use 5 in place of calendar.SATURDAY and you will get same result.
saturday = today + datetime.timedelta((5-today.weekday()) % 7 )
if you just want the date from today (inspired from Emanuelle )
def get_next_weekday(weekday_number):
"""
#weekday: week day as a integer, between 0 (Monday) to 6 (Sunday)
"""
assert 0 <= weekday_number <= 6
today_date = datetime.today()
next_week_day = timedelta((7 + weekday_number - today_date.weekday()) % 7)
return (today_date + next_week_day).strftime('%d/%m/%Y')
Again, based on Emmanuel's example, but making 0-6 conform to your week:
ScheduleShift = -1 # make Saturday end of week
EndofWeekDay = lambda do : do + datetime.timedelta( ( ScheduleShift + (13 - do.weekday() ) %7 ) )
Which can be called with:
EndofWeekDay( datetime.date.today() )
returning a datetime.date object
Just wanted to share a code. With this, you will get a list of dates when Saturday days will be in the next 10 days.
from datetime import datetime, timedelta
target_day = 'Saturday'
now_ = datetime.today().date()
how_many_days = 10
next_date = [now_ + timedelta(days=x) for x in range(how_many_days) if (now_ + timedelta(days=x)).strftime("%A") == target_day]
print(next_date)
Given a particular date, say 2011-07-02, how can I find the date of the next Monday (or any weekday day for that matter) after that date?
import datetime
def next_weekday(d, weekday):
days_ahead = weekday - d.weekday()
if days_ahead <= 0: # Target day already happened this week
days_ahead += 7
return d + datetime.timedelta(days_ahead)
d = datetime.date(2011, 7, 2)
next_monday = next_weekday(d, 0) # 0 = Monday, 1=Tuesday, 2=Wednesday...
print(next_monday)
Here's a succinct and generic alternative to the slightly weighty answers above.
def onDay(date, day):
"""
Returns the date of the next given weekday after
the given date. For example, the date of next Monday.
NB: if it IS the day we're looking for, this returns 0.
consider then doing onDay(foo, day + 1).
"""
days = (day - date.weekday() + 7) % 7
return date + datetime.timedelta(days=days)
Try
>>> dt = datetime(2011, 7, 2)
>>> dt + timedelta(days=(7 - dt.weekday()))
datetime.datetime(2011, 7, 4, 0, 0)
using, that the next monday is 7 days after the a monday, 6 days after a tuesday, and so on, and also using, that Python's datetime type reports monday as 0, ..., sunday as 6.
This is example of calculations within ring mod 7.
import datetime
def next_day(given_date, weekday):
day_shift = (weekday - given_date.weekday()) % 7
return given_date + datetime.timedelta(days=day_shift)
now = datetime.date(2018, 4, 15) # sunday
names = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday',
'saturday', 'sunday']
for weekday in range(7):
print(names[weekday], next_day(now, weekday))
will print:
monday 2018-04-16
tuesday 2018-04-17
wednesday 2018-04-18
thursday 2018-04-19
friday 2018-04-20
saturday 2018-04-21
sunday 2018-04-15
As you see it's correctly give you next monday, tuesday, wednesday, thursday friday and saturday. And it also understood that 2018-04-15 is a sunday and returned current sunday instead of next one.
I'm sure you'll find this answer extremely helpful after 7 years ;-)
Another alternative uses rrule
from dateutil.rrule import rrule, WEEKLY, MO
from datetime import date
next_monday = rrule(freq=WEEKLY, dtstart=date.today(), byweekday=MO, count=1)[0]
rrule docs: https://dateutil.readthedocs.io/en/stable/rrule.html
Another simple elegant solution is to use pandas offsets.
I find it very helpful and robust when playing with dates.
If you want the first Sunday just modify the frequency to freq='W-SUN'.
If you want a couple of next Sundays, change the offsets.Day(days).
Using pandas offsets allow you to ignore holidays, work only with Business Days and more.
You can also apply this method easily on a whole DataFrame using the apply method.
import pandas as pd
import datetime
# 1. Getting the closest monday from a given date
date = datetime.date(2011, 7, 2)
closest_monday = pd.date_range(start=date, end=date + pd.offsets.Day(6), freq="W-MON")[
0
]
# 2. Adding a 'ClosestMonday' column with the closest monday for each row in
# a pandas df using apply. Requires you to have a 'Date' column in your df
def get_closest_monday(row):
return pd.date_range(
start=row.Date, end=row.Date + pd.offsets.Day(6), freq="W-MON"
)[0]
df = pd.DataFrame([datetime.date(2011, 7, 2)], columns=["Date"])
df["ClosestMonday"] = df.apply(lambda row: get_closest_monday(row), axis=1)
print(df)
You can start adding one day to date object and stop when it's monday.
>>> d = datetime.date(2011, 7, 2)
>>> while d.weekday() != 0: #0 for monday
... d += datetime.timedelta(days=1)
...
>>> d
datetime.date(2011, 7, 4)
import datetime
d = datetime.date(2011, 7, 2)
while d.weekday() != 0:
d += datetime.timedelta(1)
dateutil has a special feature for this kind of operation and it's the most elegant way I have ever seen yet.
from datetime import datetime
from dateutil.relativedelta import relativedelta, MO
first_monday_date = (datetime(2011,7,2) + relativedelta(weekday=MO(0))).date()
if you want datetime just
first_monday_date = datetime(2011,7,2) + relativedelta(weekday=MO(0))
weekday = 0 ## Monday
dt = datetime.datetime.now().replace(hour=0, minute=0, second=0) ## or any specific date
days_remaining = (weekday - dt.weekday() - 1) % 7 + 1
next_dt = dt + datetime.timedelta(days_remaining)
Generally to find any date from day of week from today:
def getDateFromDayOfWeek(dayOfWeek):
week_days = ["monday", "tuesday", "wednesday",
"thursday", "friday", "saturday", "sunday"]
today = datetime.datetime.today().weekday()
requiredDay = week_days.index(dayOfWeek)
if today>requiredDay:
noOfDays=7-(today-requiredDay)
print("noDays",noOfDays)
else:
noOfDays = requiredDay-today
print("noDays",noOfDays)
requiredDate = datetime.datetime.today()+datetime.timedelta(days=noOfDays)
return requiredDate
print(getDateFromDayOfWeek('sunday').strftime("%d/%m/%y"))
Gives output in format of Day/Month/Year
This will give the first next Monday after given date:
import datetime
def get_next_monday(year, month, day):
date0 = datetime.date(year, month, day)
next_monday = date0 + datetime.timedelta(7 - date0.weekday() or 7)
return next_monday
print get_next_monday(2011, 7, 2)
print get_next_monday(2015, 8, 31)
print get_next_monday(2015, 9, 1)
2011-07-04
2015-09-07
2015-09-07
via list comprehension?
from datetime import *
[datetime.today()+timedelta(days=x) for x in range(0,7) if (datetime.today()+timedelta(days=x)).weekday() % 7 == 0]
(0 at the end is for next monday, returns current date when run on monday)