I created a date field called field_bday using CCK in my profile node type, then created a computed field type called age.

Here are the settings I used for the age field.

Label - Age
Widget Type - Computed
Help text - Blank
Default Value PHP Code - Blank
Required - not checked off
Number of values - 1

Computed Code:
if (!$node->nid) node_save($node);
$dob = $node->field_bday[0]['value'];
$now = time();
$then = strtotime($dob);

$diff = date('Y', $now) - date('Y', $then);

if($diff < 0) /* ideally you want to prevent this from happening */
echo '??? - negative age.';

if(($diff > 0) && (date('z',$now) < date('z',$then)))
$diff --;
$node_field[0]['value'] = $diff;

field_bday in the second line of code is the variable name for the birthdate field I make using the date widget.

Display this field - checked off.

Display Format -
$display = $node_field_item['value'];

Store using database settings below - checked off
Data type - int
Data length - 3
Default value - blank
Not NULL - checked off
Sortable - checked off

Now... I just need to figure out how to do a computed field to determine the western astrological sign, and possibly the Chinese one as well. I may make little images for each one just to make it cute but that can wait.

Any thoughts on what PHP would go in Computed Code in order to determine the astrological sign? Once I have the western one I can use it as an example to make the Chinese one as well. Smiling I will also post them attached to this question as well so people can use it/them.

Computed Field - http://drupal.org/project/computed_field
Date Field - http://drupal.org/project/date
CCK - http://drupal.org/project/cck

Comments

hershel’s picture

Download http://drupal.org/project/birthdays and look at the .module file. In there you will find code which computes astrological signs. :)

Passionate_Lass’s picture

I checked it out, its not compatible with content profile.

bryan julius’s picture

i experienced this when i compute the age ..

doomed’s picture

Passionate_Lass, i tried your code but its not working.

Are you sure it works on your end?

Keep in mind i'm just looking for a way to calculate age, not the horoscope stuff.

Passionate_Lass’s picture

Yes my code works fine on my end. Using my birthdate it gives me the correct age.

Computed Code:

if (!$node->nid) node_save($node);
  $dob = $node->field_bday[0]['value'];
        $now = time();
        $then = strtotime($dob);

        $diff = date('Y', $now) - date('Y', $then);

        if($diff < 0)      /* ideally you want to prevent this from happening */
           echo '??? - negative age.';

        if(($diff > 0) && (date('z',$now) < date('z',$then)))
           $diff --;
$node_field[0]['value'] = $diff;

Display Format:

$display = $node_field_item['value'];

Remember that you need to change field_bday to whatever the fieldname is in your case.

doomed’s picture

Passionate_Lass, that worked now, thank you!

Passionate_Lass’s picture

Yay.

I coded the astrological sign, and the Chinese horoscope field as well. If you want the code for those let me know.

Witch’s picture

it works! what a great thing!!!!!

thank you so much! thank you so much!

der_sensemann’s picture

no matter which code example i tried, it all ends up in
"The default value PHP code returned an incorrect value."

btw: is it important how the birthday-date is stored?

- Jo

Passionate_Lass’s picture

Check this detailed tutorial I wrote. I believe that yes the way it is stored is probably important.

http://drupalsn.com/learn-drupal/drupal-tutorials/user-age-date-birth-%E...

BigBroz’s picture

Passionate_Lass,
many thanks for your age computed field it is very useful for my project.
Can You post the code for astrological field too, or send it to on my e-mail?

bigbroz(at)mail.ru

Passionate_Lass’s picture

Check this tutorial that I wrote. I added a couple comments with the snippets.
http://drupalsn.com/learn-drupal/drupal-tutorials/user-age-date-birth-%E...

volocuga’s picture

I am also interested in

ymakux(here is 'at')gmail.com

Thanks!

Passionate_Lass’s picture

Check this tutorial that I wrote. I added a couple comments with the snippets.
http://drupalsn.com/learn-drupal/drupal-tutorials/user-age-date-birth-%E...

sevanden’s picture

This is how I did it, but I use this code in a 'Dynamic field' instead (yet is works the same way). Translating the strings is just a matter of adding t() ...

$zodiac_signs = array ( array ( 20, 'Aquarius'    ) ,
                        array ( 19, 'Pisces'      ) ,
                        array ( 21, 'Aries'       ) ,
                        array ( 20, 'Taurus'      ) ,
                        array ( 21, 'Gemini'      ) ,
                        array ( 21, 'Cancer'      ) ,
                        array ( 23, 'Leo'         ) ,
                        array ( 23, 'Virgo'       ) ,
                        array ( 23, 'Libra'       ) ,
                        array ( 23, 'Scorpio'     ) ,
                        array ( 22, 'Sagittarius' ) ,
                        array ( 22, 'Capricorn'   )
                      );
$birthday =  date( "Y, m d",strtotime($node->field_date_of_birth[0]['value']));

$month = date( "m",strtotime($node->field_date_of_birth[0]['value']));
$day   = date( "d",strtotime($node->field_date_of_birth[0]['value']));
if ( $day < $zodiac_signs[$month-1][0] ) {
  if ( $month == 1) {
    $month = 13;
  }
  $month = $month -1;
}
return t($zodiac_signs[$month-1][1]);
askibinski’s picture

Using CCK+date+computed field:

I just discovered that the age is not updated after somebody had a birthday, something I would really expect because "Store using the database settings below" is NOT checked in the settings of this computed field...

Albert Skibinski - Homepage

Witch’s picture

I just use Views Bulk Operations to update them.

Kristina-2’s picture

Hi.
I'd like some info on how to do that. :) Thanks!

asb’s picture

The problem by using this approach is that you have to update this data pretty often, basically daily if you have a fair number of birthdays.

Any ideas how to solve the updating smarter?

mojito_’s picture

Hi,
I'm having the same problem with ages not updating. Can anyone advise the best way to do this? Or how to use VBO to update them?
Cheers

wernerglinka’s picture

One way of doing this could be using views custom field to compute the age. This field would be executed every time the view is loaded. Of course that assumes that you would a view to show the age.

mgladding’s picture

Is there a way to provide this feature in a block to anonymous users? I want any user to be able to select their birth date and then have their sign displayed.

Thanks in advance!

autoberater’s picture

I get the age 39 if the user does not fill out the "date of birth" field.
How can i handle that? I like to get a n.a. or something when the user will not fill this out.
Is the birthday field requiered in you case?

Village Internet’s picture

If you don't input a DOB, it will default to Jan 1, 1970, thus the age is calculated to be 40

robby.smith’s picture

Can anyone help with this mysterious Age 39 if no birthdate is entered.
I would like to make this info optional, but not make the user 39 years old =)
Thanks in advance!

deadrich’s picture

Having this same problem when the DOB is not selected. Anybody able to find a solution this?

robby.smith’s picture

I'm still expierencing the issue where if no birthdate is selected, the Age autocomputes to 40 (not 40 as the year is now 2010!). Can anyone provide help?

autoberater’s picture

I have the same problem. Age 40 if no birthday is selected.

robby.smith’s picture

kindly bumping

dmetzcher’s picture

The age is 40 if the user enters nothing (because it is 2010 and the default age is 1 Jan 1970).

I used the following code to stop this...

Computed Code:

if (!$node->nid) node_save($node);
  $dob = $node->field_bday[0]['value'];
        $now = time();
        $then = strtotime($dob);

        $diff = date('Y', $now) - date('Y', $then);

        if($diff < 0)      /* ideally you want to prevent this from happening */
           echo '??? - negative age.';

        if(($diff > 0) && (date('z',$now) < date('z',$then)))
           $diff --;
$node_field[0]['value'] = $diff;
if (is_null($node->field_bday[0]['value'])) $node_field[0]['value'] = NULL ;

Note the last line: if (is_null($node->field_bday[0]['value'])) $node_field[0]['value'] = NULL ;
That's what I added. You'll need to change field_bday to whatever name you are using for the birthdate field.

The Display Format doesn't change from what Passionate_Lass originally posted. I'm posting it below so that it's here with the corrected code.

Display Format:

$display = $node_field_item['value'];

By the way, thank you to Passionate_Lass for posting the original code. I got the line that I added from a comment on her site where someone posted a shorter way to do this, but his method doesn't seem to account for leap years. His code, however, had the last line that I added which makes the computed age field NULL if nothing is entered for age, so I grabbed that line from him. :)

iparsin’s picture

I followed the Passionate_Lass code and your add-on, everything works as expected. However, for age that less than a year, I tried to output something like "less than a year" text instead of "0". I poked around with if ($diff == 0) echo "..."; but nothing happened.

Thank in advance,
iparsin

dmetzcher’s picture

I would think that the following would work, but I haven't tested it myself.

Computed Code:

if (!$node->nid) node_save($node);
  $dob = $node->field_bday[0]['value'];
        $now = time();
        $then = strtotime($dob);

        $diff = date('Y', $now) - date('Y', $then);

        if($diff < 0)      /* ideally you want to prevent this from happening */
           echo '??? - negative age.';

        if($diff == 0)      /* NEW - Check to see if the age is exactly zero and display special text. */
           echo 'Less than a year';

        if(($diff > 0) && (date('z',$now) < date('z',$then)))
           $diff --;
$node_field[0]['value'] = $diff;
if (is_null($node->field_bday[0]['value'])) $node_field[0]['value'] = NULL ;

I really only did what you said you tried to do. I don't understand why it wouldn't work, since it's really only a slight modification of the lines just above it where we are checking for $diff < 0.

Witch’s picture

Does anybody know how to display all nodes where the birthday is today?

dmetzcher’s picture

You'll want to create a new view and use your birthdate field as a filter.
Use the Date: Date (node) filter.

Date form type: Text
Granularity: Day
Date year range: (should be able to leave this as the default)
Date field(s): Content: Birth Date (field_birthdate) <-- assuming your field is called birthdate
Method: OR

Then...
Operator: Is equal to
Absolute value: now <-- type this into the field

Witch’s picture

hi dmetzcher,

i will give it a try. thank you :)

Witch’s picture

when i try to type 'now' (without ' ) into the absolute value it gives me just an "is invalid".

dmetzcher’s picture

You're right. "now" needs to go into the fields under Relative Value. I'm not sure which... Date default or To date default, or both. Test it out and report back here with your findings. If I were guessing (I am), putting it in both fields will do the trick. :-)

Witch’s picture

i tested it, but it wont work. Maybe because the year from "now" (2010) is not the same like the given from a user's birthday?

dmetzcher’s picture

Very good point! I totally missed that.
In that case... I wonder what the most efficient way to do this would be... something with a computed field, maybe?

Anyone got any ideas?

Witch’s picture

hey dmetzcher,

i created a new computed field with the following code


$birthday = strtotime($node->field_yout_Birthday_field[0]['value']);

$time = date("d.m", $birthday);

$node_field[0]['value'] = $time;

now we get just the day and month from a date. Any ideas how to go on with views or other ways?

dmetzcher’s picture

Now that you have a computed field with just month and day, have you tried to use a filter in a view?

Witch’s picture

no, you cant use this field to filter todays birthday. there is more coding necessary :(

mattsmith3’s picture

Hey Guys,

I followed this thread... and the tutorial link that is posted above... even when I got around the errors that this code was kicking up, I still kept experiencing an odd side-effect where creating or editing profiles re-directed users to a 'Page not found' message. Terribly frustrating to track it down to this one computed field.

At any rate, here's a much quicker fix that I beleive should solve everyone's needs:

http://drupal.org/project/birthdays

I'm installing now.

mattsmith3’s picture

Installed and got it up and running. Pretty useless (for me) without views integration. The rest of this modules features are nice.

I'm wondering-

Can someone who has the code on this thread working properly save the date and age fields as a feature and publish it?

tpoppe’s picture

Hey There. Just to save someone else the grief I went thru, here how to compute difference in dates within a Computed_Field:

$node_field[0]['value'] = date_difference($node->field_date1[0]['value'],$node->field_date2[0]['value'], $measure='days',$type=DATE_DATETIME);

couldn't believe there was a simple drupal API call for it

Thanks Lullabot for the tip

Anonymous’s picture

Anyone got an idea on how to make it work with the latest version of drupal 7?

I got a date field that is able to display 24 years but always add "ago" since i'm using display as time ago... ?

ptmkenny’s picture

You can remove the "ago" by using locale to edit the language strings or by using the string_override module.

However, I am looking for a solution with compute_field and views. I tried changing node to entity in the code above but it appears the conversion to Drupal 7 isn't that simple. Does anyone have a working example of computing age from a field in D7?

shandman’s picture

How would we do this in Drupal 7?

Aporie’s picture

In a computed field, assuming your dob field name is field_dob :

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

Crédits : kadimi.com