68

Here's a little snippet that I'm trying execute:

>>> from datetime import *
>>> item_date = datetime.strptime('7/16/10', "%m/%d/%y")
>>> from_date = date.today()-timedelta(days=3)
>>> print type(item_date)
<type 'datetime.datetime'>
>>> print type(from_date)
<type 'datetime.date'>
>>> if item_date > from_date:
...     print 'item is newer'
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can't compare datetime.datetime to datetime.date

I can't seem to compare the date and the datetime values. What would be the best way to compare these? Should I convert the datetime to date or vice-versa? How do i convert between them.

(A small question but it seems to be a little confusing.)

Serenity
  • 35,289
  • 20
  • 120
  • 115
Mridang Agarwalla
  • 43,201
  • 71
  • 221
  • 382
  • This seems to be a duplicate of http://stackoverflow.com/questions/7239315/cant-compare-datetime-datetime-to-datetime-date – tobixen Apr 24 '15 at 06:03

6 Answers6

112

Use the .date() method to convert a datetime to a date:

if item_date.date() > from_date:

Alternatively, you could use datetime.today() instead of date.today(). You could use

from_date = from_date.replace(hour=0, minute=0, second=0, microsecond=0)

to eliminate the time part afterwards.

kennytm
  • 510,854
  • 105
  • 1,084
  • 1,005
  • I think this is the best answer if it's given that item_date will always be a datetime and from_date will always be a date. I landed here because I wanted to sort a list containing both date and datetime. In my case, the approach above is probably the worst. – tobixen Apr 24 '15 at 10:17
  • 2
    why is the conversion necessary? I thought that internally python uses a unixtimestamp for `date` and `datetime`. Or is `date` more resource optimized in that it only looks for date and not time? – Timo May 19 '18 at 11:56
7

I am trying to compare date which are in string format like '20110930'

benchMark = datetime.datetime.strptime('20110701', "%Y%m%d") 

actualDate = datetime.datetime.strptime('20110930', "%Y%m%d")

if actualDate.date() < benchMark.date():
    print True
omar
  • 1,541
  • 3
  • 21
  • 36
samarth
  • 3,866
  • 7
  • 45
  • 60
  • 6
    If you have string format YYYYMMDD string comparison is equivalent to converting to date and comparing dates and is more efficient. – omikron Mar 10 '14 at 09:59
6

Here is another take which preserves information in case both the inputs are datetimes and not dates, "stolen" from a comment at can't compare datetime.datetime to datetime.date ... convert the date to a datetime using this construct:

datetime.datetime(d.year, d.month, d.day)

Suggestion:

from datetime import datetime

def ensure_datetime(d):
    """
    Takes a date or a datetime as input, outputs a datetime
    """
    if isinstance(d, datetime):
        return d
    return datetime.datetime(d.year, d.month, d.day)

def datetime_cmp(d1, d2):
    """
    Compares two timestamps.  Tolerates dates.
    """
    return cmp(ensure_datetime(d1), ensure_datetime(d2))
tobixen
  • 3,893
  • 1
  • 20
  • 20
2

In my case, I get two objects in and I don't know if it's date or timedate objects. Converting to date won't be good as I'd be dropping information - two timedate objects with the same date should be sorted correctly. I'm OK with the dates being sorted before the datetime with same date.

I think I will use strftime before comparing:

>>> foo=datetime.date(2015,1,10)
>>> bar=datetime.datetime(2015,2,11,15,00)
>>> foo.strftime('%F%H%M%S') > bar.strftime('%F%H%M%S')
False
>>> foo.strftime('%F%H%M%S') < bar.strftime('%F%H%M%S')
True

Not elegant, but should work out. I think it would be better if Python wouldn't raise the error, I see no reasons why a datetime shouldn't be comparable with a date. This behaviour is consistent in python2 and python3.

tobixen
  • 3,893
  • 1
  • 20
  • 20
1

Create and similar object for comparison works too ex:

from datetime import datetime, date

now = datetime.now()
today = date.today()

# compare now with today
two_month_earlier = date(now.year, now.month - 2, now.day)
if two_month_earlier > today:
    print(True)

two_month_earlier = datetime(now.year, now.month - 2, now.day)
if two_month_earlier > now:
   print("this will work with datetime too")
Peko Chan
  • 306
  • 5
  • 15
0

I got you bro

you can use timetuple function to compare between date obj and datetime obj

>>> from datetime import datetime               
>>> date_obj=datetime.utcnow().date() 
>>> type(date_obj)
<type 'datetime.date'>
>>> datetime_obj=datetime.utcnow()    
>>> type(datetime_obj)            
<type 'datetime.datetime'>
>>> datetime_obj.timetuple()          
time.struct_time(tm_year=2022, tm_mon=10, tm_mday=11, tm_hour=2, tm_min=12, tm_sec=43, tm_wday=1, tm_yday=284, tm_isdst=-1)
>>> date_obj.timetuple()     
time.struct_time(tm_year=2022, tm_mon=10, tm_mday=11, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=1, tm_yday=284, tm_isdst=-1)
>>> type(datetime_obj.timetuple())
<type 'time.struct_time'>
>>> type(date_obj.timetuple()) 
<type 'time.struct_time'>
>>> date_obj.timetuple()<datetime_obj.timetuple()
True
mike
  • 71
  • 3