DATA Step, Macro, Functions and more

age from datetime18.0

Reply
Contributor
Posts: 58

age from datetime18.0

Hi

 

a) I am trying to understand how datetime18.0 works, and why I was not able to work out the age of a person from a given Birthdate (BRTH_DT) in datetime18. It worked only when I changed the format of datetime18. using datepart, resulting in variable DOB. 

Why is that?

 

b) below I worked the age out from a specific date : 06.Jun2017   (as can be seen in the code)

What would I have to do, when I wanted to calculate the age from the time that this record was taken: LST_UPDT_DT (also displayed in datetime 18.0 - numeric) ? 

Woud I have to convert this like above or is there a better way?  Ideally I would want to work with the datetime 18 formats. Is there a way to do it? What can I do to make LST_UPDT_DT  -   BRTH_DT work, while taking care of leap years?

 

Many thanks

 

Capture.PNG

data Kea.Trails11age;
  set Kea.File113;
  DOB=datepart(BRTH_DT);
  run; 

/* AGE  */
data Kea.age;
  set Kea.Trails11age;
age = yrdif (DOB, '06.Jun2017'd);run;

 

Respected Advisor
Posts: 4,173

Re: age from datetime18.0

[ Edited ]

@AnnaNZ

SAS stores dates as numbers in numerical variables. You then apply a format to this number so it becomes human readable (=number prints as a date). 

The format doesn't change the internal value (the number) and the format isn't required for SAS to do date and datetime calculations.

 

A SAS Date value is the number of Days since 1/1/1960

A SAS DateTime value is the number of Seconds since 1/1/1960

 

Function YRDIF() requires a SAS Date value. It will fail if you pass in a SAS DateTime value (the number is way too big).

 

Function Datepart() converts a SAS DateTime value to a SAS Date value. 

Because both SAS Date and DateTime values are stored in the same SAS variable type of Numeric what the SAS Datepart() function basically does is to divide the SAS DateTime value by the seconds of a day to get the number of Days.

int(<SAS DateTime value> / 86400)  =  <SAS Date value> 

 

 

Contributor
Posts: 58

Re: age from datetime18.0

Hi Patrick, thank you for your answer. So that means in this case I convert both datetime variables using datepart and then deduct a from b ?

What is if I wanted to know the exact time from b-a?  Can I work with datetime like with any numeric value or would I have to change it into a different datetime format? In orther words, are there datetimes that are more conventional ?

Many thanks, anna

Respected Advisor
Posts: 4,173

Re: age from datetime18.0

[ Edited ]

@AnnaNZ

In SAS Date and DateTime values are only numbers and you can work with them like with any other numbers.

 

I.e: <SAS datetime value> - 60 substracts 1 minute from your datetime value.

 

SAS provides some very useful calendar functions to deal with SAS Date and DateTime values. The most common ones are INTCK() and INTNX().

https://support.sas.com/resources/papers/proceedings15/2460-2015.pdf

 

BTW: If using the YRDIF() function to calculate the Age of a person then also use the third parameter and set the value to 'AGE' 

http://support.sas.com/documentation/cdl/en/lefunctionsref/69762/HTML/default/viewer.htm#p1pmmr2dtec...

 

 

Super User
Posts: 7,854

Re: age from datetime18.0

[ Edited ]

AnnaNZ wrote:

Hi Patrick, thank you for your answer. So that means in this case I convert both datetime variables using datepart and then deduct a from b ?

What is if I wanted to know the exact time from b-a?  Can I work with datetime like with any numeric value or would I have to change it into a different datetime format? In orther words, are there datetimes that are more conventional ?

Many thanks, anna


Since datetime and time values are basically the same (they count seconds), a simple subtraction:

interval = b - a

gives you a correct SAS time value (assuming that b and a were SAS datetime values).

Example:

data test;
b = datetime();
a = intnx('dtyear',b,-20,'b');
interval = b - a;
format b a datetime19. interval time20.;
run;

proc print data=test noobs;
run;

Result:

                 b                      a                interval

09JUN2017:09:42:17     01JAN1997:00:00:00            179145:42:17

 

---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers
Contributor
Posts: 58

Re: age from datetime18.0

Posted in reply to KurtBremser

Hi Kurt

 

Many thanks for your comment. Unfortunetaly, I can't make your example get working for me.

a and b are variables both in datetime 18. I cannot quite follow how you insert them into the equation.

I am also do not quite understand why chaning over to datetime 19 ?

Can you please explain further.

Many thaks for your time.

 

Super User
Super User
Posts: 7,076

Re: age from datetime18.0

 I don't think I understand your question. The way you insert a variable into a formula is by typing its name. Perhpas it will make more sense if you look at the numeric values that SAS stores for date, datetime and time values?

1371  data _null_;
1372    now=datetime();
1373    today=datepart(now);
1374    tod=timepart(now);
1375    put now= comma20.2 +1 now datetime21.2 ;
1376    put today= comma10.2 +1 today date9. ;
1377    put tod= comma10.2 +1 tod time11.2 ;
1378  run;

now=1,812,831,051.39  11JUN2017:20:10:51.39
today=20,981.00  11JUN2017
tod=72,651.39  20:10:51.39

 

There is a bug in the behavior of the DATETIME format. Even though DATETIME18. should have enough room to display the date part in 9 characters then time part in 8 and still have space for the colon between them, instead it will result in the date part being displayed using ony 7 character, which would be confusing when trying to evaluate age.  So you need to use DATETIME19 to get it to show the century part of the date.

1388  data _null_;
1389    now=datetime();
1390    put (2*now) (datetime18. +1 datetime19.);
1391  run;

  11JUN17:20:12:55  11JUN2017:20:12:55
Super User
Posts: 7,854

Re: age from datetime18.0


AnnaNZ wrote:

Hi Kurt

 

Many thanks for your comment. Unfortunetaly, I can't make your example get working for me.

a and b are variables both in datetime 18. I cannot quite follow how you insert them into the equation.

I am also do not quite understand why chaning over to datetime 19 ?

Can you please explain further.

Many thaks for your time.

 


You will have to show how you implemented my suggestion in your code, and if it throws an error, also show the log.

We may also have reached the point where we need to take a look at your data as it actually is. Use the macro from https://communities.sas.com/t5/SAS-Communities-Library/How-to-create-a-data-step-version-of-your-dat... to create a data step that lets us recreate your dataset with all attributes and values.

---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers
Contributor
Posts: 58

Re: age from datetime18.0

Posted in reply to KurtBremser
Data ageatreferral;
Set age_test;
BRTH_DT = datetime();
LST_UPDT_DT = intnx('dtyear',b,-20,'b');
interval = b - a;
format b a datetime19. interval time20.;
run;

Hi Kurt,

 

Can you please advise how to set this up. Essentially, I need age at referral, threfore Date of Birth minus Last Update Date:

 age at referral = BRTH_DT  -  LST_UPDT_DT 

 

-  I tried a lot with intnx and YRDIF, but can't get it working. With your example I don't understand how to set it up and why you have datetime19 and time20.

My original data is all in datetime 18

Help is greatly appreaciated.

Thanks, Anna


age_test.JPG
Super User
Posts: 7,854

Re: age from datetime18.0

Anna,

 

when I wrote this:

Use the macro from https://communities.sas.com/t5/SAS-Communities-Library/How-to-create-a-data-step-version-of-your-dat... to create a data step that lets us recreate your dataset with all attributes and values

I really meant it. Posting a picture that does not even show your complete data is a) not very helpful and b) at best impolite, forcing us to type the data from screen.

 

THIS is how you post example data:

data age_test;
input id lst_upd_dt :datetime19. brth_dt :datetime19.;
format lst_upd_dt brth_dt datetime19.;
cards;
150002 01jan2001:12:07:00 06feb1956:00:00:00
;
run;

Now, I applied several different types of logic to that, that give slightly different results:

data ageatreferral;
set age_test;
l_up_dt = datepart(lst_upd_dt);
dob = datepart(brth_dt);
age_at_referral = yrdif(dob,l_up_dt);
age_at_referral2 = intck('year',dob,l_up_dt);
time_lived = lst_upd_dt - brth_dt;
format time_lived time20.;
run;

One of those (time_lived) is the application of my answer to "What is if I wanted to know the exact time from b-a?"

---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers
Ask a Question
Discussion stats
  • 9 replies
  • 258 views
  • 3 likes
  • 4 in conversation