79

I have a variable and I need to know if it is a datetime object.

So far I have been using the following hack in the function to detect datetime object:

if 'datetime.datetime' in str(type(variable)):
     print('yes')

But there really should be a way to detect what type of object something is. Just like I can do:

if type(variable) is str: print 'yes'

Is there a way to do this other than the hack of turning the name of the object type into a string and seeing if the string contains 'datetime.datetime'?

Martin Thoma
  • 124,992
  • 159
  • 614
  • 958
Ryan Saxe
  • 17,123
  • 23
  • 80
  • 128
  • Huh? Isn't this just exactly what `isinstance()` is for? – Celada Jun 07 '13 at 19:55
  • Why do you want to do this? – Daenyth Jun 07 '13 at 19:55
  • @Daenyth there are often valid reasons why duck typing doesn't work in one situation or another. But comparing the string representation of the type name as the OP is doing? That can't be right! – Celada Jun 07 '13 at 19:58
  • @Celada I know that, I'm asking, in this case, what does OP want to accomplish by doing this, because there's almost surely a better way. – Daenyth Jun 10 '13 at 13:34

8 Answers8

166

You need isinstance(variable, datetime.datetime):

>>> import datetime
>>> now = datetime.datetime.now()
>>> isinstance(now, datetime.datetime)
True

Update

As noticed by Davos, datetime.datetime is a subclass of datetime.date, which means that the following would also work:

>>> isinstance(now, datetime.date)
True

Perhaps the best approach would be just testing the type (as suggested by Davos):

>>> type(now) is datetime.date
False
>>> type(now) is datetime.datetime
True

Pandas Timestamp

One comment mentioned that in python3.7, that the original solution in this answer returns False (it works fine in python3.4). In that case, following Davos's comments, you could do following:

>>> type(now) is pandas.Timestamp

If you wanted to check whether an item was of type datetime.datetime OR pandas.Timestamp, just check for both

>>> (type(now) is datetime.datetime) or (type(now) is pandas.Timestamp)
ryanjdillon
  • 17,658
  • 9
  • 85
  • 110
RichieHindle
  • 272,464
  • 47
  • 358
  • 399
  • 2
    Not to others, this should generally be best since it is more flexible than `type(variable) == datetime.datetime` and will also yield `True` for `pandas` time-stamp objects and presumably other time-stamp formats. – ryanjdillon Mar 17 '17 at 10:41
  • 1
    @ryanjdillon why is it more flexible? While this works for datetime, it doesn't work for date, because datetime is a subclass of date. For example if you try to test `isinstance(my_datetime, datetime.date)` it will return true, which you probably don't want. This applies to all class hierarchies, is instance will return true for a test of any subclass against a parent class. – Davos Nov 30 '18 at 13:35
  • So do you then test for `isinstance(my_datetime, datetime.date) and not isinstance(my_datetime, datetime.datetime)` or test for `type(my_datetime) == datetime.date` ? – Davos Nov 30 '18 at 13:45
  • 1
    @ryanjdillon In pandas 0.23, Python 3.7 it doesn't seem to work for identifying pandas TimeStamps. I had to use: ` # assert isinstance(df.index[0], pd.Timestamp)` – user3556757 Dec 06 '18 at 04:28
  • @Davos I finally took the time to check out your comments, and thinking this was my answer made updates to it, only to realize it is not :) RichieHindle, feel free to do what you will with my contribution. – ryanjdillon Dec 07 '18 at 06:27
  • with python 3.8 checking if a variable pandas.Timestamp(1) isinstance of datetime.datetime returned True for me, so maybe just specific to 3.7? – alex9311 Oct 23 '20 at 20:05
9

Use isinstance.

if isinstance(variable,datetime.datetime):
    print "Yay!"
korylprince
  • 2,969
  • 1
  • 18
  • 27
6

Note, that datetime.date objects are not considered to be of datetime.datetime type, while datetime.datetime objects are considered to be of datetime.date type.

import datetime                                                                                                                     

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

isinstance(today, datetime.datetime)                                                                                                
>>> False

isinstance(now, datetime.datetime)                                                                                                  
>>> True

isinstance(now, datetime.date)                                                                                                      
>>> True

isinstance(now, datetime.datetime)                                                                                                  
>>> True
Artur Barseghyan
  • 12,746
  • 4
  • 52
  • 44
4

I believe all the above answer will work only if date is of type datetime.datetime. What if the date object is of type datetime.time or datetime.date?

This is how I find a datetime object. It always worked for me. (Python2 & Python3):

import datetime
type(date_obj) in (datetime, datetime.date, datetime.datetime, datetime.time)

Testing in Python2 or Python3 shell:

import datetime
d = datetime.datetime.now()  # creating a datetime.datetime object.
date = d.date()  # type(date): datetime.date
time = d.time()  # type(time): datetime.time

type(d) in (datetime, datetime.date, datetime.datetime, datetime.time)
True
type(date) in (datetime, datetime.date, datetime.datetime, datetime.time)
True
type(time) in (datetime, datetime.date, datetime.datetime, datetime.time)
True
Saurav Kumar
  • 563
  • 1
  • 6
  • 13
3

isinstance is your friend

>>> thing = "foo"
>>> isinstance(thing, str)
True
TehTris
  • 3,139
  • 1
  • 21
  • 33
2

While using isinstance will do what you want, it is not very 'pythonic', in the sense that it is better to ask forgiveness than permission.

try:
    do_something_small_with_object() #Part of the code that may raise an 
                                     #exception if its the wrong object
except StandardError:
    handle_case()

else:
    do_everything_else()
James
  • 2,635
  • 5
  • 23
  • 30
1

You can also check using duck typing (as suggested by James).

Here is an example:

from datetime import date, datetime

def is_datetime(dt):
    """
    Returns True if is datetime
    Returns False if is date
    Returns None if it is neither of these things
    """
    try:
        dt.date()
        return True
    except:
        if isinstance(dt, date):
            return False
    return None

Results:

In [8]: dt = date.today()
In [9]: tm = datetime.now()
In [10]: is_datetime(dt)
Out[11]: False
In [12]: is_datetime(tm)
Out[13]: True
In [14]: is_datetime("sdf")
In [15]:
toast38coza
  • 8,650
  • 3
  • 39
  • 32
1

This worked for me in python 3.9.4

if type(timeIn) is type(datetime.now().time()):
AkshayB
  • 55
  • 1
  • 7