Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialRoderick Hung
Front End Web Development Techdegree Graduate 23,182 PointsWrite code that finds all upcoming birthdays in the next 90 days.
So the project is requesting the user to find all the upcoming birthdays this year and within 90 days from today.
But I want to find all the upcoming birthdays in the next 90 days from today. How would I compare datetime objects? Here is my code below:
from dateutil import relativedelta
import datetime
def upcoming_birthdays(people_list, days):
# TODO: write code that finds all upcoming birthdays in the next 90 days
# 90 is passed in as a parameter from menus.py
# Template:
# PERSON turns AGE in X days on MONTH DAY
# PERSON turns AGE in X days on MONTH DAY
for person in people_list:
format_string = "%Y-%m-%d"
birthday_dt = datetime.datetime.strptime(person['birthday'], format_string)
now = datetime.datetime.now()
time_delta = datetime.timedelta(days)
future = now + time_delta
if now <= birthday_dt <= future:
4 Answers
Mark Sebeck
Treehouse Moderator 38,004 PointsRoderick Hung thanks for clarifying. I now understand the question better. I have a quick and dirty solution. I'm sure there is a cleaner way to do this. I am finding birthday this year and next and subtracting both from now. If one of those days are between 0 and 90 then the birthday is within 90 days. You will need to print the proper days until birthday. You can see in my test it was negative.
import datetime
from dateutil import relativedelta
def upcoming_birthdays(people_list, days):
# TODO: write code that finds all upcoming birthdays in the next 90 days
# 90 is passed in as a parameter from menus.py
# Template:
# PERSON turns AGE in X days on MONTH DAY
# PERSON turns AGE in X days on MONTH DAY
for person in people_list:
format_string = "%Y-%m-%d"
birthday_dt = datetime.datetime.strptime(person['birthday'], format_string)
# Using datetime of December 23,2023
now = datetime.datetime.now()
#now = datetime.datetime(2023, 12, 23)
birthday_this_year = birthday_dt.replace(year=now.year)
birthday_next_year = birthday_dt.replace(year=now.year+1)
print(f"now<{now}>")
print(f"birthday_this_year<{birthday_this_year}>")
print(f"birthday_next_year<{birthday_next_year}>")
print(f"birthday_next_year-now<{birthday_next_year-now}>")
print(f"birthday_this_year-now<{birthday_this_year-now}>")
birthday_this_year = birthday_dt.replace(year=now.year)
difference = birthday_this_year - now
turning_age = relativedelta.relativedelta(now, birthday_dt).years +1
if ((birthday_this_year-now).days > 0 and (birthday_this_year-now).days <= 90) or ((birthday_next_year-now).days > 0 and (birthday_next_year-now).days <= 90):
print(f"{person['name']} turns {turning_age} in {difference.days} days on {birthday_dt.strftime('%B %d')}")
upcoming_birthdays([{'name': 'mark', 'birthday': '1980-01-01'}], 360)
treehouse:~/workspace$ python new.py
now<2023-12-23 00:00:00>
birthday_this_year<2023-01-01 00:00:00>
birthday_next_year<2024-01-01 00:00:00>
birthday_next_year-now<9 days, 0:00:00>
birthday_this_year-now<-356 days, 0:00:00>
mark turns 44 in -356 days on January 01
treehouse:~/workspace$ python new.py
now<2024-01-06 05:30:24.410175>
birthday_this_year<2024-01-01 00:00:00>
birthday_next_year<2025-01-01 00:00:00>
birthday_next_year-now<360 days, 18:29:35.589825>
birthday_this_year-now<-6 days, 18:29:35.589825>
treehouse
Mark Sebeck
Treehouse Moderator 38,004 PointsHi Roderick Hung . Just to be clear I think you are trying to find the same answer as the video just a different way? Instead of finding the days from today the birthday is you want to compare dates correct? I think your logic is correct. Are you getting an error? You might have to tell timedelta you are using days. Try
time_delta = datetime.timedelta(days = days)
Roderick Hung
Front End Web Development Techdegree Graduate 23,182 PointsThanks for the reply Mark Sebeck
I am trying to challenge myself and go beyond the ask of the app directions.
I want to write code that finds all upcoming birthdays in the next 90 days.
The app's direction in the video Rachel says, "Now we want to calculate everyone's birthday based on this year's upcoming birthday.
Rachel's code will only show upcoming birthdays that are coming up in the same year and within 90 days.
Below, I have copied the code exactly from the video, with the exception of now = "2023-12-23". When I run the code it shows a blank list because there are no more upcoming birthdays within the year that are within 90 days.
How can I show a list of upcoming birthdays within 90 days if the variable "now" is "2023-12-23"?
def upcoming_birthdays(people_list, days):
# TODO: write code that finds all upcoming birthdays in the next 90 days
# 90 is passed in as a parameter from menus.py
# Template:
# PERSON turns AGE in X days on MONTH DAY
# PERSON turns AGE in X days on MONTH DAY
for person in people_list:
format_string = "%Y-%m-%d"
birthday_dt = datetime.datetime.strptime(person['birthday'], format_string)
# Using datetime of December 23,2023
now = datetime.datetime.now()
birthday_this_year = birthday_dt.replace(year=now.year)
difference = birthday_this_year - now
turning_age = relativedelta.relativedelta(now, birthday_dt).years +1
if 0 < difference.days < days:
print(f"{person['name']} turns {turning_age} in {difference.days} days on {birthday_dt.strftime('%B %d')}")
Roderick Hung
Front End Web Development Techdegree Graduate 23,182 PointsThanks Mark Sebeck. I had written my code this way below:
for person in people_list:
format_string = "%Y-%m-%d"
now = datetime.datetime.now()
birthday_dt = datetime.datetime.strptime(person['birthday'], format_string)
birthday_this_year = birthday_dt.replace(year=now.year)
time_delta = datetime.timedelta(days)
future = now + time_delta
difference = birthday_this_year - now
turning_age = relativedelta.relativedelta(now, birthday_dt).years +1
if now <= birthday_this_year < future:
print(f"{person['name']} turns {turning_age} in {difference.days} days on {birthday_dt.strftime('%B %d')}")
else:
birthday_next_year = birthday_this_year.replace(year=now.year +1)
difference_next_year = birthday_next_year - now
if now <= birthday_next_year < future:
print(f"{person['name']} turns {turning_age} in {difference_next_year.days} days on {birthday_dt.strftime('%B %d')}")
Gerald Bishop
Python Development Techdegree Graduate 16,897 PointsHere is my version of showing birthdays coming up in the next 90 days irrespective of whether they are in the current calendar year or in the next one.
import datetime
from dateutil import relativedelta
def upcoming_birthdays(people_list, days):
# TODO: write code that finds all upcoming birthdays in the next 90 days
# 90 is passed in as a parameter from menus.py
# Template:
# PERSON turns AGE in X days on MONTH DAY
# PERSON turns AGE in X days on MONTH DAY
for i in range(len(people_list)):
format = "%Y-%m-%d"
birthday = datetime.datetime.strptime(people_list[i]['birthday'], format)
today = datetime.date(2023,12,31)
age = relativedelta.relativedelta(today, birthday)
next_bd = datetime.date(year= birthday.year + age.years + 1, month=birthday.month, day=birthday.day)
cut_off = today + datetime.timedelta(days=days)
if next_bd < cut_off:
name = people_list[i]['name']
count_days = next_bd - today
print(f"{name} turns {age.years+1} in {count_days.days} days on {birthday.strftime('%B %d')}")