If 17:00:00 today is already passed, then it should be today's date, otherwise - yesterday's.
Today's time I get with:
test = datetime.datetime.now().replace(hour=17,minute=0,second=0,microsecond=0)
But I don't want to have future time. How can I fix it?
You could check if the current time is less than 17:00, if so, substract one day from the generated time object:
test = datetime.datetime.now().replace(hour=17,minute=0,second=0,microsecond=0)
if datetime.datetime.now() < test:
test = test - datetime.timedelta(days=1)
Better use the datetime.time of today directly for comparing the times. Then use datetime.timedelta to do the math:
if datetime.datetime.now().time() > datetime.time(17,0):
# today, as it's after 17 o'clock
test = datetime.date.today()
else:
# yesterday, as it's before 17 o'clock
test = datetime.date.today() - datetime.timedelta(days=1)
set test as today or yesterday depending on the time of day:
from datetime import datetime, date, timedelta
if datetime.now().strftime('%H:%M') > '17:00':
test = date.today()
else:
test = date.today() - timedelta(days=1)
Pythons datetime functions are indeed quite unhandy sometimes. While you can use datetime.timedelta objects for your case, to substract times in days, e.g. upcounting month or years becomes annoying. So in case you sooner or later not only want to add one day, maybe give this function a try:
import datetime
import calendar
def upcount(dt, years=0, months=0, **kwargs):
"""
Python provides no consistent function to add time intervals
with years, months, days, minutes and seconds. Usage example:
upcount(dt, years=1, months=2, days=3, hours=4)
"""
if months:
total_months = dt.month + months
month_years, months = divmod(total_months, 12)
if months == 0:
month_years -= 1
months = 12
years += month_years
else:
months = dt.month
years = dt.year + years
try:
dt = dt.replace(year=years, month=months)
except ValueError:
# 31st march -> 31st april gives this error
max_day = calendar.monthrange(years, months)[1]
dt = dt.replace(year=years, month=months, day=max_day)
if kwargs:
dt += datetime.timedelta(**kwargs)
return dt
Related
I would like to know how many days are passed from a x ago to today
I wrote this:
from datetime import datetime
timestamp = 1629195530 # A month ago
before = datetime.fromtimestamp(timestamp)
daysBefore = before.strftime("%d")
now = datetime.now()
today = now.strftime("%d")
print(f"daysBefore {daysBefore} - today {today}")
daysPassed = int(today) - int(daysBefore)
But so it seems, daysBefore is returning the days of the month, I can't get my head around this :(
Exact format with date time hour minute accuracy
from datetime import datetime
timestamp = 1629195530 # A month ago
before = datetime.fromtimestamp(timestamp)
now = datetime.now()
print(now - before))
print(f"daysBefore {daysBefore} - today {today}")
The reason this doesn't work is that it gives the day of the month. For example 17th of July and 17th of August will give a difference of zero days.
Therefore the recommend method is as #abdul Niyas P M says, use the whole date.time format to subtract two dates and afterwards extract the days.
Your issue is due to this: strftime("%d")
You are converting you date to a string and then to an int to make the difference. You can just use the datetime to do this for you:
timestamp = 1629195530 # A month ago
before = datetime.fromtimestamp(timestamp)
now = datetime.now()
print(f"daysBefore {before} - today {now}")
daysPassed = now - before
print(daysPassed.days)
I have datetime.now() objects, and I want to know how many hours will pass before a specific hour the next day
I've tried this:
now = datetime.now()
then = datetime.now() + timedelta(days=1)
then.hour = 12 # doesn't work
hours = then - now
But I don't know how can I specify the exact hour for then object
I don't understand that you need. But you can try this
then = datetime.now() + timedelta(days=1, hours=12)
or this
then = datetime.now() + timedelta(days=1)
then.replace(hour=12)
If you need get diff in hour you should use
hours = (then - now).seconds // 3600
The timedelta object will give you the total number of seconds between two times. The below will give you the number of whole hours between then and now.
now = datetime.datetime.now()
then = datetime.datetime.now() + datetime.timedelta(days=1)
delta = then - now
hours = delta.total_seconds // 3600
If the problem is that you cannot specify particular hour for an existing datetime object, you can construct a future datetime object explicitly using some attributes from now:
from datetime import datetime
now = datetime.now()
then = datetime(year=now.year, month=now.month, day=now.day+1, hour=19)
This question already has answers here:
Best way to find the months between two dates
(41 answers)
Closed 8 years ago.
In my django app, I have some date.
I need to count how many months left to this date, using full (rounded) months.
eg: today is 19/02/2015 (february), my "search" date is 04/08/2015. Difference should be 6.
How can I get a proper value?
from datetime import datetime,timedelta
from calendar import monthrange
today = datetime.today()
dt = "04/08/2015"
fut = datetime.strptime(dt, "%d/%m/%Y")
diff = 0
while today <= fut:
today += timedelta(days=monthrange(today.day,today.month)[1])
diff += 1
print(diff)
6
Without importing calender we can increment a count everytime we see a new month:
from datetime import datetime,timedelta
today = datetime.today()
dt = "09/08/2015"
fut = datetime.strptime(dt, "%d/%m/%Y")
diff = 0
while today <= fut:
mon = today.month
today += timedelta(days=1)
if today.month != mon:
diff += 1
print(diff)
6
If you want to make the future day the last day of the month:
from datetime import datetime, timedelta
from calendar import monthrange
today = datetime.today()
dt = "02/08/2015"
fut = datetime.strptime(dt, "%d/%m/%Y")
fut = fut + timedelta(days=monthrange(fut.day,fut.month)[1]-fut.day)
diff = 0
while today < fut:
mon = today.month
today += timedelta(days=1)
if today.month != mon:
diff += 1
print(diff)
This is purposely inaccurate to allow for rounding as required, all we care about are the amount of different months we encounter.
I like the arrow library: http://crsmithdev.com/arrow/
eg.
d1 = arrow.get("19/02/2015", "DD/MM/YYYY")
d2 = arrow.get("04/08/2015", "DD/MM/YYYY")
(d2-d1).days
You are going to have decide how to do your calculation. Divide by 30 or extract the months and subtract those.
d2.month - d1.month
To handle it going over a year:
((d2.year * 100) + d2.month) - ((d1.year * 100) + d1.month)
To calculate the month difference (rounded) I would go this direction:
Get the date objects for the different dates (see datetime package). This is rather easy, since the constructor takes year, month, day
Calculate the difference between the dates "date2 - date1" this automatically gives a timedelta object
Get the difference seconds between the two dates by calling "total_seconds()" on the timedelta object
Dividing the number of seconds by 24*60*60 will give the number of days
Dividing the number of days by 30 or (as you like) 31 will give the number of months. You can round the value as you like.
This should suffice:
d,m,y = date1.split('/')
d1 = datetime.date(y, m, d)
d,m,y = date1.split('/')
d2 = datetime.date(y, m, d)
delta = d2 - d1
days = delta.total_seconds() // (24*60*60)
result = int(days/30.0+0.5)
The nice thing: No additional packages needed, all is in the standard packages.
I'd like to write a function which:
takes in parameter: a number of months (int)
returns the year (int) and the month (int) of the timedelta between now and the number of input months.
Example : we are in may 2014, so:
myfunc(0) should return (2014, 5)
myfunc(12) should return (2013, 5)
myfunc(5) should return (2013, 12)
etc.
There is lots of documentation about datetime and calendar, so much that I'm a bit lost. Thanks for help.
Note: I need to get an accurate way to do it, not an approximation :)
import datetime
def myfunc(num_of_months):
today = datetime.date.today()
num_of_months = today.year * 12 + today.month - 1 - num_of_months
year = num_of_months / 12
month = num_of_months % 12 + 1
return year, month
from time import strftime, localtime, time
from calendar import monthrange
def uberdate(n):
if n == 0: return strftime('%Y, %m').split(', ')
month = int(strftime('%m'))
aDay = 60*60*24
offset = aDay # One day to start off with
for i in range(0, n):
while int(strftime('%m', localtime(time()-offset))) == month:
offset = offset+aDay
month = int(strftime('%m', localtime(time()-offset)))
return strftime('%Y, %m', localtime(time()-offset)).split(', ')
print(uberdate(5))
This produces:
[torxed#archie ~]$ python test.py
[2013, 12]
Don't know why i got the downvote, but to quote OP:
Example : we are in may 2014, so:
myfunc(5) should return (2013, 12) etc.
And this is what my function produces...
Feedback people, give it before downvoting randomly.
You can use python-dateutil module for this. https://pypi.python.org/pypi/python-dateutil
def return_year_date(delta_month):
from datetime import date
from dateutil.relativedelta import relativedelta
new_date = date.today() + relativedelta(months= -delta_month)
return new_date.year, new_date.month
EDITED (Changed the month addition to make the accuracy perfect)
Now you can put negative number of months and get past dates
I think this is what youre looking for
import datetime
from dateutil.relativedelta import *
def calculate_date(number_months):
time_now = datetime.datetime.now() # Get now time
time_future = time_now + relativedelta(months=+number_months) # Add months
return time_future.year,time_future.month #Return year,month
I've tested this script in my coputer and works perfectly
>>> calculate_data(5)
(2014, 10)
i know using datetime.timedelta i can get the date of some days away form given date
daysafter = datetime.date.today() + datetime.timedelta(days=5)
but seems no datetime.timedelta(month=1)
Use dateutil module. It has relative time deltas:
import datetime
from dateutil import relativedelta
nextmonth = datetime.date.today() + relativedelta.relativedelta(months=1)
Beautiful.
Of course there isn't -- if today's January 31, what would be "the same day of the next month"?! Obviously there is no right solution, since February 31 does not exist, and the datetime module does not play at "guess what the user posing this impossible problem without a right solution thinks (wrongly) is the obvious solution";-).
I suggest:
try:
nextmonthdate = x.replace(month=x.month+1)
except ValueError:
if x.month == 12:
nextmonthdate = x.replace(year=x.year+1, month=1)
else:
# next month is too short to have "same date"
# pick your own heuristic, or re-raise the exception:
raise
You can use calendar.nextmonth (from Python 3.7).
>>> import calendar
>>> calendar.nextmonth(year=2019, month=6)
(2019, 7)
>>> calendar.nextmonth(year=2019, month=12)
(2020, 1)
But be aware that this function isn't meant to be public API, it's used internally in calendar.Calendar.itermonthdays3() method. That's why it doesn't check the given month value:
>>> calendar.nextmonth(year=2019, month=60)
(2019, 61)
In Python 3.8 is already implemented as internal function.
from calendar import mdays
from datetime import datetime, timedelta
today = datetime.now()
next_month_of_today = today + timedelta(mdays[today.month])
I don't want to import dateutil. Have a try this. Good luck.
import calendar, datetime
def next_month ( date ):
"""return a date one month in advance of 'date'.
If the next month has fewer days then the current date's month, this will return an
early date in the following month."""
return date + datetime.timedelta(days=calendar.monthrange(date.year,date.month)[1])
This work for me
import datetime
import calendar
def next_month_date(d):
_year = d.year+(d.month//12)
_month = 1 if (d.month//12) else d.month + 1
next_month_len = calendar.monthrange(_year,_month)[1]
next_month = d
if d.day > next_month_len:
next_month = next_month.replace(day=next_month_len)
next_month = next_month.replace(year=_year, month=_month)
return next_month
usage:
d = datetime.datetime.today()
print next_month_date(d)
This is how I solved it.
from datetime import datetime, timedelta
from calendar import monthrange
today_date = datetime.now().date() # 2021-10-29
year = today_date.year
month = today_date.month
days_in_month = monthrange(year, month)[1]
next_month = today_date + timedelta(days=days_in_month)
print(next_month) # 2021-11-29
Solution on Python3 without additional modules nor internal functions.
from datetime import date
today = date.today()
nextMonth = date(today.year+((today.month+1)//12) , ((today.month+1)%12), today.day)
Hurray for integer algebra!
from datetime import timedelta
try:
next_month = (x.replace(day=28) + timedelta(days=7)).replace(day=x.day)
except ValueError: # assuming January 31 should return last day of February.
next_month = (x + timedelta(days=31)).replace(day=1) - timedelta(days=1)
from dateutil.relativedelta import relativedelta
from dateutil import parser
d2 = "1/4/2022 8:39:23 AM"
NextMonth = parser.parse(d2) + relativedelta(months=+1) + relativedelta(days=-1)
print(NextMonth)
This is how I solved it.
from datetime import date
try:
(year, month) = divmod(date.today().month, 12)
next_month = date.today().replace(year=date.today().year+year, month=month+1)
except ValueError:
# This day does not exist in next month
You can skip the try/catch if you only want the first day in next month by setting replace(year=date.today().year+year, month=month, day=1). This will always be a valid date since we have caught the month overflow using divmod.
I often need to need to keep the date as last in month when adding months. I try to add the amount of months to the day after and then remove one day again. If that fails I add one more day until success.
from datetime import timedelta
DAY = timedelta(1)
def add_months(d, months):
"Add months to date and retain last day in month."
d += DAY
# calculate year diff and zero based month
y, m = divmod(d.month + months - 1, 12)
try:
return d.replace(d.year + y, m + 1) - DAY
except ValueError:
# on fail return last day in month
# can't fail on december so just adding one more month
return d.replace(d.year + y, m + 2, 1) - DAY
This Code Works for me:
NextMonth = self.CurruntMonth.replace(day=15) + datetime.timedelta(days=30)