2

I am trying to develop a logic that depends on the type of the input being date or datetime. To achieve this goal, I used isinstance with datetime.date and datetime.datetime. Unfortunately, it seems like that a datetime.datetime object is considered an instance of datetime.date.

import datetime

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


type(date_obj)
# <class 'datetime.date'>

type(datetime_obj)
# <class 'datetime.datetime'>


isinstance(date_obj, datetime.date)
# True
isinstance(datetime_obj, datetime.date)
# True


isinstance(date_obj, datetime.datetime)
# False
isinstance(datetime_obj, datetime.date)
# True

I suspected that datetime.date might be considered a subclass of datetime.datetime but that's not the case:

issubclass(datetime.date, datetime.datetime)
# False
issubclass(datetime.datetime, datetime.date)
# True

What's the pythonic way of figureing out whether an object is a date or a datetime?

P.S. I checked this related question, but that doesn't resolve my issue.

Mehdi Zare
  • 1,221
  • 1
  • 16
  • 32
  • I think in your second snippet, you meant to write `issubclass(datetime.datetime, datetime.date)`, which is `True` – Brian61354270 Jan 16 '23 at 21:19
  • Does this answer your question? [What are the differences between type() and isinstance()?](https://stackoverflow.com/questions/1549801/what-are-the-differences-between-type-and-isinstance) – buran Jan 16 '23 at 21:21
  • @buran thanks, seems like that solves this. – Mehdi Zare Jan 16 '23 at 21:24

2 Answers2

1

You can retrieve the exact type of the objects with type, and check whether it's date or datetime using is:

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

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

Note that type objects are unique, so comparing them using is is well defined.

Brian61354270
  • 8,690
  • 4
  • 21
  • 43
0

You can check first for the wider type, then the other:

if isinstance(obj, datetime.date):
    # it's a date, not a datetime
    ...
elif isinstance(obj, datetime.datetime):
    # it's a datetime, not a date
    ...

Because every datetime.datetime object is also a datetime.date object, but the reverse is not generally true.

Mustafa Aydın
  • 17,645
  • 4
  • 15
  • 38