Python: how can I check whether an object is of type datetime.date?
Question:
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?
Answers:
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?
import datetime
d = datetime.date(2012, 9, 1)
print type(d) is datetime.date
> True
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]:
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)
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
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
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()
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
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?
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?
import datetime
d = datetime.date(2012, 9, 1)
print type(d) is datetime.date
> True
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]:
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)
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
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
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()
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