'Trying to define a function that will take an argument that's a DOB and returns the number of days until their next birthday
I'm attempting to def a function where I input an argument that's a variable assigned a date value (a birthday). This function should then use that birthday to calculate how many days until the person's next birthday.
I've imported from from dateutil.relativedelta import relativedelta and from datetime import date.
I know what I need to be able to do is take the inputed argument that is the birthday to find the age of the person. From there I'll have to add that age + 1 to the DOB to get the date of their next birthday. With the date of their next birthday I can subtract today's date from it, and get the result I want: the number of days from today until their next birthday.
But I haven't been able to wrap my head around how to do it. I know how to take a date and use the relativedelta() function to get another date, as I defined a function to take someone's DOB and determine what day they'd be eligible to vote in US elections (18 yrs old):
birthday = date(1993, 5, 19)
def when_can_vote_us(birthday):
vote_date = birthday + relativedelta(years=+18)
return vote_date
when_can_vote_us(birthday)
But I don't know how to get the next birthday date without erroring out: trying something like
birth_date = date(1990, 1, 1)
def make_birthday_announcement(name, birth_date):
today = date.today()
age = today - birth_date
next_birthday = birth_date + relativedelta(years=+(age+1))
days_until_next_bday = next_birthday - today
return days_until_next_bday
gives me this error:
Input In [1], in make_birthday_announcement(name, birth_date)
3 today = date.today()
4 age = today - birth_date
----> 5 next_birthday = birth_date + relativedelta(years=+(age+1))
6 days_until_next_bday = next_birthday - today
7 return days_until_next_bday
TypeError: unsupported operand type(s) for +: 'datetime.timedelta' and 'int'
I don't know how else to do it.
Solution 1:[1]
The datetime module can handle the basic version of this more-or-less on its own.
def next_birthday(dob):
today = datetime.date.today()
# birthdays after today should be in this year
if (dob.month, dob.day) >= (today.month, today.day):
return datetime.date(today.year, dob.month, dob.day)
# birthdays before today should be in next year
return datetime.date(today.year + 1, dob.month, dob.day)
Note: The above function will return today if the person's birthday is today.
There's one issue with that function: What if the person's birthday is on February 29th?
That's a leap day that only happens on leap years, so the answer is ambiguous. Do they only have birthdays on the actual 29th of February? If so, their next birthday could be 4 or even 8 years from now if the leap year cycle is in the right place. Should they instead have a birthday on the closest day in the current year's calendar? If so, then should that day be Feb 28 or Mar 1?
I think that giving a ValueError for instances where this question arises is reasonable for the default behavior, and that's what the above function does. But you many want to include more advanced options for selecting which way to handle Feb 29th.
PS: Leap year birthdays are one of my favorite examples of a little detail that greatly complicates a seemingly simple problem.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Pi Marillion |
