How to compare dates in Python? - python

I need to see if a date has more than X days. How can I do this in Python?
I have tested something like:
if datetime.date(2010, 1, 12) > datetime.timedelta(3):
I got the error:
TypeError: can't compare datetime.date to datetime.timedelta
Any clue on how to achieve this?

You can't compare a datetime to a timedelta. A timedelta represents a duration, a datetime represents a specific point in time. The difference of two datetimes is a timedelta. Datetimes are comparable with each other, as are timedeltas.
You have 2 options:
Subtract another datetime from the one you've given, and compare the resulting timedelta with the timedelta you've also given.
Convert the timedelta to a datetime by adding or subtracting it to another datetime, and then compare the resulting datetime with the datetime you've given.

Comparing apples and oranges is always very hard! You are trying to compare "January 12, 2010" (a fixed point in time) with "3 hours" (a duration). There is no sense in this.
If what you are asking is "does my datetime fall after the nth day of the month" then you can do :
my_important_date = datetime.now()
if my_important_date.day > n:
pass #do you important things

Related

Python - how to convert and determine a type of a 5 digit date?

I have some of the date fields represented as 5-digit numbers. And there is a mapping from the numbers to an actual date. However I can't figure out what logic should be applied to convert the numbers to dates in the "%Y-%m-%d" format?
13581 -> 2007-03-09
12784 -> 2005-01-01
The numbers shown are the numbers of days since 1st January 1970, which is the origin of Unix time.
They can be converted using for example:
from datetime import datetime, timedelta
n = 13581
print((datetime.utcfromtimestamp(0) + timedelta(n)).strftime("%Y-%m-%d"))
gives:
2007-03-09
Here timedelta is called with a single argument, being the offset in days. In general it is called with timedelta(days, seconds, microseconds) but all of these arguments default to zero.
As shown by
import datetime
datetime.date(2005, 1, 1)-datetime.timedelta(days=12784)
# datetime.date(1970, 1, 1)
your number is the number of days since 1970-01-01.
So, you can get the date by:
datetime.date(1970, 1, 1) + datetime.timedelta(days=12784)
# datetime.date(2005, 1, 1)
Here you go:
>>> from datetime import date, timedelta
>>> (date(1970,1,1) + timedelta(days=12784)).strftime("%Y-%m-%d")
'2005-01-01'
Just in case for a column in dataframe while using the accepted answer, you can use .apply:
df["column"].apply(lambda x: (datetime.utcfromtimestamp(0) + timedelta(int(x))).strftime("%Y-%m-%d"))

Convert time (given in days since YYYY) into readable time format

I need help with converting time to a readable format. My time array (has 580 elements) is # of days since January 1st, 1900. How do I convert that to a normal time format (ie mm-dd-yyyy)?
For example, input time is 43,887 and output should read 02-27-2020 after adding it to Jan 1, 1900.
Thank you!
datetime.datetime and timedelta class can be helpful here.
from datetime import datetime, timedelta
def convert(inp, date1):
new_date = date1 + timedelta(inp)
return new_date.strftime("%m-%d-%Y")
date1 = datetime(1900, 1, 1)
print(convert(43887, date1))
You can use the datetime.datetime class can help you here. The following works, if those values are treated as integer days (you don't specify what they are).
from datetime import datetime
dt = datetime.fromordinal(43887)
dt.strftime('%d-%m-%Y')

Subtracting dates and only take out number of days as number

#Under d.types i can confirm they are both datetime objects
date1 datetime64[ns]
date2 datetime64[ns]
df_test['snaptoexpectedStart'] = df['date1'] - df['date2']
TypeError: '<' not supported between instances of 'str' and 'int'
I dont understand why I'm getting that error when both the columns im trying to subtract are in the correct format.
I guess it has something to do with the datetime format I suppose, try casting this way to see if it works :
from datetime import datetime
df_test['snaptoexpectedStart'] = datetime(df['date1']) - datetime(df['date2'])
If you are looking to get the number of days only than try this :
df_test['snaptoexpectedStart'] = (df_test['date1'] - df_test['date2Date']).dt.days
You might want to look into the timedelta class:
According to the API, subtracting two datetimes (assuming they are datetime.datetimes) results in a timedelta object. You can then use the .day attribute of the timedelta to get the difference in days.

Compare two dates with different formats in Python

I'm not familiar with Python, just debugging an existing code. I'm comparing two dates here but they have different formats. I get the "TypeError: can't compare offset-naive and offset-aware datetimes" when I do the compare.
if date_start <= current_date:
"TypeError: can't compare offset-naive and offset-aware
str(date_start) >> 2015-08-24 16:25:00+00:00
str(current_date) >> 2015-08-24 17:58:42.092391
How do I make a valid date comparison? I'm assuming I need to convert one to another format.
UPDATE
hour_offset = 0
minute_offset = 0
if timezone_offset:
offset_sign = int('%s1' % timezone_offset[0])
hour_offset = offset_sign * int(timezone_offset[1:3])
minute_offset = offset_sign * int(timezone_offset[3:5])
current_date = (datetime.datetime.now() +
datetime.timedelta(hours=hour_offset,minutes=minute_offset))
The previous dev might have applied the timezone offset this way. Any thoughts on this one?
Use dt.replace(tzinfo=tz) to add a timezone to the naive datetime, so that they can be compared.
There is no more details here to solve.But if you want to get a offset-naive time.Try this
(offset-aware-datetime).replace(tzinfo=None)
To add a timezone to offset-naive time.Try this
(offset-naive-datetime).replace(tzinfo=tz)
One way is to convert the date to seconds since epoch and then compare. Say,if your date is 2015-08-24 16:25:00 then you can convert to seconds using datetime method. It takes parameters as (year, month, day[, hour[, minute[,second[, microsecond[, tzinfo]]]]]). It returns a datetime object. Finally, you can use strftime() to get seconds as a zero-padded decimal number. So your code can be:
import datetime
d1 = datetime.datetime(2015,8,24,16,25,0)
d2 = datetime.datetime(2015,8,24,17,58,42,92391)
if int(d1.strftime("%s")) > int(d2.strftime("%s")):
print "First one is bigger"
else:
print "Second one is bigger"
I hope this helps!

How to convert dateutil.relativedelta object to datetime.timedelta object?

How can I convert a dateutil.relativedelta object to a datetime.timedelta object?
e.g.,
# pip install python-dateutil
from dateutil.relativedelta import relativedelta
from datetime import timedelta
rel_delta = relativedelta(months=-2)
# How can I convert rel_delta to a timedelta object so that I can call total_seconds() ?
time_delta = ???(rel_delta)
time_delta.total_seconds() # call the timedelta.total_seconds() method
You can't, for one huge reason: They don't store the same information. datetime.timedelta only stores days, seconds, and milliseconds, whereas dateutil.relativedelta stores every single time component fed to it.
That dateutil.relativedelta does so is important for storing things such as a difference of 1 month, but since the length of a month can vary this means that there is no way at all to express the same thing in datetime.timedelta.
In case someone is looking to convert a relativedelta to a timedelta from a specific date, simply add and subtract the known time:
utcnow = datetime.utcnow()
rel_delta = relativedelta(months=-2)
time_delta = utcnow + rel_delta - utcnow # e.g, datetime.timedelta(days=-62)
As a commenter points out, the resulting timedelta value will differ based on what month it is.
Depending on why you want to call total_seconds, it may be possible to refactor your code to avoid the conversion altogether. For example, consider a check on whether or not a user is over 18 years old:
datetime.date.today() - user['dateOfBirth'] < datetime.timedelta(days=365*18)
This check is not a good idea, because the timedelta object does not account for things like leap years. It's tempting to rewrite as:
datetime.date.today() - user['dateOfBirth'] < dateutil.relativedelta.relativedelta(years=18)
which would require comparing a timedelta (LHS) to a relativedelta (RHS), or converting one to the other. However, you can refactor the check to avoid this conversion altogether:
user['dateOfBirth'] + dateutil.relativedelta.relativedelta(years=18) > datetime.date.today()

Categories