Age from date of birth in Drupal 7

In this tutorial I’m gonna show you how to calculate and display properly the age from a date CCK field the simplest way. The method I’m about to show you doesn’t need the Views module and if you use Views you’ll find that it’s totally compatible without adding any PHP code.

Requirements

Before starting I want you to meet the following requirements in order to follow this tutorial:

  • Install and enable the Computed_field module
  • Install and enable the Date module (Date API, Date & Date popup)
  • Install and enable the Rules module
  • Enable the core PHP filter module
  • Add a date field to an existing content type (let’s call it field_dob)

For the purpose of this tutorial I created a very simple content type named Candidate with only 2 fields:

  • I changed the title from Title to Full name and removed the Body field
  • I added a Date field and named it field_dob

Add a computed field

Now let’s add a new field with Age as a label and field_age as a name and Computed as a field type.
In the next screen we will set the field settings:

  • Computed Code (PHP):
    $entity_field[0]['value'] = ( time() - strtotime($entity->field_dob[LANGUAGE_NONE][0]['value']) ) / 86400 / 365.25;
    
  • Display Code (PHP):
    $display_output = floor($entity_field_item['value']);
  • Data type: Decimal
  • Decimal Scale (decimal): 3

Add content and test

Now let’s add a few items and see if it works as we expected, I added a couple of entries and tested:

  • Old KADIMI (born on 1 Jan 1990) => Age computed 21
  • Young KADIMI (born on 2 Jan 1990) => Age computed 21

Sorting with Views

You may want to use the Views module to accommodate the output to your needs, one of the features of the Views module is that it enable you to sort results.

So what if we wanted to sort our candidates by age, Both KADIMI brothers (Old and Young) are 21 years old but Old is 1 day older that Young, for Drupal they have the same age and the result of the sorting may be inaccurate, actually we already fixed this issue by storing the age as a decimal number with 3 decimal points and displaying it as an integer (by using floor), by looking into the database table field_data_field_age with phpMyAdmin:

  • Young KADIMI is 21.570 years old
  • Old KADIMI is 21.573 yeas old

Update age

In order to recompute a candidate age we must re-save that candidate node, one way to do this is using Rules and Drupal cron

  • Visit /admin/config/workflow/rules/reaction/add to add a rule, give it a descriptive name like “Re-save candidates nodes”
    Set React on event to: Cron maintenance tasks are performed
  • Add a new action
    Set Select the action to add to: Execute custom PHP code
    Set the PHP code to:

    $old   = '1 day';      # Content is considered outdated if older than {$old}
    $type  = 'candidate';  # Apply to nodes of type {$type}
    $limit = 20;           # Update {$limit} nodes per cron
     
    $old = strtotime("now - $old");
    
    $sql = '
      SELECT n.nid FROM {node} n
      WHERE n.type = :type
        AND n.changed  < :old
      ORDER BY n.changed ASC
      LIMIT :limit
    ';
    
    $sql_vars = [
      ':type' => $type,
      ':old' => $old,
      ':limit' => $limit,
    ];
    
    $nids = db_query($sql, $sql_vars);
     
    foreach ($nids as $nid){
       $node = node_load($nid);
       node_save($node);
    }

    Tweak the 3 parameters in a way that suits your needs and that’s it!

Need help?

If you found this tutorial difficult and couldn’t follow the instructions you can ask for help on the comments section or you can hire me and I will take care of this for you.

22 thoughts on “Age from date of birth in Drupal 7

It works for dates later than ’12/14/1901’… I don’t know why, I will update as soon as I know something:

echo $age = ( time() - strtotime('12/14/1901') )/ 86400 / 365.25; // 109.87949428981
echo $age = ( time() - strtotime('01/01/1901') )/ 86400 / 365.25; // 41.830216461328

I did this and it works great except now when I create an exposed filter in views if I put 23 as the max age it doesnt bring up any of the people who are 23 because in the computers mind they are older then 23, they are 23.1 or wtvr.

You have two solutions:
1 – Setup another custom field where the age is stored as an integer and filter on this field
or
2 – Use two filters (min and max)

Thanks! Switching the field to be stored as an integer worked.

I am now working on the Update age php and I just want to make sure I did this correctly. I switched where it says candidate by type to what my content type is called and I changed the count to 100 so it does more nodes per cron. Is that what I was supposed to do to customize it for my site?

So after adding the Update Age php I noticed I get errors when running the cron and my site has lines of error code on it.

Any idea?

Thanks

Turns out that switching the age filed to be an integer does not work because then it doesnt calculate correctly. Also I tried the Min and Max for the filters and its still not working.

Thanks

Thank you for this tutorial.
What do I change in the Rules PHP code to use for user field instead of node field? I would like to update the user’s account at midnight on the birthday. Thanks.

Life saving (metaphorically speaking) tutorial!! Thanks.

What do you change the PHP Update age code to for use with Users? Seams more relevant when talking about age. Would you change all $nid to $uid and $node to $user?

e.g.
$old = ‘1 day’; # Content is considered outdated if older than {$old}
$type = ‘user’; # Apply to nodes of type {$type}
$limit = 20; # Update {$limit} nodes per cron

$old = strtotime(“now – $old”);

$sql = ‘
SELECT n.nid FROM {user} n
WHERE n.type = :type
AND n.changed $type,
‘:old’ => $old,
‘:limit’ => $limit,
];

$uids = db_query($sql, $sql_vars);

foreach ($uids as $uid){
$user = user_load($uid);
user_save($user);
}

i have problem !
what if:
today: July 8, 1989
birth day : July 9, 1989
my age should be 22, but your code display 23 !?
any help 🙂

Did you find a solution to this? I’m having the same problem with some of my profiles, but not all of them xD

Thanks for your tutorial. I found that easier way is to create “code field” in Display Suite. That don’t need any cron task.

hi please just for precision

WHERE n.type = :type AND n.created  $old, ":type"=>$type 

should it be the table n.created or n.changed

Nabil , one more question please

i the PHP code , didn’t see were the $count variable that suppose to limit the number of node to be fetched for resave.

Leave a Reply to Amine Cancel reply

Your email address will not be published. Required fields are marked *