Convert timedelta to years?
You need more than a timedelta
to tell how many years have passed; you also need to know the beginning (or ending) date. (It's a leap year thing.)
Your best bet is to use the dateutil.relativedelta
object, but that's a 3rd party module. If you want to know the datetime
that was n
years from some date (defaulting to right now), you can do the following::
from dateutil.relativedelta import relativedelta
def yearsago(years, from_date=None):
if from_date is None:
from_date = datetime.now()
return from_date - relativedelta(years=years)
If you'd rather stick with the standard library, the answer is a little more complex::
from datetime import datetime
def yearsago(years, from_date=None):
if from_date is None:
from_date = datetime.now()
try:
return from_date.replace(year=from_date.year - years)
except ValueError:
# Must be 2/29!
assert from_date.month == 2 and from_date.day == 29 # can be removed
return from_date.replace(month=2, day=28,
year=from_date.year-years)
If it's 2/29, and 18 years ago there was no 2/29, this function will return 2/28. If you'd rather return 3/1, just change the last return
statement to read::
return from_date.replace(month=3, day=1,
year=from_date.year-years)
Your question originally said you wanted to know how many years it's been since some date. Assuming you want an integer number of years, you can guess based on 365.2425 days per year and then check using either of the yearsago
functions defined above::
def num_years(begin, end=None):
if end is None:
end = datetime.now()
num_years = int((end - begin).days / 365.2425)
if begin > yearsago(num_years, end):
return num_years - 1
else:
return num_years
Convert timedelta of days into years
I can help you, check this out- > timedelta(days=5511).days
this returns days in int
and then you can divide it to 365 and you will take years. timedelta(days=5511).days/365
.
Using datetime.timedelta to add years
timedelta
does not support years, because the duration of a year depends on which year (for example, leap years have Feb 29).
You could use a relativedelta
instead (from PyPI package python-dateutil
) which does support years
and takes into account the baseline date for additions.
>>> from dateutil.relativedelta import relativedelta
>>> import datetime
>>> d = datetime.date(2020, 2, 29)
>>> d
datetime.date(2020, 2, 29)
>>> d + relativedelta(years=1)
datetime.date(2021, 2, 28)
Years between two date column = 'Timedelta' object has no attribute 'item'
I think you need sub
for subtract, convert timedeltas to days by dt.days
, divide by div
and last round
:
df_Years['Year_To_Maturity'] = (df_Years['maturity_date'].sub(df_Years['Today'])
.dt.days
.div(365)
.round(4))
print (df_Years)
maturity_date Today Year_To_Maturity
0 2022-12-15 2018-03-21 4.7397
1 2028-02-15 2018-03-21 9.9123
2 2045-12-01 2018-03-21 27.7178
3 2025-08-18 2018-03-21 7.4164
4 2019-01-16 2018-03-21 0.8247
5 2018-12-21 2018-03-21 0.7534
Thanks @pir for better solution:
df_Years['Year_To_Maturity'] = (df_Years['maturity_date'].sub(df_Years['Today'])
.dt.days
.div(365.25)
.round(4))
print (df_Years)
maturity_date Today Year_To_Maturity
0 2022-12-15 2018-03-21 4.7365
1 2028-02-15 2018-03-21 9.9055
2 2045-12-01 2018-03-21 27.6988
3 2025-08-18 2018-03-21 7.4114
4 2019-01-16 2018-03-21 0.8241
5 2018-12-21 2018-03-21 0.7529
How do I convert datetime.timedelta to minutes, hours in Python?
There's no built-in formatter for timedelta
objects, but it's pretty easy to do it yourself:
days, seconds = duration.days, duration.seconds
hours = days * 24 + seconds // 3600
minutes = (seconds % 3600) // 60
seconds = seconds % 60
Or, equivalently, if you're in Python 2.7+ or 3.2+:
seconds = duration.total_seconds()
hours = seconds // 3600
minutes = (seconds % 3600) // 60
seconds = seconds % 60
Now you can print it however you want:
'{} minutes, {} hours'.format(minutes, hours)
For example:
def convert_timedelta(duration):
days, seconds = duration.days, duration.seconds
hours = days * 24 + seconds // 3600
minutes = (seconds % 3600) // 60
seconds = (seconds % 60)
return hours, minutes, seconds
td = datetime.timedelta(2, 7743, 12345)
hours, minutes, seconds = convert_timedelta(td)
print '{} minutes, {} hours'.format(minutes, hours)
This will print:
9 minutes, 50 hours
If you want to get "10 minutes, 1 hour" instead of "10 minutes, 1 hours", you need to do that manually too:
print '{} minute{}, {} hour{}'.format(minutes, 's' if minutes != 1 else '',
hours, 's' if minutes != 1 else '')
Or you may want to write an english_plural
function to do the 's'
bits for you, instead of repeating yourself.
From your comments, it sounds like you actually want to keep the days separate. That's even easier:
def convert_timedelta(duration):
days, seconds = duration.days, duration.seconds
hours = seconds // 3600
minutes = (seconds % 3600) // 60
seconds = (seconds % 60)
return days, hours, minutes, seconds
If you want to convert this to a single value to store in a database, then convert that single value back to format it, do this:
def dhms_to_seconds(days, hours, minutes, seconds):
return (((days * 24) + hours) * 60 + minutes) * 60 + seconds
def seconds_to_dhms(seconds):
days = seconds // (3600 * 24)
hours = (seconds // 3600) % 24
minutes = (seconds // 60) % 60
seconds = seconds % 60
return days, hours, minutes, seconds
So, putting it together:
def store_timedelta_in_database(thingy, duration):
seconds = dhms_to_seconds(*convert_timedelta(duration))
db.execute('INSERT INTO foo (thingy, duration) VALUES (?, ?)',
thingy, seconds)
db.commit()
def print_timedelta_from_database(thingy):
cur = db.execute('SELECT duration FROM foo WHERE thingy = ?', thingy)
seconds = int(cur.fetchone()[0])
days, hours, minutes, seconds = seconds_to_dhms(seconds)
print '{} took {} minutes, {} hours, {} days'.format(thingy, minutes, hours, days)
calculate datetime-difference in years, months, etc. in a new pandas dataframe column
With a simple function you can reach your goal.
The function calculates the years difference and the months difference with a simple calculation.
import pandas as pd
import datetime
def parse_date(td):
resYear = float(td.days)/364.0 # get the number of years including the the numbers after the dot
resMonth = int((resYear - int(resYear))*364/30) # get the number of months, by multiply the number after the dot by 364 and divide by 30.
resYear = int(resYear)
return str(resYear) + "Y" + str(resMonth) + "m"
df = pd.DataFrame([("2000-01-10", "1970-04-29")], columns=["start", "end"])
df["delta"] = [parse_date(datetime.datetime.strptime(start, '%Y-%m-%d') - datetime.datetime.strptime(end, '%Y-%m-%d')) for start, end in zip(df["start"], df["end"])]
print df
start end delta
0 2000-01-10 1970-04-29 29Y9m
Related Topics
Pycharm Current Working Directory
Easy Way of Finding Decimal Places
Which Is More Preferable to Use: Lambda Functions or Nested Functions ('Def')
Sqlalchemy Create_All() Does Not Create Tables
How to Update the Image of a Tkinter Label Widget
Plot a Histogram Such That Bar Heights Sum to 1 (Probability)
Reducing Size of Pyinstaller Exe
How to Config Nltk Data Directory from Code
How to Parse a Website Using Selenium and Beautifulsoup in Python
Python Regex Instantly Replace Groups
Python Accessing Nested JSON Data
Access Item in a List of Lists
Why 'Torch.Cuda.Is_Available()' Returns False Even After Installing Pytorch with Cuda
Improper Use of _New_ to Generate Class Instances