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 trial

Python Python Dates and Times The Birthday App Upcoming birthdays

Roderick Hung
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Roderick Hung
Front End Web Development Techdegree Graduate 23,182 Points

Write 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
MOD
Mark Sebeck
Treehouse Moderator 37,799 Points

Roderick 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
MOD
Mark Sebeck
Treehouse Moderator 37,799 Points

Hi 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
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Roderick Hung
Front End Web Development Techdegree Graduate 23,182 Points

Thanks 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
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Roderick Hung
Front End Web Development Techdegree Graduate 23,182 Points

Thanks 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
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Gerald Bishop
Python Development Techdegree Graduate 16,897 Points

Here 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')}")