Newbie Questions (Regarding From Datetime Import Datetime)

Viewed 44

I came across this code to count how much days I have til my birthday.

I know the difference between 'from import' and 'import' however I am confused because based on the code below, the second function named 'days_remaining' I was able to write in the variable days = (current_year - now).days. But if I recall correctly, days is a method/attribute under timedelta and I shouldn't be able to use that if I wrote from datetime import datetime because I am specifically importing only datetime method in the module.

from datetime import datetime
import time

def get_user_birthday():
  date_str = input("Enter your birth date in DD/MM/YYYY: ")
  try:
    birthday = datetime.strptime(date_str, "%d/%m/%Y")
  except TypeError:
    birthday = datetime.datetime(*(time.strptime(date_str, "%d/%m/%Y")[0:6]))
  return birthday

def days_remaining(birth_date):
  now = datetime.now()
  current_year = datetime(now.year, birth_date.month, birth_date.day)
  days = (current_year - now).days
  if days < 0:
    next_year = datetime(now.year+1, birth_date.month, birth_date.day)
    days = (next_year - now).days
  return days

birthday = get_user_birthday()
next_birthday = days_remaining(birthday)
print("Your birthday is coming in: ", next_birthday, " days")
1 Answers

If you want to explicitly call something from timedelta you need to import it; but the date arithmetic functions in datetime.datetime will sometimes return a datetime.timedelta object whose methods you can then access directly, often without reflecting on, or even knowing, its type or methods.

Internally, subtraction using the arithmetic minus - operation simply calls the __sub__ method of the first operand; this is how you are able to use (what looks like) simple subtraction on objects which are not numbers (and, as a matter of fact, also objects which are numbers :-)

To reiterate, datetime.datetime has to import datetime.timedelta, but it can then return an object created by this module to you, and you don't have to know or care that it did. As long as the returned object supports the methods you are calling on it, you will be fine.

More generally, many libraries which you import will give you back objects of types you didn't have to import, from that module, or another one entirely. You only need to explicitly import something if you explicitly want to refer to a symbol from that module (catch a named error, instantiate or inherit from a specific class, etc). The rest of the time (and it probably happens more often than you would imagine at first) you don't need to pay much attention to this, because it's just a relatively insignificant implementation detail.

Related