109

I have tried a few obvious options but none of them works:

In [150]: x
Out[150]: datetime.date(2012, 9, 1)

In [151]: type(x)
Out[151]: datetime.date

In [152]: isinstance(x, datetime.date)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-152-9a298ea6fce5> in <module>()
----> 1 isinstance(x, datetime.date)

TypeError: isinstance() arg 2 must be a class, type, or tuple of classes and types

In [153]: x is datetime.date
Out[153]: False

In [154]: type(x) is datetime.date
Out[154]: False

What is the right way of doing this?

  • 3
    Can you produce an [SSCCE](http://sscce.org)? I should think a four- or five-line program would suffice. I [cannot reproduce your results](http://ideone.com/gqdou2) from what you have already posted. – Robᵩ Apr 22 '13 at 16:02
  • 1
    What Python version are you using? For Python-2.6 `isinstance(x, datetime.date)` works fine as does `type(x) is datetime.date` – RedBaron Apr 22 '13 at 16:03
  • Which version of Python are you using, and what did you do to generate `x`? – Mark Ransom Apr 22 '13 at 16:03
  • x should not matter, it is complaining about arg 2 of `isinstance`, his `datetime.date` class is borked for some reason – cmd Apr 22 '13 at 16:04
  • 2
    Could you check your imports? This line is actually missing in your snippet. The error message hints at something like "from datetime import date, datetime". But it must be "import datetime". – Simon Steinberger Apr 22 '13 at 16:05
  • if it's dataframe, you can use `df.select_dtypes(include=[np.datetime64])` – shahar_m Jun 14 '21 at 12:12

8 Answers8

159

i believe the reason it is not working in your example is that you have imported datetime like so :

from datetime import datetime

this leads to the error you see

In [30]: isinstance(x, datetime.date)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/<ipython-input-30-9a298ea6fce5> in <module>()
----> 1 isinstance(x, datetime.date)

TypeError: isinstance() arg 2 must be a class, type, or tuple of classes and types

if you simply import like so :

import datetime

the code will run as shown in all of the other answers

In [31]: import datetime

In [32]: isinstance(x, datetime.date)
Out[32]: True

In [33]: 
olly_uk
  • 11,559
  • 3
  • 39
  • 45
  • 1
    If you have a datetime (instead of just a date), by extension you can do: `x = datetime.datetime.now()` then `isinstance(x, datetime.datetime)` – fantabolous Aug 11 '14 at 05:28
  • 9
    Well, if you'd like to distinguish datetime.date and datetime.datetime this method will fail: `>>> import datetime` `>>> foo = datetime.datetime.now()` `>>> isinstance(foo, datetime.date)` `True` .__class__ should help `>>> foo.__class__ == datetime.date` `False` `>>> foo.__class__ == datetime.datetime` `True` – BernarditoLuis Sep 10 '15 at 13:12
  • 3
    In order to differentiate between "datetime.date" and "datetime.date" classes you should use `type(x) is datetime.date` after importing the "datetime" library as explained here. – Elias Mar 09 '20 at 13:57
  • Why not use type? I've done it, but noone mentioned it. Is it taboo or something? I always `from datetime import datetime`, it's very rare for me not to. `if isinstance(dt, type(datetime.now()))` – DBMage Nov 03 '20 at 20:16
  • Thanks, @BernarditoLuis for the appropriate answer. – Ashok Joshi Mar 16 '22 at 06:20
22

right way is

import datetime
isinstance(x, datetime.date)

When I try this on my machine it works fine. You need to look into why datetime.date is not a class. Are you perhaps masking it with something else? or not referencing it correctly for your import?

cmd
  • 5,754
  • 16
  • 30
  • The example in the question shows this not working. Do you have an explanation for that? – Mark Ransom Apr 22 '13 at 16:01
  • 5
    cmd's solution also returns True if x is a datetime.datetime. This may not be what you want or expect. Simon Steinberger's answer properly discriminates between datetime.date and datetime.datetime. – Chuck Jul 16 '15 at 19:43
  • 2
    @cmd In python 2.7 the statement "isinstance(datetime.datetime.now(), datetime.date)" returns True. – Chuck Apr 10 '17 at 13:49
  • Thats true. datetime.datetime object is a datetime.date through inheritance. If you want to distinguish between datetime.datetime objects and datetime.date objects check for `if sinstance(x, datetime.datetime)` first then `elif isinstance(x, datetime.date)` since datetime is a date but date is not a datetime. – cmd Oct 08 '20 at 20:26
19

In Python 3.8.4 it can be checked that the method with isinstance will fail when checking if a datetime is whether a date or a datetime as both checks will give True.

    >>> from datetime import datetime, date
    >>> mydatetime = datetime.now()
    >>> mydate = mydatetime.date()
    >>> isinstance(mydatetime, datetime)
    True
    >>> isinstance(mydatetime, date)
    True

This is due to the fact that datetime is a subclass of date as it is explained in this other answer:

an instance of a derived class is an instance of a base class, too

Therefore, when distinguishing between datetime and date, type should be used instead:

    >>> type(mydatetime) == date
    False
    >>> type(mydate) == date
    True
    >>> type(mydate) == datetime
    False
    >>> type(mydatetime) == datetime
    True
forzagreen
  • 2,509
  • 30
  • 38
Andreu Gimenez
  • 413
  • 5
  • 9
17
import datetime
d = datetime.date(2012, 9, 1)
print type(d) is datetime.date

> True
Simon Steinberger
  • 6,605
  • 5
  • 55
  • 97
  • 1
    Using `is` instead of `==` is more idiomatic way of doing it: `print type(d) is datetime.date`. – SpankMe Apr 22 '13 at 16:00
  • 1
    Using type() for type checking is discouraged and unwise, the proper way is to do isinstance. – Visgean Skeloru Dec 21 '14 at 20:39
  • 3
    In this case, type() works as expected for both datetime.date and datetime.datetime. isinstance(x, datetime.date) returns True if x is a datetime.date or a datetime.datetime. – Chuck Jul 16 '15 at 19:49
  • @SpankMe: Thanks, I've adapted the answer. – Simon Steinberger Jul 16 '15 at 20:01
  • 2
    Using `is` instead of `==` is a premature optimization that might break. There is no reason to test for object identity here (it is likely to work in many cases until it doesn't). You should mention that `type()` is used instead of `isinstance()`, to reject subclasses such as `datetime.datetime`. – jfs Jul 17 '15 at 00:09
17

According to documentation class date is a parent for class datetime. And isinstance() method will give you True in all cases. If you need to distinguish datetime from date you should check name of the class

import datetime

datetime.datetime.now().__class__.__name__ == 'date' #False
datetime.datetime.now().__class__.__name__ == 'datetime' #True
datetime.date.today().__class__.__name__ == 'date' #True
datetime.date.today().__class__.__name__ == 'datetime' #False

I've faced with this problem when i have different formatting rules for dates and dates with time

Roman Kazakov
  • 697
  • 7
  • 12
7

If your existing code is already relying on from datetime import datetime, you can also simply also import date

from datetime import datetime, timedelta, date
print isinstance(datetime.today().date(), date)
Dmitry B.
  • 9,107
  • 3
  • 43
  • 64
4

In Python 3.5, isinstance(x, date) works to me:

>>> from datetime import date
>>> x = date(2012, 9, 1)
>>> type(x)
<class 'datetime.date'>
>>> isinstance(x, date)
True
>>> type(x) is date
True
fedorqui
  • 275,237
  • 103
  • 548
  • 598
0

If you are using freezegun package in tests you may need to have more smart isinstance checks which works well with FakeDate and original Date/Datetime beeing inside with freeze_time context:

def isinstance_date(value):
    """Safe replacement for isinstance date which works smoothly also with Mocked freezetime"""
    import datetime
    if isinstance(value, datetime.date) and not isinstance(value, datetime.datetime):
        return True
    elif type(datetime.datetime.today().date()) == type(value):
        return True
    else:
        return False


def isinstance_datetime(value):
    """Safe replacement for isinstance datetime which works smoothly also with Mocked freezetime """
    import datetime
    if isinstance(value, datetime.datetime):
        return True
    elif type(datetime.datetime.now()) == type(value):
        return True
    else:
        return False

and tests to verify the implementation

class TestDateUtils(TestCase):

    def setUp(self):
        self.date_orig = datetime.date(2000, 10, 10)
        self.datetime_orig = datetime.datetime(2000, 10, 10)

        with freeze_time('2001-01-01'):
            self.date_freezed = datetime.date(2002, 10, 10)
            self.datetime_freezed = datetime.datetime(2002, 10, 10)

    def test_isinstance_date(self):
        def check():
            self.assertTrue(isinstance_date(self.date_orig))
            self.assertTrue(isinstance_date(self.date_freezed))
            self.assertFalse(isinstance_date(self.datetime_orig))
            self.assertFalse(isinstance_date(self.datetime_freezed))
            self.assertFalse(isinstance_date(None))

        check()
        with freeze_time('2005-01-01'):
            check()

    def test_isinstance_datetime(self):
        def check():
            self.assertFalse(isinstance_datetime(self.date_orig))
            self.assertFalse(isinstance_datetime(self.date_freezed))
            self.assertTrue(isinstance_datetime(self.datetime_orig))
            self.assertTrue(isinstance_datetime(self.datetime_freezed))
            self.assertFalse(isinstance_datetime(None))

        check()
        with freeze_time('2005-01-01'):
            check()

pymen
  • 5,737
  • 44
  • 35