Date differences in Python in Years and Days (No Months) - python

I have two dates: 2005/04/10 and 2018/02/11.
The following code calculates the difference in terms of years, months and days:
from datetime import datetime
from dateutil.relativedelta import relativedelta
start_date = datetime(2005,4,10)
end_date = datetime(2018,2,11)
difference = relativedelta(end_date, start_date)
print(difference.years)
print(difference.months)
print(difference.days)
The output is:
12
10
1
12 years, 10 months and 1 day. The problem is that I am not interested in months I only want it in years and days. In my example, it should be 12 years and 306 days. I know that a good approximation is 10 months*30=300 days but the result is 301, not 306. I want to calculate precisely the days taking into account leap months and the difference in a number of days for each month. Is there any built-in method in Python to do that?
Look I already did my research on StackOverflow to find an answer but all the one related to my question do not answer to my problem.

After the code you already wrote, do this:
mid_date = datetime(start_date.year + difference.years, start_date.month, start_date.day)
print((end_date - mid_date).days)
That gives 307 for your example input.
The idea is to offset the original start_date by difference.years to avoid double-counting that portion of the difference.

Thanks to John's comment I wrote this code that I think satisfies my request:
from datetime import datetime
from dateutil.relativedelta import relativedelta
start_date = datetime(2005,4,10)
end_date = datetime(2018,2,11)
difference = relativedelta(end_date, start_date)
remaining_days = 0
if start_date != datetime(start_date.year, 1, 1):
end_first_year = datetime(start_date.year, 12, 31)
remaining_days += (end_first_year - start_date).days
if end_date != datetime(start_date.year, 1, 1):
begin_last_year = datetime(end_date.year, 1, 1)
remaining_days += (end_date - begin_last_year).days
print(difference.years)
print(remaining_days)
This gives exactly 306 remaining days.
Can anyone suggest a less verbose snippet of code?

Related

Determine a date starting from two integer numbers

Determine a date (as day, month, year) starting from two integer numbers that represent the year and the number of the day in that year.
i'm new to coding and I don't know where to start even.
If I understand correctly you can use Python datetime module to do what you need:
from datetime import datetime
print(datetime.strptime("2004-68", "%Y-%j").strftime("%d.%m.%Y"))
Result:
08.03.2004
You can start with creating algorithm in your head, or on paper.
Then you can translate it to python code.
or
you can read documentation about datetime lib in python and try to combine functions to you desired output. https://docs.python.org/3/library/datetime.html
For example:
from datetime import datetime, timedelta
year = 2004
days = 68
date = datetime(year, 1, 1) + timedelta(days=days-1)
# days-1 is needed because we already start with first day in year
print(date)
# 2004-03-08 00:00:00
year=int(input("year="))
days=int(input("number of days="))
day=int
month = days/28 + 1
m = int(month)
if ((year % 400 == 0) or
(year % 100 != 0) and
(year % 4 == 0)) :
day = days % 30
else:
day = days % 30 + 1
print(day,".", m, ".",year)
is this any good? or more preciseley is it corect? like i need this more basic aproach to the problem

python get same day last year

how to get same day last year in python
I tried datetime.datetime.now() - relativedelta(years=1) but this doesn't produce the result I'm looking.
Can anyone help. Thanks
example:
20/08/2020 (Thursday) last year will be 22/08/2019 (Thursday)
The answer from Pranav Hosangadi here is very nice, but please note that not every year has 52 weeks! It may be also 53, if you follow the
ISO8601 week numbering standard.
Number of ISO weeks in a year may be get according to this Stack Overflow thread, resulting in you code:
print(datetime.datetime.now())
2020-08-20 22:57:28.061648
def lastweeknumberoflastyear():
return datetime.date(datetime.datetime.now().year-1, 12, 28).isocalendar()[1]
print(datetime.datetime.now() - datetime.timedelta(weeks=lastweeknumberoflastyear()))
2019-08-22 22:57:28.061785
You want the same day of week one year ago. A year has 52 weeks
print(datetime.datetime.now())
2020-08-20 17:56:56.397626
print(datetime.datetime.now() - datetime.timedelta(weeks=52))
2019-08-22 17:56:56.397626
You can do something like:
now = datetime.datetime.now()
last_year = now.replace(now.year - 1)
Note that this will not account for leap years. If you want to find a date exactly 365 days prior, you would instead do something like:
now = datetime.datetime.now()
last_year = now - datetime.timedelta(days=365)
I'd probably do it like this, as a year is not always 365 days.
from datetime import datetime
x = datetime.now()
last_year = datetime(x.year-1,x.month,x.day,x.hour,x.minute,x.second,x.microsecond)
Let's say you want to look at today's date and then get the same date but last year:
today = datetime.date.today()
previous_year = today.year -1
today_last_year = today.replace(year = previous_year)

How do I calculate year fraction from datetime objects in Python?

I have two dates expressed as datetime objects and trying to calculate the time between the two dates in fractions of years (equivalent to the Excel yearfrac function).
Using relativedelta I can get the number of years, number of months and number of days between the dates, but not the fraction of years, and I can also subtract the dates to get the number of days, but dividing by 365.25 doesn't seem to get me the answer I would expect.
start_date = dt.datetime(2010, 12, 31)
end_date = dt.datetime(2019, 5, 16);
delta = relativedelta(end_date, start_date);
print(delta)
This is the output I get:
relativedelta(years=+8, months=+4, days=+16)
What I am looking for is: 8.38
If I use the following code:
delta = (end_date - start_date)/365.25
print(delta)
I get output of:
8 days, 8:56:10.841889
I just did the math of 8 + ((months * 30) + days)/365 = 8.3726. This is assuming 30 days in all months and 365 days in a year. Less precise but can fit on one line. What do you get when you divide by the number 365.25 that makes it wrong? How precise does it have to be?
If you need absolute precision, I would simply do:
from datetime import date
d0 = date(2010, 12, 31)
d1 = date(2019, 5, 16)
delta = d1 - d0
delta_fraction = delta.days/365.25
print(delta_fraction)
# Output: 8.72348
EDIT
This is a simplified solution assuming 365.25 days in a year (you can use 365.2425 days to be accurate up to the 400 year exception) to account for leap years. If you require it to match exactly excel's output, your probably better off writing a vba macro for excel
One thing to remember is that datetime.datetime objects have the subtraction operator defined, returning a datetime.timedelta object. And datetime.timedelta objects have the division operator defined, so you can get a ratio between a timedelta and either a common year (365 days) or the average length of all common and leap years (365 days, 5 hours, 49 minutes and 12 seconds).
import datetime as dt
start_date = dt.datetime(2010, 12, 31)
end_date = dt.datetime(2019, 5, 16)
print(round((end_date-start_date)/dt.timedelta(365,0,0,0),2)) #8.38
print(round((end_date-start_date)/dt.timedelta(365,5,49,12),2)) #8.38

Calculating the date a fixed number of days from given date [duplicate]

This question already has answers here:
Days between two dates? [duplicate]
(4 answers)
Closed 5 years ago.
I need to design a code that will automatically generate the date X number of days from current date.
For that, I currently have a function that returns an epoch timestamp, which I then add the fixed number of days in seconds. However, I am currently stuck there and do not know how to convert the epoch timestamp into a Gregorian calendar date format (DD/MM/YYYY HH:MM). Displaying time is optional, can be rounded to the nearest day.
A way to do this without using an epoch timestamp and directly getting the current date in a readable format, printing it, and adding X days to it before generating the second date, is also fine, but I have no idea how that would work.
Any help/input would be much appreciated. Thanks in advance.
You can use timedelta.
import datetime as dt
x = 5 # Days offset.
now = dt.datetime.now()
>>> now + dt.timedelta(days=x)
datetime.datetime(2017, 12, 2, 21, 10, 19, 290884)
Or just using days:
today = dt.date.today()
>>> today + dt.timedelta(days=x)
datetime.date(2017, 12, 2)
Easy enough to convert back to a string using strftime:
>>> (today + dt.timedelta(days=x)).strftime('%Y-%m-%d')
'2017-12-02'
import datetime
x = 5
'''
Date_Time = datetime.datetime.now()#It wil give Date & time both
Time = datetime.datetime.now().time()#It will give Time Only
'''
Date = datetime.datetime.now().date()#It will give date only
print(Date + datetime.timedelta(days=x))#It will add days to current date
Output:
2017-12-03

How to calculate months left to particular date? [duplicate]

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.

Categories

Resources