Map column birthdates in python pandas df to astrology signs - python

I have a dataframe with a column that includes individuals' birthdays. I would like to map that column to the individuals' astrology sign using code I found (below). I am having trouble writing the code to creat the variables.
My current dataframe looks like this
birthdate answer YEAR MONTH-DAY
1970-03-31 5 1970 03-31
1970-05-25 9 1970 05-25
1970-06-05 3 1970 06-05
1970-08-28 2 1970 08-28
The code I found that creates a function to map the dates is available at this website: https://www.geeksforgeeks.org/program-display-astrological-sign-zodiac-sign-given-date-birth/
Any tips would be appreciated.

Change previous answer by Series.dt.month_name with lowercase strings:
def zodiac_sign(day, month):
# checks month and date within the valid range
# of a specified zodiac
if month == 'december':
return 'Sagittarius' if (day < 22) else 'capricorn'
elif month == 'january':
return 'Capricorn' if (day < 20) else 'aquarius'
elif month == 'february':
return 'Aquarius' if (day < 19) else 'pisces'
elif month == 'march':
return 'Pisces' if (day < 21) else 'aries'
elif month == 'april':
return 'Aries' if (day < 20) else 'taurus'
elif month == 'may':
return 'Taurus' if (day < 21) else 'gemini'
elif month == 'june':
return 'Gemini' if (day < 21) else 'cancer'
elif month == 'july':
return 'Cancer' if (day < 23) else 'leo'
elif month == 'august':
return 'Leo' if (day < 23) else 'virgo'
elif month == 'september':
return 'Virgo' if (day < 23) else 'libra'
elif month == 'october':
return 'Libra' if (day < 23) else 'scorpio'
elif month == 'november':
return 'scorpio' if (day < 22) else 'sagittarius'
dates = pd.to_datetime(astrology['birthdate'])
y = dates.dt.year
now = pd.to_datetime('now').year
astrology = astrology.assign(month = dates.dt.month_name().str.lower(),
day = dates.dt.day,
year = y.mask(y > now, y - 100))
print (astrology)
birthdate answer YEAR MONTH-DAY month day year
0 1970-03-31 5 1970 03-31 march 31 1970
1 1970-05-25 9 1970 05-25 may 25 1970
2 1970-06-05 3 1970 06-05 june 5 1970
3 1970-08-28 2 1970 08-28 august 28 1970
astrology['sign'] = astrology.apply(lambda x: zodiac_sign(x['day'], x['month']), axis=1)
print (astrology)
birthdate answer YEAR MONTH-DAY month day year sign
0 1970-03-31 5 1970 03-31 march 31 1970 aries
1 1970-05-25 9 1970 05-25 may 25 1970 gemini
2 1970-06-05 3 1970 06-05 june 5 1970 Gemini
3 1970-08-28 2 1970 08-28 august 28 1970 virgo

You can apply the zodiac_sign function to the dataframe as -
import pandas as pd
from io import StringIO
# Sample
x = StringIO("""birthdate,answer,YEAR,MONTH-DAY
1970-03-31,5,1970,03-31
1970-05-25,9,1970,05-25
1970-06-05,3,1970,06-05
1970-08-28,2,1970,08-28
""")
df = pd.read_csv(x, sep=',')
df['birthdate'] = pd.to_datetime(df['birthdate'])
df['zodiac_sign'] = df['birthdate'].apply(lambda x: zodiac_sign(x.day, x.strftime("%B").lower()))
print(df)
Output:
birthdate answer YEAR MONTH-DAY zodiac_sign
0 1970-03-31 5 1970 03-31 aries
1 1970-05-25 9 1970 05-25 gemini
2 1970-06-05 3 1970 06-05 Gemini
3 1970-08-28 2 1970 08-28 virgo

Related

How can i find all 'friday the 13th' due year 2000 to 2020 by python

How can i find all 'friday the 13th' due year 2000 to 2020 by python and have it print as below using a nested for loop:
print(i,k,13,"is friday the 13th!")
ex)
2000 10 13 is friday the 13th!
2001 4 13 is friday the 13th!
...
2020 11 13 is friday the 13th!
Based on your code in the comments, this should work for you:
from datetime import date, timedelta
def friday_13_in_year(y):
day = date(y, 1, 1)
end = date(y, 12, 31)
one_day = timedelta(days=1)
while day < end:
if day.weekday() == 4 and day.day == 13:
return str(day)+" is friday the 13th!"
day += one_day
print([friday_13_in_year(y) for y in range(2000, 2022+1)])
l=[i for i in ((datetime.datetime.strptime('20000101','%Y%m%d')+datetime.timedelta(days=i)) for i in range(7306)) if i.day == 13 and i.weekday() == 4]
l lists all Fridays 13th from 2000 to 2020. 20 years in days is 20*365.25+1 = 7306

python nested while loops and datetime

I'm teaching myself python to ATBS. Instead of spending 45 minutes typing out a bunch of repetitive data in excel I've spent the past 90 failing to write a simple calendar script.
Starting with the values "2012-09-01" and "2012-09-30" I want to each line to increase the month value by 1 it hits 12 and at which point the year value advances by 1, until the date 2018-12-31.
e.g.
"2012-09-01 2012-09-30
2012-10-01 2012-10-31
2012-11-01 2012-11-30
2012-12-01 2012-12-31"
Here's my code, which stops at 2012-12-31.
import datetime
year = 2012
month = 9
day_start = 1
day_end = 31
while year <= 2018:
while month <= 12:
if month == 4 or month == 6 or month == 9 or month == 11:
day_end = 30
else:
day_end = 31
print(datetime.date(year, month, day_start), " ", datetime.date(year, month, day_end))
month = month + 1
year = year + 1
Any help is much appreciated!
Check this out. Using the calendar library to detect leap years.
import datetime
import calendar
year = 2012
month = 9
day_start = 1
day_end = 31
while year <= 2018:
while month <= 12:
if month == 4 or month == 6 or month == 9 or month == 11:
day_end = 30
elif month == 2:
day_end = 29 if calendar.isleap(year) else 28
else:
day_end = 31
print(datetime.date(year, month, day_start), " ", datetime.date(year, month, day_end))
month = month + 1
year = year + 1
month = 1
Line
if month == 4 or month == 6 or month == 9 or month == 11:
can be abbreviated to:
if month in (4, 6, 9, 11):

Unexpected input value detection for dates in Zodiac calendar sample

I'm doing a task in Python, which is to create a zodiac calendar judging by input month and day of the month.
I've made a successful calendar, however, I have no idea how to solve the problem, if I input an incorrect month name or nonexistent date.
I have tried tons of things: to create a different hierarchy, or under each zodiac sign I wrote else: print ('Entering an incorrect date'). I even tried to register with if day <0 and day> 31 or month! = 'March' or month! = 'April', etc... It turned out to be a huge useless function in the end, and nothing worked either.
I feel that there is a one-line solution here to detect days < 0 and > 31 and incorrect month name, but I just can't understand it. Could somebody help, please?
month = input('Enter the month: ')
day = int(input ('Enter the date of month: '))
if day >= 21 and day <= 31 and month.lower() == 'march' or day >=1 and day <= 19 and month.lower() == 'april':
zodiac='Aries'
if day >= 20 and day <= 30 and month.lower() == 'april' or day >=1 and day <= 19 and month.lower() == 'may':
zodiac='Taurus'
if day >= 21 and day <= 31 and month.lower() == 'may' or day >=1 and day <= 20 and month.lower() == 'june':
zodiac='Gemini'
if day >= 21 and day <= 30 and month.lower() == 'june' or day >=1 and day <= 22 and month.lower() == 'july':
zodiac='Cancer'
if day >= 23 and day <= 31 and month.lower() == 'july' or day >=1 and day <= 22 and month.lower() == 'august':
zodiac='Leo'
if day >= 23 and day <= 31 and month.lower() == 'august' or day >=1 and day <= 22 and month.lower() == 'september':
zodiac='Virgo'
if day >= 23 and day <= 30 and month.lower() == 'september' or day >=1 and day <= 22 and month.lower() == 'october':
zodiac='Libra'
if day >= 23 and day <= 31 and month.lower() == 'october' or day >=1 and day <= 21 and month.lower() == 'november':
zodiac='Scorpio'
if day >= 22 and day <= 30 and month.lower() == 'november' or day >=1 and day <= 21 and month.lower() == 'december':
zodiac='Sagittarius'
if day >= 22 and day <= 31 and month.lower() == 'december' or day >=1 and day <= 19 and month.lower() == 'january':
zodiac='Capricorn'
if day >= 20 and day <= 31 and month.lower() == 'january' or day >=1 and day <= 18 and month.lower() == 'february':
zodiac='Aquarius'
if day >= 19 and day <= 28 and month.lower() == 'february' or day >=1 and day <= 20 and month.lower() == 'march':
zodiac='Pisces'
print('Conclusion:')
print(zodiac)
You might want to look into the datetime module. With it, you can do comparisons between dates and times easily without the need for extraneous if statements.
For example, if one were to do something like:
import datetime
dt = datetime.datetime.today()
print dt.month
Then you would get:
3
So instead of reading in input for months in a string format, you could simply ask for the number of the month to help create a datetime object more easily. Alternatively, you could do something like this:
month_input = input("What is the month?")
months = ["january", "february", "march", "april", "may", "june", "july", "august", "september", "october", "november", "december"]
month_input = month_input.lower().strip() #convert to lowercase and remove whitespace
month_num = months.index(month_input) + 1 #Add one because lists start at index 0
That way you can get the number of the month to use a datetime object to do your comparisons and evaluations from there.

How to Calculate the number of days in the year(s) between 2 dates in python

For example:
date 1 : 1 january 2000
date 2 : 17 november 2006
I want to know how many days there are between date 1 and date 2 in the year 2000, 2001, ..., 2006
so I need something that returns something like this (doesn't matter if it's in a list or something):
2000: 365, 2001: 365, ..., 2006: 320
I've looked for something like this on the internet but that only turned up ways to calculate the number of days/months/years between 2 dates
hm, try something like this:
import datetime, calendar
date1 = datetime.date(year1, month1, day1) # month and day are 1-base
date2 = datetime.date(year2, month2, day2)
days_in_first_year = (datetime.date(year1,12,31)-date1).days
days_in_last_year = (date2 - datetime.date(year2, 1, 1)).days
if year1 != year2:
n_days_list = [days_in_first_year]
for year in range(year1+1, year2): n_days_list.append(365 + (1*calendar.isleap(year)))
n_days_list.append(days_in_last_year)
else: n_days_list = [days_in_first_year + days_in_last_year]
haven't tested this, might be some off-by-one errors; make sure it does what you expect.
edit: correct the boundaries of the range() call, correctly handle year1 == year2
>>> start_date = datetime.datetime(2006, 7, 3)
>>> end_date = datetime.datetime(2012, 12, 21)
>>> years = range(start_date.year, end_date.year + 1)
>>> start, end = start_date, end_date + datetime.timedelta(1)
>>> for year in years:
... year_start = datetime.datetime(year, 1, 1, 0, 0)
... year_end = datetime.datetime(year + 1, 1, 1, 0, 0)
... print(year, min(end, year_end) - max(start, year_start))
...
2006 182 days, 0:00:00
2007 365 days, 0:00:00
2008 366 days, 0:00:00
2009 365 days, 0:00:00
2010 365 days, 0:00:00
2011 365 days, 0:00:00
2012 356 days, 0:00:00
UPDATE: You should probably add a datetime.timedelta(1) to the end date, because otherwise you'd be off with one day at the end. Fixed. But that depends on whether you want to include it or exclude it.
from datetime import date
DATE_END = date(2006, 11, 17)
def get_days(date_start):
return (DATE_END - date_start).days
starting_dates = [
date(2000, 1, 1),
date(2001, 1, 1),
date(2002, 1, 1),
]
print map(get_days, starting_dates)
Use this pseudocode to see if a year is a leap-year or not
if year modulo 400 is 0
then is_leap_year
else if year modulo 100 is 0
then not_leap_year
else if year modulo 4 is 0
then is_leap_year
else
not_leap_year
to create a list of all leap-years and the years that's not.
You can have something simply by doing this:
>>> from datetime import datetime
>>> d1 = datetime.strptime("30 Nov 00", "%d %b %y")
>>> (datetime.now() - d1).days
3907
two parts: build the date ranges as tuples with a start and end date, build a dictionary whose key is the year and the values are the days. I don't need to account for leap year in the calculation because that is automatic in the range calculation
date_ranges=[]
def buildDateRanges(start_year,start_month,start_day, end_year,end_month,end_day):
start_date=datetime.datetime(start_year,start_month,start_day)
end_date=datetime.datetime(end_year,end_month,end_day)
start_year=start_date.year
end_year=end_date.year
date_ranges=[]
if start_year != end_year:
for year in range(start_year,end_year+1):
if year==start_year:
date_ranges.append((start_date,datetime.datetime(start_date.year,12,31)))
elif year==end_year:
date_ranges.append((datetime.datetime(start_year+1,1,1),end_date))
else:
date_ranges.append((start_date,end_date))
return date_ranges
date_ranges=buildDateRanges(2006, 7, 3,2012,12,21)
def years_days(days):
years = days // 365
days = days % 365
return years, days
results={}
for i in range(len(date_ranges)):
start_date=date_ranges[i][0]
end_date=date_ranges[i][1]
days=(end_date-start_date).days
years,days=years_days(days)
year=start_date.year
print(years,days)
while True:
if year==end_date.year:
results[year]=days
else:
results[year]=365
year+=1
if year>end_date.year:
break
print(results)
output:
{2006: 181, 2007: 365.0, 2008: 365.0, 2009: 365.0, 2010: 365.0, 2011: 365.0, 2012: 356.0}
Convert both days into seconds since the epoch (ie. 1 Jan 1970 Midnight)
Subtract.
The do the division to convert seconds into days for the difference.

Age from birthdate in python

How can I find an age in python from today's date and a persons birthdate? The birthdate is a from a DateField in a Django model.
That can be done much simpler considering that int(True) is 1 and int(False) is 0, and tuples comparison goes from left to right:
from datetime import date
def calculate_age(born):
today = date.today()
return today.year - born.year - ((today.month, today.day) < (born.month, born.day))
from datetime import date
def calculate_age(born):
today = date.today()
try:
birthday = born.replace(year=today.year)
except ValueError: # raised when birth date is February 29 and the current year is not a leap year
birthday = born.replace(year=today.year, month=born.month+1, day=1)
if birthday > today:
return today.year - born.year - 1
else:
return today.year - born.year
Update: Use Danny's solution, it's better
from datetime import date
days_in_year = 365.2425
age = int((date.today() - birth_date).days / days_in_year)
In Python 3, you could perform division on datetime.timedelta:
from datetime import date, timedelta
age = (date.today() - birth_date) // timedelta(days=365.2425)
As suggested by #[Tomasz Zielinski] and #Williams python-dateutil can do it just 5 lines.
from dateutil.relativedelta import *
from datetime import date
today = date.today()
dob = date(1982, 7, 5)
age = relativedelta(today, dob)
>>relativedelta(years=+33, months=+11, days=+16)`
The simplest way is using python-dateutil
import datetime
import dateutil
def birthday(date):
# Get the current date
now = datetime.datetime.utcnow()
now = now.date()
# Get the difference between the current date and the birthday
age = dateutil.relativedelta.relativedelta(now, date)
age = age.years
return age
from datetime import date
def age(birth_date):
today = date.today()
y = today.year - birth_date.year
if today.month < birth_date.month or today.month == birth_date.month and today.day < birth_date.day:
y -= 1
return y
Unfortunately, you cannot just use timedelata as the largest unit it uses is day and leap years will render you calculations invalid. Therefore, let's find number of years then adjust by one if the last year isn't full:
from datetime import date
birth_date = date(1980, 5, 26)
years = date.today().year - birth_date.year
if (datetime.now() - birth_date.replace(year=datetime.now().year)).days >= 0:
age = years
else:
age = years - 1
Upd:
This solution really causes an exception when Feb, 29 comes into play. Here's correct check:
from datetime import date
birth_date = date(1980, 5, 26)
today = date.today()
years = today.year - birth_date.year
if all((x >= y) for x,y in zip(today.timetuple(), birth_date.timetuple()):
age = years
else:
age = years - 1
Upd2:
Calling multiple calls to now() a performance hit is ridiculous, it does not matter in all but extremely special cases. The real reason to use a variable is the risk of data incosistency.
If you're looking to print this in a page using django templates, then the following might be enough:
{{ birth_date|timesince }}
The classic gotcha in this scenario is what to do with people born on the 29th day of February. Example: you need to be aged 18 to vote, drive a car, buy alcohol, etc ... if you are born on 2004-02-29, what is the first day that you are permitted to do such things: 2022-02-28, or 2022-03-01? AFAICT, mostly the first, but a few killjoys might say the latter.
Here's code that caters for the 0.068% (approx) of the population born on that day:
def age_in_years(from_date, to_date, leap_day_anniversary_Feb28=True):
age = to_date.year - from_date.year
try:
anniversary = from_date.replace(year=to_date.year)
except ValueError:
assert from_date.day == 29 and from_date.month == 2
if leap_day_anniversary_Feb28:
anniversary = datetime.date(to_date.year, 2, 28)
else:
anniversary = datetime.date(to_date.year, 3, 1)
if to_date < anniversary:
age -= 1
return age
if __name__ == "__main__":
import datetime
tests = """
2004 2 28 2010 2 27 5 1
2004 2 28 2010 2 28 6 1
2004 2 28 2010 3 1 6 1
2004 2 29 2010 2 27 5 1
2004 2 29 2010 2 28 6 1
2004 2 29 2010 3 1 6 1
2004 2 29 2012 2 27 7 1
2004 2 29 2012 2 28 7 1
2004 2 29 2012 2 29 8 1
2004 2 29 2012 3 1 8 1
2004 2 28 2010 2 27 5 0
2004 2 28 2010 2 28 6 0
2004 2 28 2010 3 1 6 0
2004 2 29 2010 2 27 5 0
2004 2 29 2010 2 28 5 0
2004 2 29 2010 3 1 6 0
2004 2 29 2012 2 27 7 0
2004 2 29 2012 2 28 7 0
2004 2 29 2012 2 29 8 0
2004 2 29 2012 3 1 8 0
"""
for line in tests.splitlines():
nums = [int(x) for x in line.split()]
if not nums:
print
continue
datea = datetime.date(*nums[0:3])
dateb = datetime.date(*nums[3:6])
expected, anniv = nums[6:8]
age = age_in_years(datea, dateb, anniv)
print datea, dateb, anniv, age, expected, age == expected
Here's the output:
2004-02-28 2010-02-27 1 5 5 True
2004-02-28 2010-02-28 1 6 6 True
2004-02-28 2010-03-01 1 6 6 True
2004-02-29 2010-02-27 1 5 5 True
2004-02-29 2010-02-28 1 6 6 True
2004-02-29 2010-03-01 1 6 6 True
2004-02-29 2012-02-27 1 7 7 True
2004-02-29 2012-02-28 1 7 7 True
2004-02-29 2012-02-29 1 8 8 True
2004-02-29 2012-03-01 1 8 8 True
2004-02-28 2010-02-27 0 5 5 True
2004-02-28 2010-02-28 0 6 6 True
2004-02-28 2010-03-01 0 6 6 True
2004-02-29 2010-02-27 0 5 5 True
2004-02-29 2010-02-28 0 5 5 True
2004-02-29 2010-03-01 0 6 6 True
2004-02-29 2012-02-27 0 7 7 True
2004-02-29 2012-02-28 0 7 7 True
2004-02-29 2012-02-29 0 8 8 True
2004-02-29 2012-03-01 0 8 8 True
import datetime
Todays date
td=datetime.datetime.now().date()
Your birthdate
bd=datetime.date(1989,3,15)
Your age
age_years=int((td-bd).days /365.25)
Expanding on Danny's Solution, but with all sorts of ways to report ages for younger folk (note, today is datetime.date(2015,7,17)):
def calculate_age(born):
'''
Converts a date of birth (dob) datetime object to years, always rounding down.
When the age is 80 years or more, just report that the age is 80 years or more.
When the age is less than 12 years, rounds down to the nearest half year.
When the age is less than 2 years, reports age in months, rounded down.
When the age is less than 6 months, reports the age in weeks, rounded down.
When the age is less than 2 weeks, reports the age in days.
'''
today = datetime.date.today()
age_in_years = today.year - born.year - ((today.month, today.day) < (born.month, born.day))
months = (today.month - born.month - (today.day < born.day)) %12
age = today - born
age_in_days = age.days
if age_in_years >= 80:
return 80, 'years or older'
if age_in_years >= 12:
return age_in_years, 'years'
elif age_in_years >= 2:
half = 'and a half ' if months > 6 else ''
return age_in_years, '%syears'%half
elif months >= 6:
return months, 'months'
elif age_in_days >= 14:
return age_in_days/7, 'weeks'
else:
return age_in_days, 'days'
Sample code:
print '%d %s' %calculate_age(datetime.date(1933,6,12)) # >=80 years
print '%d %s' %calculate_age(datetime.date(1963,6,12)) # >=12 years
print '%d %s' %calculate_age(datetime.date(2010,6,19)) # >=2 years
print '%d %s' %calculate_age(datetime.date(2010,11,19)) # >=2 years with half
print '%d %s' %calculate_age(datetime.date(2014,11,19)) # >=6 months
print '%d %s' %calculate_age(datetime.date(2015,6,4)) # >=2 weeks
print '%d %s' %calculate_age(datetime.date(2015,7,11)) # days old
80 years or older
52 years
5 years
4 and a half years
7 months
6 weeks
7 days
Here is a solution to find age of a person as either years or months or days.
Lets say a person's date of birth is 2012-01-17T00:00:00
Therefore, his age on 2013-01-16T00:00:00 will be 11 months
or if he is born on 2012-12-17T00:00:00,
his age on 2013-01-12T00:00:00 will be 26 days
or if he is born on 2000-02-29T00:00:00,
his age on 2012-02-29T00:00:00 will be 12 years
You will need to import datetime.
Here is the code:
def get_person_age(date_birth, date_today):
"""
At top level there are three possibilities : Age can be in days or months or years.
For age to be in years there are two cases: Year difference is one or Year difference is more than 1
For age to be in months there are two cases: Year difference is 0 or 1
For age to be in days there are 4 possibilities: Year difference is 1(20-dec-2012 - 2-jan-2013),
Year difference is 0, Months difference is 0 or 1
"""
years_diff = date_today.year - date_birth.year
months_diff = date_today.month - date_birth.month
days_diff = date_today.day - date_birth.day
age_in_days = (date_today - date_birth).days
age = years_diff
age_string = str(age) + " years"
# age can be in months or days.
if years_diff == 0:
if months_diff == 0:
age = age_in_days
age_string = str(age) + " days"
elif months_diff == 1:
if days_diff < 0:
age = age_in_days
age_string = str(age) + " days"
else:
age = months_diff
age_string = str(age) + " months"
else:
if days_diff < 0:
age = months_diff - 1
else:
age = months_diff
age_string = str(age) + " months"
# age can be in years, months or days.
elif years_diff == 1:
if months_diff < 0:
age = months_diff + 12
age_string = str(age) + " months"
if age == 1:
if days_diff < 0:
age = age_in_days
age_string = str(age) + " days"
elif days_diff < 0:
age = age-1
age_string = str(age) + " months"
elif months_diff == 0:
if days_diff < 0:
age = 11
age_string = str(age) + " months"
else:
age = 1
age_string = str(age) + " years"
else:
age = 1
age_string = str(age) + " years"
# The age is guaranteed to be in years.
else:
if months_diff < 0:
age = years_diff - 1
elif months_diff == 0:
if days_diff < 0:
age = years_diff - 1
else:
age = years_diff
else:
age = years_diff
age_string = str(age) + " years"
if age == 1:
age_string = age_string.replace("years", "year").replace("months", "month").replace("days", "day")
return age_string
Some extra functions used in the above codes are:
def get_todays_date():
"""
This function returns todays date in proper date object format
"""
return datetime.now()
And
def get_date_format(str_date):
"""
This function converts string into date type object
"""
str_date = str_date.split("T")[0]
return datetime.strptime(str_date, "%Y-%m-%d")
Now, we have to feed get_date_format() with the strings like 2000-02-29T00:00:00
It will convert it into the date type object which is to be fed to get_person_age(date_birth, date_today).
The function get_person_age(date_birth, date_today) will return age in string format.
As I did not see the correct implementation, I recoded mine this way...
def age_in_years(from_date, to_date=datetime.date.today()):
if (DEBUG):
logger.debug("def age_in_years(from_date='%s', to_date='%s')" % (from_date, to_date))
if (from_date>to_date): # swap when the lower bound is not the lower bound
logger.debug('Swapping dates ...')
tmp = from_date
from_date = to_date
to_date = tmp
age_delta = to_date.year - from_date.year
month_delta = to_date.month - from_date.month
day_delta = to_date.day - from_date.day
if (DEBUG):
logger.debug("Delta's are : %i / %i / %i " % (age_delta, month_delta, day_delta))
if (month_delta>0 or (month_delta==0 and day_delta>=0)):
return age_delta
return (age_delta-1)
Assumption of being "18" on the 28th of Feb when born on the 29th is just wrong.
Swapping the bounds can be left out ... it is just a personal convenience for my code :)
Extend to Danny W. Adair Answer, to get month also
def calculate_age(b):
t = date.today()
c = ((t.month, t.day) < (b.month, b.day))
c2 = (t.day< b.day)
return t.year - b.year - c,c*12+t.month-b.month-c2
import datetime
def age(date_of_birth):
if date_of_birth > datetime.date.today().replace(year = date_of_birth.year):
return datetime.date.today().year - date_of_birth.year - 1
else:
return datetime.date.today().year - date_of_birth.year
In your case:
import datetime
# your model
def age(self):
if self.birthdate > datetime.date.today().replace(year = self.birthdate.year):
return datetime.date.today().year - self.birthdate.year - 1
else:
return datetime.date.today().year - self.birthdate.year
Slightly modified Danny's solution for easier reading and understanding
from datetime import date
def calculate_age(birth_date):
today = date.today()
age = today.year - birth_date.year
full_year_passed = (today.month, today.day) < (birth_date.month, birth_date.day)
if not full_year_passed:
age -= 1
return age
A slightly more elegant solution than #DannyWAdairs solution might be to work with the .timetuple() method [Python-doc]:
from datetime import date
def calculate_age(born):
today = date.today()
return today.year - born.year - (today.timetuple()[1:3] < born.timetuple()[1:3])
You can easily use this to generalize this further to increase its granularity to seconds, such that the age increments if it is greater than or equal to the number of seconds of that day, if born is for example a datetime object:
from datetime import datetime
def calculate_age_with_seconds(born):
today = datetime.now()
return today.year - born.year - (today.timetuple()[1:6] < born.timetuple()[1:6])
This will work for born both being a date or a datetime object.
serializers.py
age = serializers.SerializerMethodField('get_age')
class Meta:
model = YourModel
fields = [..,'','birthdate','age',..]
import datetime
def get_age(self, instance):
return datetime.datetime.now().year - instance.birthdate.year
You can use Python 3 to do all this. Just run the following code and see.
# Creating a variables:
greeting = "Hello, "
name = input("what is your name?")
birth_year = input("Which year you were born?")
response = "Your age is "
# Converting string variable to int:
calculation = 2020 - int(birth_year)
# Printing:
print(f'{greeting}{name}. {response}{calculation}')

Categories

Resources