Subtracting Dates With Python - python

I'm working on a simple program to tell an individual how long they have been alive.
I know how to get the current date, and get their birthday. The only problem is I have no way of subtracting the two, I know a way of subtracting two dates, but unfortunately it does not include hours, minutes, or seconds.
I am looking for a method that can subtract two dates and return the difference down to the second, not merely the day.

from datetime import datetime
birthday = datetime(1988, 2, 19, 12, 0, 0)
diff = datetime.now() - birthday
print diff
# 8954 days, 7:03:45.765329

Use UTC time otherwise age in seconds can go backwards during DST transition:
from datetime import datetime
born = datetime(1981, 12, 2) # provide UTC time
age = datetime.utcnow() - born
print(age.total_seconds())
You also can't use local time if your program runs on a computer that is in a different place (timezone) from where a person was born or if the time rules had changed in this place since birthday. It might introduce several hours error.
If you want to take into account leap seconds then the task becomes almost impossible.

When substracting two datetime objects you will get a new datetime.timedelta object.
from datetime import datetime
x = datetime.now()
y = datetime.now()
delta = y - x
It will give you the time difference with resolution to microsencods.
For more information take a look at the official documentation.

Create a datetime.datetime from your date:
datetime.datetime.combine(birthdate, datetime.time())
Now you can subtract it from datetime.datetime.now().
>>> from datetime import date, datetime, time
>>> bday = date(1973, 4, 1)
>>> datetime.now() - datetime.combine(bday, time())
datetime.timedelta(14392, 4021, 789383)
>>> print datetime.now() - datetime.combine(bday, time())
14392 days, 1:08:13.593813

import datetime
born = datetime.date(2002, 10, 31)
today = datetime.date.today()
age = today - born
print(age.total_seconds())
Output: 463363200.0

Since DateTime.DateTime is an immutable type method like these always produce a new object the difference of two DateTime object produces a DateTime.timedelta type:
from datetime import date,datetime,time,timedelta
dt=datetime.now()
print(dt)
dt2=datetime(1997,7,7,22,30)
print(dt2)
delta=dt-dt2
print(delta)
print(int(delta.days)//365)
print(abs(12-(dt2.month-dt.month)))
print(abs(dt.day))
The output timedelta(8747,23:48:42.94) or what ever will be days when u test the code indicates that the time delta encodes an offset of 8747 days and 23hour and 48 minute ...
The Output
2021-06-19 22:27:36.383761
1997-07-07 22:30:00
8747 days, 23:57:36.383761
23 Year
11 Month
19 Day

Related

How to convert numbers to dates

the emplyee number is composed of year and month and 3 digit control number how to know the number of years they works if we base on todays date? Employee1 201011003, eployee2 200605015
You can use datetime library like this:
from datetime import date
date_str = '201011003'
year = int(date_str[0:4])
month = int(date_str[4:6])
d = date(year, month, 1)
year_delta = (date.today() - d).days // 365
print(year_delta)
You can use datetime.strptime to read the date string into a datetime object. By subtracting two datetime objects you'll get back a timedelta object, which you can use to compute the years the employee has been there.
from datetime import datetime
def get_date(s):
return datetime.strptime(s[:6], '%Y%m')
Examples
>>> get_date('201011003')
datetime.datetime(2010, 11, 1, 0, 0)
>>> get_date('200605015')
datetime.datetime(2006, 5, 1, 0, 0)
Depending on the precision you want, you can approximate the number of years the employee has been there like
def get_years(s):
start = datetime.strptime(s[:6], '%Y%m')
now = datetime.now()
return (now - start).days / 365.25
>>> get_years('201011003')
9.527720739219713
>>> get_years('200605015')
14.03148528405202
To get very accurate results, I suggest you to use the dateutil package. It contains a super powerful function called relativedelta that is going to give you the years, months and days that have passed since the day you are interested in, considering leap years (instead of just days, as the datetime.timedelta does).
Also, just as CoryKramer did, we can use the strptime function to parse the date from the employee's codes you have.
import datetime as dt
from dateutil.relativedelta import relativedelta
employee = '201011003'
date_joined = dt.datetime.strptime(employee[:6], '%Y%m')
result = relativedelta(dt.datetime.today(), date_joined)
print('The employee has been working for {} years, {} months and {} days'.format(
result.years, result.months, result.days))
Outputs
The employee has been working for 9 years, 6 months and 11 days

Not understanding datetime delta in Python

from datetime import datetime as dt
I have 2 datetime fields
dt.now() returns 2019-01-08 11:46:26.035303
This is PST
x is my dataset
x['CreatedDate'] returns 2019-01-08T20:35:47.000+0000
dt.strptime(x['CreatedDate'.split('.')[0],'%Y-%m-%dT%H:%M:%S)) - datetime.timedelta(hours=8) returns 2019-01-08 08:43:33
I subtract the two,
tdelta = dt.now() - (dt.strptime(x['CreatedDate'.split('.')[0],'%Y-%m-%dT%H:%M:%S)) - datetime.timedelta(hours=8))
which is 2019-01-08 11:46:26.035303 - 2019-01-08 08:43:33
The difference should be ~3 hours but the result I'm getting is -1 day, 11:02:53.039790
-13H 12M 53S
I'm confused as to what is being returned.
Disclaimer
I am having a tough time making the datetime objects that you made. So, my answer will not be a direct solution to your exact problem.
I dont have x defined in my code. If you supply it, I can adjust my answer to be more specific.
Answer
But if you use this code:
import datetime as dt
first_time = dt.datetime(2019, 1, 8, 8, 43, 33) #This is a good way to make a datetime object
To make your datetime object then this code below will make the correct calculations and print it effectively for you:
second_time = dt.datetime.now()
my_delta = first_time - second_time
print("Minutes: " + str(my_delta.total_seconds()/60))
print("Hours: " + str(my_delta.total_seconds()/3600))
print("Days: " + str(my_delta.total_seconds()/3600/24))
Note
dt.datetime takes (year, month, day, hour, minute, second) here but dt.datetime.now() is making one with microseconds as well (year, month, day, hour, minute, second, microseconds). The function can handle being given different time specificities without error.
Note 2
If you do print(my_delta) and get something like: -1 day, 16:56:54.481901 this will equate to your difference if your difference is Hours: -7.051532805277778 This is because 24-16.95 = -7.05
The issue is with the subtraction of datetime.timedelta(hours=8) I removed that from changed the dt.now to dt.utcnow() and it works fine.

Convert two timestamp floats to a readable number of years, months, and days

I have two timestamps which are stored in float format:
tms1 = 1479081600.0
tms2 = 1482105600.0
Upon calculating the difference I get
tms2 - tms1
3024000.0
How do I go about displaying this time difference of 3024000 into a readable format in days, months or years? (The answer is 35 days between 14 Nov 2016 to 19 Dec 2016 using an online unix time difference calculator)
You can use (after importing datetime)
datetime.timedelta(seconds=3024000).days
which is
35
You should use timedelta as this is a time delta - a difference in time, not an absolute time. A full representation can also be obtained by coercing a timedelta to a string:
print(datetime.timedelta(seconds=3024000))
Gives the output:
35 days, 0:00:00
Note that you don't need an online calculator for anything - datetime comes with batteries included. You could do:
import datetime
date_format = "%d %b %Y"
start_date = datetime.datetime.strptime("14 Nov 2016", date_format)
end_date = datetime.datetime.strptime("19 Dec 2016", date_format)
print(start_date == datetime.datetime.fromtimestamp(1479081600))
print(start_date)
print(end_date.strftime("%d/%m/%Y"))
diff = end_date - start_date
print(diff)
print(diff.days)
which outputs:
True
2016-11-14 00:00:00
19/12/2016
35 days, 0:00:00
35
Note that diff here is identical to the original timedelta object, but is dynamically created from datetimes rather than statically constructed. I've also demonstrated the fact that you can build a datetime from a timestamp, should you wish, and I've also taken the liberty of demonstrating strftime and the like to illustrate the power of datetime. I highly recommend the datetime approach over an arithmetic approach as it's a lot more readable and extensible.
This answer is pretty lightweight, which isn't necessarily bad, as often you might not need any more functionality than it provides, but if the timedelta between two days is less than 24 hours, it will round down to 0 days, for example. It also can't handle timezones. If you need either of those, see the legendary Raymond's awesome answer
Just subtracting seconds doesn't help you know whether a day boundary has been crossed, so it is necessary to convert the timestamps to datetime objects before computing the days.
Add since the timezone can affect what the calendar day is for a UTC timestamp, you may need a tzinfo object as well.
Once the calendar dates are known, a little calendar math is needed to compute the difference in years, months, and days:
from datetime import timedelta, datetime
def time_diff(start_timestamp, end_timestamp, tz=None):
""" Return time difference in years, months, and days.
If *tz* is None, the timestamp is converted to the platform’s local date
and time. Otherwise, *tz* should be an instance of a *tzinfo* subclass.
"""
# Determine whether we're going forward or backward in time
ago = ''
if end_timestamp < start_timestamp:
ago = 'ago'
start_timestamp, end_timestamp = end_timestamp, start_timestamp
# Compute the calendar dates from the timestamps
d1 = datetime.fromtimestamp(start_timestamp, tz)
d2 = datetime.fromtimestamp(end_timestamp, tz)
# Advance d1 day-by-day until the day is at or above d2.day
days = 0
while d2.day < d1.day:
days += 1
d1 += timedelta(days=1)
# Now compute the day difference
days += d2.day - d1.day
# Compute the totals months difference and express in years and months
total_months = (d2.year * 12 + d2.month) - (d1.year * 12 + d1.month)
years, months = divmod(total_months, 12)
# format the output
plural = lambda n: '' if n == 1 else 's'
return '%d year%s, %d month%s, and %d day%s %s' % (
years, plural(years), months, plural(months), days, plural(days), ago)
Here is an example of how to use the function:
from datetime import tzinfo
class GMT1(tzinfo):
# Example tzinfo subclass taken from the Python docs
def utcoffset(self, dt):
return timedelta(hours=1)
def dst(self, dt):
return timedelta(0)
def tzname(self,dt):
return "Europe/Prague"
print(time_diff(1479081600.0, 1482105600.0, tz=GMT1()))
This outputs:
0 years, 1 month, and 5 days

Convert TLE times (decimal days) to seconds after epoch

The standard two line element (TLE) format contains times as 2-digit year plus decimal days, so 16012.375 would be January 12, 2016 at 09:00. Using python's time or datatime modules, how can I convert this to seconds after epoch? I think I should use structured time but I am not sure how. seconds_of is a fictitious function - need to replace with something real.
EDIT: It will be most helpful if the answer is long (verbose) - like one step per line or so, so I can understand what is happening.
EDIT 2: After seeing the comments from #J.F.Sebastian I looked at the link for TLE and found it nowhere states "UTC". So I should point out the initial information and final information are UTC. There is no reference to local time, time zone, or system time.
e.g.
tim = "16012.375"
year = 2000 + int(tim[0:2])
decimal_days = float(tim[2:])
print year, decimal_days
2016, 12.375
# seconds_of is a fictitious function - need to replace with something real
seconds_after_epoch = seconds_of(2016,1,1) + (3600. * 24.) * decimal_days
You could try something like this [EDIT according to the comments].
import datetime
import time
# get year 2 digit and floating seconds days
y_d, nbs = "16012.375".split('.')
# parse to datetime (since midnight and add the seconds) %j Day of the year as a zero-padded decimal number.
d = datetime.datetime.strptime(y_d, "%y%j") + datetime.timedelta(seconds=float("." + nbs) * 24 * 60 * 60)
# 1.0 => 1 day
# from time tuple get epoch time.
time.mktime(d.timetuple())
#1481896800.0
It is easy to get datetime object given year and decimal_days:
>>> from datetime import datetime, timedelta
>>> year = 2016
>>> decimal_days = 12.375
>>> datetime(year, 1, 1) + timedelta(decimal_days - 1)
datetime.datetime(2016, 1, 12, 9, 0)
How to convert the datetime object into "seconds since epoch" depends on the timezone (local, utc, etc). See Converting datetime.date to UTC timestamp in Python e.g., if your input is in UTC then it is simple to get "seconds since the Epoch":
>>> utc_time = datetime(2016, 1, 12, 9, 0)
>>> (utc_time - datetime(1970, 1, 1)).total_seconds()
1452589200.0

Python date check

I'm hoping to create a program that takes todays date and a given date in the future and finds the difference in days between those two dates. I'm not too sure as to how I would go about doing this and I have very little experience using datetime.
From what I've been trying and reading up, I need to import datetime, and then grab todays date. After that, I need to take an input from the user for the day, month and year that they want in the future, and to make a check that the current year is less than the future year. After that, I'll need to do a calculation in the difference in days between them and print that to the screen.
Any help would be very much appreciated.
Many Thanks
here a hint for you small program using datetime and time:
>>> import time
>>> import datetime
>>> today_time = time.time()
>>> today_time
1415848116.311676
>>> today_time = datetime.datetime.fromtimestamp(today_time)
>>> today_time
datetime.datetime(2014, 11, 13, 8, 38, 36, 311676)
>>> future_time = input("Enter Year,month,day separeted by space:")
Enter Year,month,day separeted by space:2015 06 24
>>> year,month,day = future_time.split()
>>> diff = datetime.datetime(int(year),int(month),int(day)) - today_time
>>> diff.days
222
you can use datetime.date but instead asking user current date, you can have it from the system using time.time

Categories