Age of a person

Hello everybody! how can I calculate the age of a person in home assistant? Thank you very much!

The person class does not have any attribute you can base your calculation on

Yes I know, so I ask if there is any way to calculate it

If you were to create an input_datetime for the persons date of birth then you could use a calculation based on todays date to determine the age.

1 Like

You can make a template sensor like:

sensor:
  - platform: template
    sensors:
      age_someone:
        value_template: >
          {% set today = now() %}
          {% set birthday = (1990, 11, 20)%}
          {{ today.year - birthday[0] - ((today.month, today.day) < (birthday[1], birthday[2])) }}

This is display the correct age.

2 Likes

I thought there had to be a better way! Nice

oh it’s fantastic and it works perfectly. Thank you very much basnijholt

Anyway thank you very much!

Thanks for the great template. here is my updated one. it will give the age in months, weeks, and days as attributes
Months and Days as attributes

- platform: template
  sensors:
    age_someone:
      friendly_name: someone's Birthday
      value_template: >
        {% set today = now() %}
        {% set birthday = (2020, 11, 15)%}
        {{ today.year - birthday[0] - ((today.month, today.day) < (birthday[1], birthday[2])) }}
      attribute_templates:
        months: >
          {% set today = now() %}
          {% set birthday = (2020, 11, 15)%}
          {{ (today.month - birthday[1] - (today.day < birthday[2]) | int) }}
        days: >
          {{ (as_timestamp(now()) - as_timestamp('2020-11-15')) | timestamp_custom('%d') }}

Months, Weeks, and Days as attributes
useful if you are tracking infant age

- platform: template
  sensors:
    age_someone:
      friendly_name: someone's Birthday
      value_template: >
        {% set today = now() %}
        {% set birthday = (2020, 11, 15)%}
        {{ today.year - birthday[0] - ((today.month, today.day) < (birthday[1], birthday[2])) }}
      attribute_templates:
        months: >
          {% set today = now() %}
          {% set birthday = (2020, 11, 15)%}
          {{ (today.month - birthday[1] - (today.day < birthday[2]) | int) }}
        weeks: >
          {{ ((as_timestamp(now()) - as_timestamp('2020-11-15')) | timestamp_custom('%d')| int / 7) |int }}
        days: >
          {{((as_timestamp(now()) - as_timestamp('2020-11-15')) | timestamp_custom('%d')| int ) -( ((((as_timestamp(now()) - as_timestamp('2020-11-15')) | timestamp_custom('%d')| int / 7) |int) * 7 ))}}
2 Likes

It would be nice to have some of this built in to HA. Like every person might have sensors entities attached for their current age, a binary sensor for whether or not it’s their birthday, etc. Imagine if every person in the house could have a bio, and even state preferences… so if I’m in a room, the lights go to 5000K, but if my wife is in the room and I’m not, it goes to 4000K. If we’re both in the room… average to 4500K? :grinning: But seriously, if home automation is about improving the lives of people, we could be doing a lot more to understand and instrument and act on the preferences and important life moments of people.

EDIT: corrected “sensors” with “entities”.

4 Likes

Thanks for this, was really useful to have the option to display in either weeks and days, or just days.

However, it seems like there’s an issue with how the month is displayed
{{ (today.month - birthday[1] - (today.day < birthday[2]) | int) }}

If the birthday month occurs after the current month, it returns a negative instead (the actual value deducted from 12, basically)

Also, if I set a birthday exactly X years ago (eg 19 Feb 2020), it returns X years + 2 days instead.

Thanks for the help on starting!!

I know this is an old thread; but this is what I cam up with; I think its a little easier to see where you need to change the birthdays.

- platform: template
  sensors:
    age_daisy:
      friendly_name: Daisy's Birthday
      value_template: "1"
      attribute_templates:
        years: >
          {% set birthday = as_datetime('2021-03-30') %}
          {% set daysOld = (now().today() - birthday).days %}
          {{ (daysOld // 365.25) |int }}
        months: >
          {% set birthday = as_datetime('2021-03-30') %}
          {% set daysOld = (now().today() - birthday).days %}
          {{ (daysOld % 365.25 // 30.42) |int }}
        weeks: >
          {% set birthday = as_datetime('2021-03-30') %}
          {% set daysOld = (now().today() - birthday).days %}
          {{ (daysOld % 365.25 % 30.42 // 7) |int }}
        daysW: >
          {% set birthday = as_datetime('2021-03-30') %}
          {% set daysOld = (now().today() - birthday).days %}
          {{ (daysOld % 365.25 % 30.42 % 7) |int }}
        daysM: >
          {% set birthday = as_datetime('2021-03-30') %}
          {% set daysOld = (now().today() - birthday).days %}
          {{ (daysOld % 365.25 % 30.42) |int }}

This is the template widget I made for my phone

{% set years = state_attr('sensor.age_daisy', 'years') %}
{% set months = state_attr('sensor.age_daisy', 'months') %}
{% set weeks = state_attr('sensor.age_daisy', 'weeks') %}
{% set days = state_attr('sensor.age_daisy', 'daysW') %}

Daisy
{% if(years is not none) %}{{ years }} year{% if(years > 1) %}s{% endif %} {% endif %}{% if(months is not none) %}{{ months }} month{% if(months > 1) %}s{% endif %} {% endif %}{% if(weeks is not none) %}{{ weeks }} week{% if(weeks > 1) %}s{% endif %} {% endif %}{% if(days is not none) %}{{ days }} day{% if(days > 1) %}s{% endif %}{% endif %}

Daisy 1 year 3 months 3 weeks 6 days

1 Like

Thanks for this, nicking it now :slight_smile:

Hi there! I would need some help. Where should I put this code? I added the first in the templates yaml and got that working. But I cant figure out where to put the last part.

You can put that code in a template card on your dashboard

1 Like

Also a note for everyone else on this thread: if you want to add a birthday to a person entity, you can do that under the customize section:

customize:
  person.my_name:
    birthday: '2000-12-31'

You can then reference it in templates via

{{ state_attr('person.my_name', 'birthday') }}
{% set birthday = state_attr('person.my_name', 'birthday') | as_datetime | as_local %}
{% set last_birthday = [birthday.replace(year=now().year), birthday.replace(year=now().year-1)] | reject('gt',today_at()) | sort | last %}
{% set next_birthday = [birthday.replace(year=now().year), birthday.replace(year=now().year+1)] | reject('lt',today_at()) | sort | first %}
1 Like

Firstly, thank you. When I look at the code, it looks correct, but it does not calculate correctly.
Core: 2024.4.1

What doesn’t calculate correctly? The template excludes the end date, but IMO is still accurate. There are several methods to achieve time duration calculations, but your reply doesn’t define what is wrong when applied to your use case.

Actually it should be 5 months and 12 days. But the calculation is wrong and the number of days tomorrow may be 0.

The calculation is based on average months and average years… handling irregular units like those accurately is a more complicated calculation. You may want to take a look at:

{%- set birth = "2023-11-28" %}
{% from 'relative_time_plus.jinja' import relative_time_plus %}
{{ relative_time_plus(birth, always_show=['yr', 'mth', 'day'], parts=3)}}
1 Like